VTK  9.7.1
vtkLogger.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
158 #ifndef vtkLogger_h
159 #define vtkLogger_h
160 
161 #include "vtkObjectBase.h"
162 #include "vtkSetGet.h" // needed for macros
163 
164 #include <string> // needed for std::string
165 
166 #if defined(_MSC_VER)
167 #include <sal.h> // Needed for _In_z_ etc annotations
168 #endif
169 
170 // this is copied from `loguru.hpp`
171 #if defined(__clang__) || defined(__GNUC__)
172 // Helper macro for declaring functions as having similar signature to printf.
173 // This allows the compiler to catch format errors at compile-time.
174 #define VTK_PRINTF_LIKE(fmtarg, firstvararg) \
175  __attribute__((__format__(__printf__, fmtarg, firstvararg)))
176 #define VTK_FORMAT_STRING_TYPE const char*
177 #elif defined(_MSC_VER)
178 #define VTK_PRINTF_LIKE(fmtarg, firstvararg)
179 #define VTK_FORMAT_STRING_TYPE _In_z_ _Printf_format_string_ const char*
180 #else
181 #define VTK_PRINTF_LIKE(fmtarg, firstvararg)
182 #define VTK_FORMAT_STRING_TYPE const char*
183 #endif
184 
185 VTK_ABI_NAMESPACE_BEGIN
186 class VTKCOMMONCORE_EXPORT vtkLogger : public vtkObjectBase
187 {
188 public:
189  vtkBaseTypeMacro(vtkLogger, vtkObjectBase);
190  void PrintSelf(ostream& os, vtkIndent indent) override;
191 
193  {
194  // Used to mark an invalid verbosity. Do not log to this level.
195  VERBOSITY_INVALID = -10, // Never do LOG_F(INVALID)
196 
197  // You may use VERBOSITY_OFF on g_stderr_verbosity, but for nothing else!
198  VERBOSITY_OFF = -9, // Never do LOG_F(OFF)
199 
200  VERBOSITY_ERROR = -2,
201  VERBOSITY_WARNING = -1,
202 
203  // Normal messages. By default written to stderr.
204  VERBOSITY_INFO = 0,
205 
206  // Same as VERBOSITY_INFO in every way.
207  VERBOSITY_0 = 0,
208 
209  // Verbosity levels 1-9 are generally not written to stderr, but are written to file.
210  VERBOSITY_1 = +1,
211  VERBOSITY_2 = +2,
212  VERBOSITY_3 = +3,
213  VERBOSITY_4 = +4,
214  VERBOSITY_5 = +5,
215  VERBOSITY_6 = +6,
216  VERBOSITY_7 = +7,
217  VERBOSITY_8 = +8,
218  VERBOSITY_9 = +9,
219 
220  // trace level, same as VERBOSITY_9
221  VERBOSITY_TRACE = +9,
222 
223  // Don not use higher verbosity levels, as that will make grepping log files harder.
224  VERBOSITY_MAX = +9,
225  };
226 
264  static void Init(int& argc, char* argv[], const char* verbosity_flag = "-v");
265  static void Init();
274  static void SetStderrVerbosity(Verbosity level);
275 
282  static void SetInternalVerbosityLevel(Verbosity level);
283 
288  enum FileMode
289  {
291  APPEND
292  };
293 
300  static void LogToFile(const char* path, FileMode filemode, Verbosity verbosity);
301 
305  static void EndLogToFile(const char* path);
306 
308 
311  static void SetThreadName(const std::string& name);
312  static std::string GetThreadName();
314 
318  static std::string GetIdentifier(vtkObjectBase* obj);
319 
324  struct Message
325  {
326  // You would generally print a Message by just concatenating the buffers without spacing.
327  // Optionally, ignore preamble and indentation.
328  Verbosity verbosity; // Already part of preamble
329  const char* filename; // Already part of preamble
330  unsigned line; // Already part of preamble
331  const char* preamble; // Date, time, uptime, thread, file:line, verbosity.
332  const char* indentation; // Just a bunch of spacing.
333  const char* prefix; // Assertion failure info goes here (or "").
334  const char* message; // User message goes here.
335  };
336 
338 
341  using LogHandlerCallbackT = void (*)(void* user_data, const Message& message);
342  using CloseHandlerCallbackT = void (*)(void* user_data);
343  using FlushHandlerCallbackT = void (*)(void* user_data);
345 
355  static void AddCallback(const char* id, LogHandlerCallbackT callback, void* user_data,
356  Verbosity verbosity, CloseHandlerCallbackT on_close = nullptr,
357  FlushHandlerCallbackT on_flush = nullptr);
358 
363  static bool RemoveCallback(const char* id);
364 
368  static bool IsEnabled();
369 
375  static Verbosity GetCurrentVerbosityCutoff();
376 
383  static Verbosity ConvertToVerbosity(int value);
384 
391  static Verbosity ConvertToVerbosity(const char* text);
392 
394 
399  static void Log(
400  Verbosity verbosity, VTK_FILEPATH const char* fname, unsigned int lineno, const char* txt);
401  static void StartScope(
402  Verbosity verbosity, const char* id, VTK_FILEPATH const char* fname, unsigned int lineno);
403  static void EndScope(const char* id);
404 #if !defined(__WRAP__)
405  static void LogF(Verbosity verbosity, VTK_FILEPATH const char* fname, unsigned int lineno,
406  VTK_FORMAT_STRING_TYPE format, ...) VTK_PRINTF_LIKE(4, 5);
407  static void StartScopeF(Verbosity verbosity, const char* id, VTK_FILEPATH const char* fname,
408  unsigned int lineno, VTK_FORMAT_STRING_TYPE format, ...) VTK_PRINTF_LIKE(5, 6);
409 
410  class VTKCOMMONCORE_EXPORT LogScopeRAII
411  {
412  public:
413  LogScopeRAII();
414  LogScopeRAII(vtkLogger::Verbosity verbosity, const char* fname, unsigned int lineno,
415  VTK_FORMAT_STRING_TYPE format, ...) VTK_PRINTF_LIKE(5, 6);
416  ~LogScopeRAII();
417 #if defined(_MSC_VER) && _MSC_VER > 1800
418  // see loguru.hpp for the reason why this is needed on MSVC
419  LogScopeRAII(LogScopeRAII&& other)
420  : Internals(other.Internals)
421  {
422  other.Internals = nullptr;
423  }
424 #else
425  LogScopeRAII(LogScopeRAII&&) = default;
426 #endif
427 
428  private:
429  LogScopeRAII(const LogScopeRAII&) = delete;
430  void operator=(const LogScopeRAII&) = delete;
431  class LSInternals;
432  LSInternals* Internals;
433  };
434 #endif
435 
443  static bool EnableSigabrtHandler;
444  static bool EnableSigbusHandler;
445  static bool EnableSigfpeHandler;
446  static bool EnableSigillHandler;
447  static bool EnableSigintHandler;
448  static bool EnableSigsegvHandler;
449  static bool EnableSigtermHandler;
450 
451 protected:
452  vtkLogger();
453  ~vtkLogger() override;
454 
455 private:
456  vtkLogger(const vtkLogger&) = delete;
457  void operator=(const vtkLogger&) = delete;
458  static vtkLogger::Verbosity InternalVerbosityLevel;
459 };
460 
462 
476 #define vtkVLogF(level, ...) \
477  ((level) > vtkLogger::GetCurrentVerbosityCutoff()) \
478  ? (void)0 \
479  : vtkLogger::LogF(level, __FILE__, __LINE__, __VA_ARGS__)
480 #define vtkLogF(verbosity_name, ...) vtkVLogF(vtkLogger::VERBOSITY_##verbosity_name, __VA_ARGS__)
481 #define vtkVLog(level, x) \
482  do \
483  { \
484  if ((level) <= vtkLogger::GetCurrentVerbosityCutoff()) \
485  { \
486  vtkOStrStreamWrapper::EndlType const endl; \
487  vtkOStrStreamWrapper::UseEndl(endl); \
488  vtkOStrStreamWrapper vtkmsg; \
489  vtkmsg << "" x; \
490  vtkLogger::Log(level, __FILE__, __LINE__, vtkmsg.str()); \
491  vtkmsg.rdbuf()->freeze(0); \
492  } \
493  } while (false)
494 #define vtkLog(verbosity_name, x) vtkVLog(vtkLogger::VERBOSITY_##verbosity_name, x)
495 
498 
510 #define vtkVLogIfF(level, cond, ...) \
511  ((level) > vtkLogger::GetCurrentVerbosityCutoff() || (cond) == false) \
512  ? (void)0 \
513  : vtkLogger::LogF(level, __FILE__, __LINE__, __VA_ARGS__)
514 
515 #define vtkLogIfF(verbosity_name, cond, ...) \
516  vtkVLogIfF(vtkLogger::VERBOSITY_##verbosity_name, cond, __VA_ARGS__)
517 
518 #define vtkVLogIf(level, cond, x) \
519  do \
520  { \
521  if ((level) <= vtkLogger::GetCurrentVerbosityCutoff() && (cond)) \
522  { \
523  vtkOStrStreamWrapper::EndlType endl; \
524  vtkOStrStreamWrapper::UseEndl(endl); \
525  vtkOStrStreamWrapper vtkmsg; \
526  vtkmsg << "" x; \
527  vtkLogger::Log(level, __FILE__, __LINE__, vtkmsg.str()); \
528  vtkmsg.rdbuf()->freeze(0); \
529  } \
530  } while (false)
531 #define vtkLogIf(verbosity_name, cond, x) vtkVLogIf(vtkLogger::VERBOSITY_##verbosity_name, cond, x)
532 
534 #define VTKLOG_CONCAT_IMPL(s1, s2) s1##s2
535 #define VTKLOG_CONCAT(s1, s2) VTKLOG_CONCAT_IMPL(s1, s2)
536 #define VTKLOG_ANONYMOUS_VARIABLE(x) VTKLOG_CONCAT(x, __LINE__)
537 
538 #define vtkVLogScopeF(level, ...) \
539  auto VTKLOG_ANONYMOUS_VARIABLE(msg_context) = ((level) > vtkLogger::GetCurrentVerbosityCutoff()) \
540  ? vtkLogger::LogScopeRAII() \
541  : vtkLogger::LogScopeRAII(level, __FILE__, __LINE__, __VA_ARGS__)
542 
543 #define vtkLogScopeF(verbosity_name, ...) \
544  vtkVLogScopeF(vtkLogger::VERBOSITY_##verbosity_name, __VA_ARGS__)
545 
546 #define vtkLogScopeFunction(verbosity_name) vtkLogScopeF(verbosity_name, "%s", __func__)
547 #define vtkVLogScopeFunction(level) vtkVLogScopeF(level, "%s", __func__)
548 
550 
554 #define vtkLogStartScope(verbosity_name, id) \
555  vtkLogger::StartScope(vtkLogger::VERBOSITY_##verbosity_name, id, __FILE__, __LINE__)
556 #define vtkLogEndScope(id) vtkLogger::EndScope(id)
557 
558 #define vtkLogStartScopeF(verbosity_name, id, ...) \
559  vtkLogger::StartScopeF(vtkLogger::VERBOSITY_##verbosity_name, id, __FILE__, __LINE__, __VA_ARGS__)
560 
561 #define vtkVLogStartScope(level, id) vtkLogger::StartScope(level, id, __FILE__, __LINE__)
562 #define vtkVLogStartScopeF(level, id, ...) \
563  vtkLogger::StartScopeF(level, id, __FILE__, __LINE__, __VA_ARGS__)
564 
571 #define vtkLogIdentifier(vtkobject) vtkLogger::GetIdentifier(vtkobject).c_str()
572 
573 VTK_ABI_NAMESPACE_END
574 #endif
Verbosity verbosity
Definition: vtkLogger.h:328
The message structure that is passed to custom callbacks registered using vtkLogger::AddCallback.
Definition: vtkLogger.h:324
static bool EnableSigabrtHandler
Definition: vtkLogger.h:443
const char * indentation
Definition: vtkLogger.h:332
static bool EnableSigbusHandler
Definition: vtkLogger.h:444
const char * filename
Definition: vtkLogger.h:329
void(*)(void *user_data) CloseHandlerCallbackT
Callback handle types.
Definition: vtkLogger.h:342
virtual void PrintSelf(ostream &os, vtkIndent indent)
Methods invoked by print to print information about the object including superclasses.
void(*)(void *user_data) FlushHandlerCallbackT
Callback handle types.
Definition: vtkLogger.h:343
static bool EnableSigsegvHandler
Definition: vtkLogger.h:448
logging framework for use in VTK and in applications based on VTK
Definition: vtkLogger.h:186
a simple class to control print indentation
Definition: vtkIndent.h:28
const char * preamble
Definition: vtkLogger.h:331
#define VTK_PRINTF_LIKE(fmtarg, firstvararg)
Definition: vtkLogger.h:181
static bool EnableSigfpeHandler
Definition: vtkLogger.h:445
abstract base class for most VTK objects
Definition: vtkObjectBase.h:68
const char * message
Definition: vtkLogger.h:334
void(*)(void *user_data, const Message &message) LogHandlerCallbackT
Callback handle types.
Definition: vtkLogger.h:341
const char * prefix
Definition: vtkLogger.h:333
#define VTK_FILEPATH
static bool EnableSigtermHandler
Definition: vtkLogger.h:449
static bool EnableSigillHandler
Definition: vtkLogger.h:446
static bool EnableUnsafeSignalHandler
Flag to enable/disable the logging frameworks printing of a stack trace when catching signals...
Definition: vtkLogger.h:442
static bool EnableSigintHandler
Definition: vtkLogger.h:447
#define VTK_FORMAT_STRING_TYPE
Definition: vtkLogger.h:182
void operator=(const vtkObjectBase &)
FileMode
Support log file modes: TRUNCATE truncates the file clearing any existing contents while APPEND appen...
Definition: vtkLogger.h:288