Viskores  1.0
Classes | Namespaces | Macros | Enumerations | Functions
Logging.h File Reference

Logging utilities. More...

#include <viskores/internal/Configure.h>
#include <viskores/internal/ExportMacros.h>
#include <viskores/Types.h>
#include <viskores/cont/viskores_cont_export.h>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <typeindex>
#include <typeinfo>

Go to the source code of this file.

Classes

struct  viskores::cont::LogCondStream
 Conditionally logs a message with a stream-like interface. More...
 

Namespaces

 viskores
 Groups connected points that have the same field value.
 
 viskores::cont
 Viskores Control Environment.
 

Macros

#define VISKORES_CONCAT_IMPL(s1, s2)   s1##s2
 
#define VISKORES_CONCAT(s1, s2)   VISKORES_CONCAT_IMPL(s1, s2)
 
#define VISKORES_ANONYMOUS_VARIABLE   VISKORES_CONCAT(viskores_anonymous_, __LINE__)
 
#define VISKORES_LOG_IF_S(level, cond, ...)   viskores::cont::LogCondStream(level, cond, __FILE__, __LINE__) << __VA_ARGS__
 
#define VISKORES_LOG_IF_F(level, cond, ...)   viskores::cont::LogCond(level, cond, __FILE__, __LINE__, __VA_ARGS__)
 
#define VISKORES_LOG_S(level, ...)   VISKORES_LOG_IF_S(level, true, __VA_ARGS__)
 Writes a message using stream syntax to the indicated log level. More...
 
#define VISKORES_LOG_F(level, ...)   VISKORES_LOG_IF_F(level, true, __VA_ARGS__)
 Writes a message using printf syntax to the indicated log level. More...
 
#define VISKORES_LOG_SCOPE(level, ...)
 
#define VISKORES_LOG_SCOPE_FUNCTION(level)   VISKORES_LOG_SCOPE(level, __func__)
 
#define VISKORES_LOG_ALWAYS_S(level, ...)   VISKORES_LOG_S(level, __VA_ARGS__)
 
#define VISKORES_LOG_CAST_SUCC(inObj, outObj)
 Convenience macro for logging the successful cast of dynamic object. More...
 
#define VISKORES_LOG_CAST_FAIL(inObj, outType)
 Convenience macro for logging a failed cast of dynamic object. More...
 
#define VISKORES_LOG_TRYEXECUTE_FAIL(errorMessage, functorName, deviceId)
 Convenience macro for logging a TryExecute failure to the Error level. If logging is disabled, a message is still printed to stderr. More...
 
#define VISKORES_LOG_TRYEXECUTE_DISABLE(errorMessage, functorName, deviceId)
 Similar to VISKORES_LOG_TRYEXECUTE_FAIL, but also informs the user that the device has been disable for future TryExecute calls. More...
 
#define VISKORES_DEFINE_USER_LOG_LEVEL(name, offset)
 Convenience macro for creating a custom log level that is usable in the other macros. If logging is disabled this macro does nothing. More...
 

Enumerations

enum  viskores::cont::LogLevel {
  viskores::cont::LogLevel::Off = -9, viskores::cont::LogLevel::Fatal = -3, viskores::cont::LogLevel::Error = -2, viskores::cont::LogLevel::Warn = -1,
  viskores::cont::LogLevel::Info = 0, viskores::cont::LogLevel::UserFirst = 1, viskores::cont::LogLevel::UserLast = 255, viskores::cont::LogLevel::DevicesEnabled,
  viskores::cont::LogLevel::Perf, viskores::cont::LogLevel::MemCont, viskores::cont::LogLevel::MemExec, viskores::cont::LogLevel::MemTransfer,
  viskores::cont::LogLevel::KernelLaunches, viskores::cont::LogLevel::Cast, viskores::cont::LogLevel::UserVerboseFirst = 1024, viskores::cont::LogLevel::UserVerboseLast = 2047
}
 Log levels for use with the logging macros. More...
 

Functions

viskores::cont::LogLevel viskores::cont::GetStderrLogLevel ()
 Get the active highest log level that will be printed to stderr. More...
 
void viskores::cont::SetLogLevelName (viskores::cont::LogLevel level, const std::string &name)
 Register a custom name to identify a log level. More...
 
std::string viskores::cont::GetLogLevelName (viskores::cont::LogLevel level)
 Get a human readable name for the log level. More...
 
std::string viskores::cont::GetLogErrorContext ()
 
std::string viskores::cont::GetStackTrace (viskores::Int32 skip=0)
 Returns a stacktrace on supported platforms. More...
 
std::string viskores::cont::GetHumanReadableSize (viskores::UInt64 bytes, int prec=2)
 Convert a size in bytes to a human readable string (such as "64 bytes", "1.44 MiB", "128 GiB", etc). More...
 
template<typename T >
std::string viskores::cont::GetHumanReadableSize (T &&bytes, int prec=2)
 
std::string viskores::cont::GetSizeString (viskores::UInt64 bytes, int prec=2)
 Returns "%1 (%2 bytes)" where %1 is the result from GetHumanReadableSize and %2 is the exact number of bytes. More...
 
template<typename T >
std::string viskores::cont::GetSizeString (T &&bytes, int prec=2)
 
void viskores::cont::LogCond (LogLevel level, bool cond, const char *file, unsigned line, const char *format...)
 Conditionally logs a message with a printf-like format. More...
 
void viskores::cont::InitLogging (int &argc, char *argv[], const std::string &loggingFlag="--viskores-log-level", const std::string &loggingEnv="VISKORES_LOG_LEVEL")
 This shouldn't be called directly – prefer calling viskores::cont::Initialize, which takes care of logging as well as other initializations. More...
 
void viskores::cont::InitLogging ()
 This shouldn't be called directly – prefer calling viskores::cont::Initialize, which takes care of logging as well as other initializations. More...
 
void viskores::cont::SetStderrLogLevel (const char *verbosity)
 Set the range of log levels that will be printed to stderr. More...
 
void viskores::cont::SetStderrLogLevel (viskores::cont::LogLevel level)
 Set the range of log levels that will be printed to stderr. More...
 
void viskores::cont::SetLogThreadName (const std::string &name)
 Specifies a humman-readable name to identify the current thread in the log output. More...
 
std::string viskores::cont::GetLogThreadName ()
 Specifies a humman-readable name to identify the current thread in the log output. More...
 
std::string viskores::cont::TypeToString (const std::type_info &t)
 Use RTTI information to retrieve the name of the type T. More...
 
std::string viskores::cont::TypeToString (const std::type_index &t)
 Use RTTI information to retrieve the name of the type T. More...
 
template<typename T >
std::string viskores::cont::TypeToString ()
 Use RTTI information to retrieve the name of the type T. More...
 
template<typename T >
std::string viskores::cont::TypeToString (const T &)
 Use RTTI information to retrieve the name of the type T. More...
 
void viskores::cont::InitLogging (int &argc, char *argv[], const std::string &loggingFlag="--viskores-log-level", const std::string &loggingEnv="VISKORES_LOG_LEVEL")
 This shouldn't be called directly – prefer calling viskores::cont::Initialize, which takes care of logging as well as other initializations. More...
 
void viskores::cont::InitLogging ()
 This shouldn't be called directly – prefer calling viskores::cont::Initialize, which takes care of logging as well as other initializations. More...
 
void viskores::cont::SetStderrLogLevel (const char *verbosity)
 Set the range of log levels that will be printed to stderr. More...
 
void viskores::cont::SetStderrLogLevel (viskores::cont::LogLevel level)
 Set the range of log levels that will be printed to stderr. More...
 
void viskores::cont::SetLogThreadName (const std::string &name)
 Specifies a humman-readable name to identify the current thread in the log output. More...
 
std::string viskores::cont::GetLogThreadName ()
 Specifies a humman-readable name to identify the current thread in the log output. More...
 
std::string viskores::cont::TypeToString (const std::type_info &t)
 Use RTTI information to retrieve the name of the type T. More...
 
std::string viskores::cont::TypeToString (const std::type_index &t)
 Use RTTI information to retrieve the name of the type T. More...
 
template<typename T >
std::string viskores::cont::TypeToString ()
 Use RTTI information to retrieve the name of the type T. More...
 
template<typename T >
std::string viskores::cont::TypeToString (const T &)
 Use RTTI information to retrieve the name of the type T. More...
 

Detailed Description

Logging utilities.

This file includes the logging system for Viskores. There are a variety of macros to print log messages using C++ stream or printf syntax. Nested scopes may be created in the log output, and there are several helper functions to help format common types of log data such as byte counts and type names.

Logging is enabled via the CMake option Viskores_ENABLE_LOGGING by default. The default log level is set to only log Warn and Error messages; Fatal levels are printed to stderr by default. The logging system will need to be initialized through a call to either viskores::cont::Initialize or viskores::cont::InitLogging.

Additional logging features are enabled by calling viskores::cont::InitLogging (or preferably, viskores::cont::Initialize) in an executable. This will:

The main logging entry points are the macros VISKORES_LOG_S and VISKORES_LOG_F, which using C++ stream and printf syntax, repectively. Other variants exist, including conditional logging and special-purpose logs for writing specific events, such as DynamicObject cast results and TryExecute failures.

The logging backend supports the concept of "Scopes". By creating a new scope with the macros VISKORES_LOG_SCOPE or VISKORES_LOG_SCOPE_FUNCTION, a new "logging scope" is opened within the C++ scope the macro is called from. New messages will be indented in the log until the scope ends, at which point a message is logged with the elapsed time that the scope was active. Scopes may be nested to arbitrary depths.

The logging implementation is thread-safe. When working in a multithreaded environment, each thread may be assigned a human-readable name using viskores::cont::SetThreadName. This will appear in the log output so that per-thread messages can be easily tracked.

By default, only Warn, Error, and Fatal messages are printed to stderr. This can be changed at runtime by passing the '–viskores-log-level' flag to an executable that calls viskores::cont::InitLogging. Alternatively, the application can explicitly call viskores::cont::SetStderrLogLevel to change the verbosity. When specifying a verbosity, all log levels with enum values less-than-or-equal-to the requested level are printed. viskores::cont::LogLevel::Off (or "--viskores-log-level Off") may be used to silence the log completely.

The helper functions viskores::cont::GetHumanReadableSize and viskores::cont::GetSizeString assist in formating byte sizes to a more readable format. Similarly, the viskores::cont::TypeToString template functions provide RTTI based type-name information. When logging is enabled, these use the logging backend to demangle symbol names on supported platforms.

The more verbose Viskores log levels are:

The log may be shared and extended by applications that use Viskores. There are two log level ranges left available for applications: User and UserVerbose. The User levels may be enabled without showing any of the verbose Viskores levels, while UserVerbose levels will also enable all Viskores levels.

Macro Definition Documentation

◆ VISKORES_ANONYMOUS_VARIABLE

#define VISKORES_ANONYMOUS_VARIABLE   VISKORES_CONCAT(viskores_anonymous_, __LINE__)

◆ VISKORES_CONCAT

#define VISKORES_CONCAT (   s1,
  s2 
)    VISKORES_CONCAT_IMPL(s1, s2)

◆ VISKORES_CONCAT_IMPL

#define VISKORES_CONCAT_IMPL (   s1,
  s2 
)    s1##s2

◆ VISKORES_DEFINE_USER_LOG_LEVEL

#define VISKORES_DEFINE_USER_LOG_LEVEL (   name,
  offset 
)
Value:
static constexpr viskores::cont::LogLevel name = static_cast<viskores::cont::LogLevel>( \
static_cast<typename std::underlying_type<viskores::cont::LogLevel>::type>( \
viskores::cont::LogLevel::UserFirst) + \
offset % \
static_cast<typename std::underlying_type<viskores::cont::LogLevel>::type>( \

Convenience macro for creating a custom log level that is usable in the other macros. If logging is disabled this macro does nothing.

Parameters
nameThe name to give the new log level
offsetThe offset from the viskores::cont::LogLevel::UserFirst value from the LogLevel enum. Additionally moduloed against the viskores::cont::LogLevel::UserLast value
Note
This macro is to be used for quickly setting log levels. For a more maintainable solution it is recommended to create a custom enum class and then cast appropriately, as described here: https://gitlab.kitware.com/vtk/viskores/-/issues/358#note_550157

◆ VISKORES_LOG_ALWAYS_S

#define VISKORES_LOG_ALWAYS_S (   level,
  ... 
)    VISKORES_LOG_S(level, __VA_ARGS__)

This ostream-style log message is always emitted, even when logging is disabled at compile time.

◆ VISKORES_LOG_CAST_FAIL

#define VISKORES_LOG_CAST_FAIL (   inObj,
  outType 
)
Value:
"Cast failed: %s (%p) --> %s", \
viskores::cont::TypeToString(inObj).c_str(), \
&inObj, \
viskores::cont::TypeToString<outType>().c_str())

Convenience macro for logging a failed cast of dynamic object.

Parameters
inObjThe dynamic object.
outTypeThe candidate type (or typelist) that was unsuccessful.

◆ VISKORES_LOG_CAST_SUCC

#define VISKORES_LOG_CAST_SUCC (   inObj,
  outObj 
)
Value:
"Cast succeeded: %s (%p) --> %s (%p)", \
viskores::cont::TypeToString(inObj).c_str(), \
&inObj, \
viskores::cont::TypeToString(outObj).c_str(), \
&outObj)

Convenience macro for logging the successful cast of dynamic object.

Parameters
inObjThe dynamic object.
outObjThe resulting downcasted object.

◆ VISKORES_LOG_F

#define VISKORES_LOG_F (   level,
  ... 
)    VISKORES_LOG_IF_F(level, true, __VA_ARGS__)

Writes a message using printf syntax to the indicated log level.

The ellipsis may be replaced with the log message as if constructing a printf call, e.g:

"Executed functor %s on device %s",
viskores::cont::TypeToString(functor).c_str(),
deviceId.GetName().c_str());

◆ VISKORES_LOG_IF_F

#define VISKORES_LOG_IF_F (   level,
  cond,
  ... 
)    viskores::cont::LogCond(level, cond, __FILE__, __LINE__, __VA_ARGS__)

Same as VISKORES_LOG_F, but only logs if cond is true.

◆ VISKORES_LOG_IF_S

#define VISKORES_LOG_IF_S (   level,
  cond,
  ... 
)    viskores::cont::LogCondStream(level, cond, __FILE__, __LINE__) << __VA_ARGS__

Same as VISKORES_LOG_S, but only logs if cond is true.

◆ VISKORES_LOG_S

#define VISKORES_LOG_S (   level,
  ... 
)    VISKORES_LOG_IF_S(level, true, __VA_ARGS__)

Writes a message using stream syntax to the indicated log level.

The ellipsis may be replaced with the log message as if constructing a C++ stream, e.g:

"Executed functor " << viskores::cont::TypeToString(functor)
<< " on device " << deviceId.GetName());

◆ VISKORES_LOG_SCOPE

#define VISKORES_LOG_SCOPE (   level,
  ... 
)
Value:
viskores::cont::detail::LogScope VISKORES_ANONYMOUS_VARIABLE \
{ \
level, __FILE__, __LINE__, __VA_ARGS__ \
}

Creates a new scope at the requested level. The log scope ends when the code scope ends. The ellipses form the scope name using printf syntax.

{
"Executing filter %s",
viskores::cont::TypeToString(myFilter).c_str());
myFilter.Execute();
}

◆ VISKORES_LOG_SCOPE_FUNCTION

#define VISKORES_LOG_SCOPE_FUNCTION (   level)    VISKORES_LOG_SCOPE(level, __func__)

◆ VISKORES_LOG_TRYEXECUTE_DISABLE

#define VISKORES_LOG_TRYEXECUTE_DISABLE (   errorMessage,
  functorName,
  deviceId 
)
Value:
"TryExecute encountered an error: " << errorMessage); \
VISKORES_LOG_S(viskores::cont::LogLevel::Error, "Failing functor: " << functorName); \
VISKORES_LOG_S(viskores::cont::LogLevel::Error, "Failing device: " << deviceId.GetName()); \
VISKORES_LOG_S(viskores::cont::LogLevel::Error, "The failing device has been disabled.")

Similar to VISKORES_LOG_TRYEXECUTE_FAIL, but also informs the user that the device has been disable for future TryExecute calls.

Parameters
errorMessageThe error message detailing the failure.
functorNameThe name of the functor (see viskores::cont::TypeToString)
deviceIdThe device tag / id for the device on which the functor failed.

◆ VISKORES_LOG_TRYEXECUTE_FAIL

#define VISKORES_LOG_TRYEXECUTE_FAIL (   errorMessage,
  functorName,
  deviceId 
)
Value:
"TryExecute encountered an error: " << errorMessage); \
VISKORES_LOG_S(viskores::cont::LogLevel::Error, "Failing functor: " << functorName); \
VISKORES_LOG_S(viskores::cont::LogLevel::Error, "Failing device: " << deviceId.GetName())

Convenience macro for logging a TryExecute failure to the Error level. If logging is disabled, a message is still printed to stderr.

Parameters
errorMessageThe error message detailing the failure.
functorNameThe name of the functor (see viskores::cont::TypeToString)
deviceIdThe device tag / id for the device on which the functor failed.
viskores::cont::LogLevel::Error
@ Error
Important but non-fatal errors, such as device fail-over.
VISKORES_LOG_SCOPE
#define VISKORES_LOG_SCOPE(level,...)
Definition: Logging.h:219
VISKORES_LOG_F
#define VISKORES_LOG_F(level,...)
Writes a message using printf syntax to the indicated log level.
Definition: Logging.h:217
viskores::cont::LogLevel::UserLast
@ UserLast
The last in a range of logging levels reserved for code that uses Viskores.
viskores::cont::LogLevel::Cast
@ Cast
Reports when a dynamic object is (or is not) resolved via a CastAndCall or other casting method.
viskores::cont::LogLevel
LogLevel
Log levels for use with the logging macros.
Definition: Logging.h:311
VISKORES_LOG_S
#define VISKORES_LOG_S(level,...)
Writes a message using stream syntax to the indicated log level.
Definition: Logging.h:216
viskores::cont::LogLevel::Perf
@ Perf
General timing data and algorithm flow information, such as filter execution, worklet dispatches,...
VISKORES_ANONYMOUS_VARIABLE
#define VISKORES_ANONYMOUS_VARIABLE
Definition: Logging.h:205
viskores::cont::TypeToString
std::string TypeToString(const std::type_info &t)
Use RTTI information to retrieve the name of the type T.