v0.13.1
LogManager.cpp
Go to the documentation of this file.
1/**
2 * @file LogManager.cpp
3 * @brief Log and register warnings
4 *
5 */
6
7#include <MoFEM.hpp>
8
9#undef likely
10
11#include <cstddef>
12#include <string>
13#include <ostream>
14#include <fstream>
15#include <iomanip>
16
17#include <boost/date_time/posix_time/posix_time.hpp>
18
19static int dummy_file_ptr = 1;
20
21namespace MoFEM {
22
23using namespace MoFEM::LogKeywords;
24
25constexpr std::array<char *const, LogManager::SeverityLevel::error + 1>
27
28std::ostream &operator<<(std::ostream &strm,
29 const LogManager::SeverityLevel &level) {
30
31 strm << "<" << LogManager::severityStrings[level] << "> ";
32
33 return strm;
34}
35
37 : public boost::enable_shared_from_this<LogManager::InternalData> {
38
39 class SelfStreamBuf : public std::stringbuf {
40 virtual int sync() {
41 if (!this->str().empty()) {
42 PetscFPrintf(PETSC_COMM_SELF, LogManager::dummy_mofem_fd, "%s",
43 this->str().c_str());
44 this->str("");
45 }
46 return 0;
47 }
48 };
49
50 struct WorldStreamBuf : public std::stringbuf {
51 WorldStreamBuf(MPI_Comm comm) : cOmm(comm) {}
52 virtual int sync() {
53 if (!this->str().empty()) {
54 PetscFPrintf(cOmm, LogManager::dummy_mofem_fd, "%s",
55 this->str().c_str());
56 this->str("");
57 }
58 return 0;
59 }
60
61 private:
62 MPI_Comm cOmm;
63 };
64
65 struct SynchronizedStreamBuf : public std::stringbuf {
66 SynchronizedStreamBuf(MPI_Comm comm) : cOmm(comm) {}
67 virtual int sync() {
68 if (!this->str().empty()) {
69 PetscSynchronizedFPrintf(cOmm, LogManager::dummy_mofem_fd, "%s",
70 this->str().c_str());
71 this->str("");
72 }
73 return 0;
74 }
75
76 private:
77 MPI_Comm cOmm;
78 };
79
83
84 std::ostream strmSelf;
85 std::ostream strmWorld;
86 std::ostream strmSync;
87
88 static bool logQuiet;
89 static bool noColors;
90 static bool sinksAdd;
91 static bool logTime;
92
93 static std::map<std::string, LoggerType> logChannels;
94
95 boost::shared_ptr<std::ostream> getStrmSelf() {
96 return boost::shared_ptr<std::ostream>(shared_from_this(), &strmSelf);
97 }
98 boost::shared_ptr<std::ostream> getStrmWorld() {
99 return boost::shared_ptr<std::ostream>(shared_from_this(), &strmWorld);
100 }
101 boost::shared_ptr<std::ostream> getStrmSync() {
102 return boost::shared_ptr<std::ostream>(shared_from_this(), &strmSync);
103 }
104
105 InternalData(MPI_Comm comm)
106 : worldBuf(comm), syncBuf(comm), strmSelf(&selfBuf), strmWorld(&worldBuf),
107 strmSync(&syncBuf) {}
108
109 virtual ~InternalData() = default;
110};
111
116
117std::map<std::string, LogManager::LoggerType>
119
120boost::shared_ptr<LogManager::InternalData> LogManager::internalDataPtr;
121
123 : cOre(const_cast<MoFEM::Core &>(core)) {}
124
126LogManager::query_interface(boost::typeindex::type_index type_index,
127 UnknownInterface **iface) const {
129 *iface = const_cast<LogManager *>(this);
131}
132
135 PetscInt sev_level = SeverityLevel::inform;
136 PetscBool log_scope = PETSC_FALSE;
137 PetscBool log_quiet = PETSC_FALSE;
138 PetscBool log_no_colors = PETSC_FALSE;
139 PetscBool log_time = PETSC_FALSE;
140
141 CHKERR PetscOptionsBegin(PETSC_COMM_WORLD, "log_",
142 "Logging interface options", "none");
143
144 CHKERR PetscOptionsEList("-severity_level", "Severity level", "",
145 severityStrings.data(), SeverityLevel::error + 1,
146 severityStrings[sev_level], &sev_level, PETSC_NULL);
147 CHKERR PetscOptionsEList("-sl", "Seeverity level", "",
148 severityStrings.data(), SeverityLevel::error + 1,
149 severityStrings[sev_level], &sev_level, PETSC_NULL);
150
151 CHKERR PetscOptionsBool("-scope", "Log scope", "", log_scope, &log_scope,
152 NULL);
153
154 CHKERR PetscOptionsBool("-quiet", "Quiet log attributes", "", log_quiet,
155 &log_quiet, NULL);
156
157 CHKERR PetscOptionsBool("-no_color", "Terminal with no colors", "",
158 log_no_colors, &log_no_colors, NULL);
159 CHKERR PetscOptionsBool("-nc", "Terminal with no colors", "", log_no_colors,
160 &log_no_colors, NULL);
161
162 CHKERR PetscOptionsBool("-time", "Log time", "",
163 log_time, &log_time, NULL);
164
165 ierr = PetscOptionsEnd();
166 CHKERRG(ierr);
167
168 logging::core::get()->set_filter(MoFEM::LogKeywords::severity >= sev_level);
169
170 if (log_scope)
171 logging::core::get()->add_global_attribute("Scope", attrs::named_scope());
172
173 if (log_quiet)
175
176 if (log_no_colors)
178
179 if (log_time)
181
183}
184
185void LogManager::recordFormatterDefault(logging::record_view const &rec,
186 logging::formatting_ostream &strm) {
187
189
190 auto sev = rec[severity];
191 auto p = rec[proc_attr];
192 auto l = rec[line_id];
193 auto s = rec[scope];
194 auto tg = rec[tag_attr];
195 auto tl = rec[timeline];
196
197 auto set_color = [&](const auto str) {
198#if defined(PETSC_HAVE_UNISTD_H) && defined(PETSC_USE_ISATTY)
199 if (isatty(fileno(stdout)) && !LogManager::InternalData::noColors)
200 strm << str;
201#endif
202 };
203
205
206 auto local_time = boost::posix_time::second_clock::local_time();
207 strm << "(Local time ";
208 strm << local_time.date().year() << "-" << local_time.date().month()
209 << "-" << local_time.date().day() << " "
210 << local_time.time_of_day().hours() << ":"
211 << local_time.time_of_day().minutes() << ":"
212 << local_time.time_of_day().seconds();
213 strm << ") ";
214
215 }
216
217 if (!p.empty()) {
218 strm << "[";
219 set_color("\033[32m");
220 strm << p;
221 set_color("\033[0m");
222 strm << "] ";
223 }
224
225 switch (sev.get()) {
226 case SeverityLevel::error:
227 set_color("\033[1m");
228 case SeverityLevel::warning:
229 set_color("\033[31m");
230 break;
231 case SeverityLevel::inform:
232 set_color("\033[34m");
233 break;
234 case SeverityLevel::verbose:
235 set_color("\033[35m");
236 break;
237 case SeverityLevel::noisy:
238 set_color("\033[36m");
239 break;
240 }
241
242 strm << sev;
243
244 set_color("\033[0m");
245
246 if (!l.empty())
247 strm << std::hex << std::setw(8) << std::setfill('0') << l.get()
248 << std::dec << std::setfill(' ') << ": ";
249
250 if (!s.empty()) {
251 for (::boost::log::attributes::named_scope_list::const_iterator iter =
252 s->begin();
253 iter != s->end(); ++iter) {
254 const auto path = std::string(iter->file_name.data());
255 const auto file = path.substr(path.find_last_of("/\\") + 1);
256 strm << "(" << file << ":" << iter->line << ">" << iter->scope_name
257 << ")";
258 }
259 strm << " ";
260 }
261
262 if (!tg.empty()) {
263
264 set_color("\033[1m");
265 strm << "[" << tg.get() << "] ";
266 set_color("\033[0m");
267 }
268
269 if (!tl.empty())
270 strm << "[" << tl.get() << "] ";
271 }
272
273 auto msg = rec[logging::expressions::smessage];
274
275 strm << msg;
276}
277
278boost::shared_ptr<LogManager::SinkType>
279LogManager::createSink(boost::shared_ptr<std::ostream> stream_ptr,
280 std::string comm_filter) {
281
282 auto backend = boost::make_shared<sinks::text_ostream_backend>();
283 if (stream_ptr)
284 backend->add_stream(stream_ptr);
285 backend->auto_flush(true);
286
287 auto sink = boost::make_shared<SinkType>(backend);
288 sink->set_filter((expr::has_attr(channel) && channel == comm_filter));
289 sink->set_formatter(&recordFormatterDefault);
290
291 return sink;
292}
293
295
296 internalDataPtr = boost::make_shared<InternalData>(comm);
297
298 auto core_log = logging::core::get();
299 core_log->remove_all_sinks();
300 core_log->add_sink(LogManager::createSink(
301 boost::shared_ptr<std::ostream>(&std::clog, boost::null_deleter()),
302 "PETSC"));
303 core_log->add_sink(createSink(getStrmSelf(), "SELF"));
304 core_log->add_sink(createSink(getStrmWorld(), "WORLD"));
305 core_log->add_sink(createSink(getStrmSync(), "SYNC"));
306
307 LogManager::setLog("PETSC");
308 LogManager::setLog("SELF");
309 LogManager::setLog("WORLD");
310 LogManager::setLog("SYNC");
311
312 MOFEM_LOG_TAG("PETSC", "petsc");
313
314 int rank;
315 MPI_Comm_rank(comm, &rank);
316 core_log->add_global_attribute("Proc", attrs::constant<unsigned int>(rank));
317}
318
319boost::shared_ptr<std::ostream> LogManager::getStrmSelf() {
320 return internalDataPtr->getStrmSelf();
321}
322
323boost::shared_ptr<std::ostream> LogManager::getStrmWorld() {
324 return internalDataPtr->getStrmWorld();
325}
326
327boost::shared_ptr<std::ostream> LogManager::getStrmSync() {
328 return internalDataPtr->getStrmSync();
329}
330
331static char dummy_file;
333
335
336 if (bit == 0)
337 return;
338
339 if (bit & (BitLineID | BitScope)) {
340
341 if (bit & BitLineID)
342 lg.add_attribute("LineID", attrs::counter<unsigned int>(1));
343
344 if (bit & BitScope)
345 lg.add_attribute("Scope", attrs::named_scope());
346
347 } else {
348 THROW_MESSAGE("Wrong cast");
349 }
350}
351
352void LogManager::addAttributes(const std::string channel, const int bit) {
353 addAttributes(getLog(channel), bit);
354}
355
356void LogManager::addTag(LogManager::LoggerType &lg, const std::string tag) {
357 lg.add_attribute("Tag", attrs::constant<std::string>(tag));
358}
359
360void LogManager::addTag(const std::string channel, const std::string tag) {
361 getLog(channel).add_attribute("Tag", attrs::constant<std::string>(tag));
362}
363
364LogManager::LoggerType &LogManager::setLog(const std::string channel) {
366 LoggerType(boost::log::keywords::channel = channel);
367 return InternalData::logChannels[channel];
368}
369
370LogManager::LoggerType &LogManager::getLog(const std::string channel) {
371 return InternalData::logChannels.at(channel);
372}
373
374bool LogManager::checkIfChannelExist(const std::string channel) {
375 return InternalData::logChannels.find(channel) !=
377}
378
379std::string LogManager::petscStringCache = std::string();
380
381PetscErrorCode LogManager::logPetscFPrintf(FILE *fd, const char format[],
382 va_list Argp) {
384 if (fd != stdout && fd != stderr && fd != dummy_mofem_fd) {
385 CHKERR PetscVFPrintfDefault(fd, format, Argp);
386
387 } else {
388
389 std::array<char, 1024> buff;
390 size_t length;
391 CHKERR PetscVSNPrintf(buff.data(), 1024, format, &length, Argp);
392
393 auto get_str = [&buff]() {
394 std::string str;
395 if (!petscStringCache.empty())
396 str = petscStringCache + std::string(buff.data());
397 else
398 str = std::string(buff.data());
399 return str;
400 };
401 const auto str = get_str();
402
403 if (!str.empty()) {
404 if (fd != dummy_mofem_fd) {
405
407 MoFEM::LogManager::SeverityLevel::inform;
408 if (str.find("WARNING") != std::string::npos)
409 sev = MoFEM::LogManager::SeverityLevel::warning;
410
411 std::istringstream is(str);
412 std::string line;
413 std::vector<std::string> log_list;
414
415 while (getline(is, line, '\n'))
416 log_list.push_back(line);
417
418 if (str.back() != '\n') {
419 petscStringCache = log_list.back();
420 log_list.pop_back();
421 } else
422 petscStringCache.clear();
423
424 for(auto &line : log_list)
425 MOFEM_LOG("PETSC", sev) << line;
426
427 } else {
428 std::clog << str;
429 }
430 }
431 }
433}
434
435std::string LogManager::getVLikeFormatedString(const char *fmt, va_list args) {
436 std::array<char, 1024> buf;
437 vsprintf(buf.data(), fmt, args);
438 return std::string(buf.data());
439}
440
441std::string LogManager::getCLikeFormatedString(const char *fmt, ...) {
442 va_list args;
443 va_start(args, fmt);
444 auto str = getVLikeFormatedString(fmt, args);
445 va_end(args);
446 return str;
447}
448
449} // namespace MoFEM
static Index< 'p', 3 > p
static int dummy_file_ptr
Definition: LogManager.cpp:19
PetscErrorCode PetscVFPrintfDefault(FILE *fd, const char *format, va_list Argp)
#define MoFEMFunctionReturnHot(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:447
#define MoFEMFunctionBegin
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:346
#define CHKERRG(n)
Check error code of MoFEM/MOAB/PETSc function.
Definition: definitions.h:483
#define MoFEMFunctionReturn(a)
Last executable line of each PETSc function used for error handling. Replaces return()
Definition: definitions.h:416
#define CHKERR
Inline error check.
Definition: definitions.h:535
#define MoFEMFunctionBeginHot
First executable line of each MoFEM function, used for error handling. Final line of MoFEM functions ...
Definition: definitions.h:440
#define THROW_MESSAGE(msg)
Throw MoFEM exception.
Definition: definitions.h:561
static LoggerType & setLog(const std::string channel)
Set ans resset chanel logger.
Definition: LogManager.cpp:364
#define MOFEM_LOG(channel, severity)
Log.
Definition: LogManager.hpp:301
SeverityLevel
Severity levels.
Definition: LogManager.hpp:33
#define MOFEM_LOG_TAG(channel, tag)
Tag channel.
Definition: LogManager.hpp:332
static void addTag(LogManager::LoggerType &lg, const std::string tag)
Add tag to logger.
Definition: LogManager.cpp:356
static void addAttributes(LogManager::LoggerType &lg, const int bit=0)
Add attributes to logger.
Definition: LogManager.cpp:334
static LoggerType & getLog(const std::string channel)
Get logger by channel.
Definition: LogManager.cpp:370
auto bit
set bit
FTensor::Index< 'l', 3 > l
static MoFEMErrorCodeGeneric< PetscErrorCode > ierr
Definition: Exceptions.hpp:76
PetscErrorCode MoFEMErrorCode
MoFEM/PETSc error code.
Definition: Exceptions.hpp:56
implementation of Data Operators for Forces and Sources
Definition: MoFEM.hpp:24
std::ostream & operator<<(std::ostream &os, const EntitiesFieldData::EntData &e)
static char dummy_file
Definition: LogManager.cpp:331
Core (interface) class.
Definition: Core.hpp:82
boost::shared_ptr< std::ostream > getStrmWorld()
Definition: LogManager.cpp:98
SynchronizedStreamBuf syncBuf
Definition: LogManager.cpp:82
virtual ~InternalData()=default
boost::shared_ptr< std::ostream > getStrmSync()
Definition: LogManager.cpp:101
static std::map< std::string, LoggerType > logChannels
Definition: LogManager.cpp:93
boost::shared_ptr< std::ostream > getStrmSelf()
Definition: LogManager.cpp:95
Log manager is used to build and partition problems.
Definition: LogManager.hpp:26
static constexpr std::array< char *const, error+1 > severityStrings
Definition: LogManager.hpp:35
static boost::shared_ptr< SinkType > createSink(boost::shared_ptr< std::ostream > stream_ptr, std::string comm_filter)
Create a sink object.
Definition: LogManager.cpp:279
LogManager(const MoFEM::Core &core)
Definition: LogManager.cpp:122
static MoFEMErrorCode getOptions()
Get logger option.
Definition: LogManager.cpp:133
static std::string getCLikeFormatedString(const char *fmt,...)
Converts formatted output to string.
Definition: LogManager.cpp:441
static void createDefaultSinks(MPI_Comm comm)
Create default sinks.
Definition: LogManager.cpp:294
boost::log::sources::severity_channel_logger< SeverityLevel, std::string > LoggerType
Definition of the channel logger.
Definition: LogManager.hpp:64
static boost::shared_ptr< std::ostream > getStrmWorld()
Get the strm world object.
Definition: LogManager.cpp:323
MoFEMErrorCode query_interface(boost::typeindex::type_index type_index, UnknownInterface **iface) const
Definition: LogManager.cpp:126
static PetscErrorCode logPetscFPrintf(FILE *fd, const char format[], va_list Argp)
Use to handle PETSc output.
Definition: LogManager.cpp:381
static std::string getVLikeFormatedString(const char *fmt, va_list args)
Converts formatted output to string.
Definition: LogManager.cpp:435
static boost::shared_ptr< std::ostream > getStrmSync()
Get the strm sync object.
Definition: LogManager.cpp:327
static void recordFormatterDefault(logging::record_view const &rec, logging::formatting_ostream &strm)
Default record formatter.
Definition: LogManager.cpp:185
static bool checkIfChannelExist(const std::string channel)
Check if channel exist.
Definition: LogManager.cpp:374
static boost::shared_ptr< std::ostream > getStrmSelf()
Get the strm self object.
Definition: LogManager.cpp:319
static std::string petscStringCache
Definition: LogManager.hpp:232
static FILE * dummy_mofem_fd
Dummy file pointer (DO NOT USE)
Definition: LogManager.hpp:184
static boost::shared_ptr< InternalData > internalDataPtr
Definition: LogManager.hpp:230
base class for all interface classes