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