OpenVDB 14.0.0
Loading...
Searching...
No Matches
logging.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3
4#ifndef OPENVDB_UTIL_LOGGING_HAS_BEEN_INCLUDED
5#define OPENVDB_UTIL_LOGGING_HAS_BEEN_INCLUDED
6
7#include <openvdb/version.h>
8#include <openvdb/Platform.h>
9
10#include <atomic>
11#include <memory>
12#include <sstream>
13#include <string>
14
15namespace openvdb {
17namespace OPENVDB_VERSION_NAME {
18namespace logging {
19
20/// @brief Message severity level, in increasing order of severity.
21enum class Level { Debug = 0, Info, Warn, Error, Fatal };
22
23/// @brief Return the current severity threshold. Messages below this are dropped.
25
26/// @brief Set the severity threshold. Messages below this are dropped.
28
29/// @brief Return true if a message of the given level would be logged.
30/// @details Used by the logging macros to skip formatting a message that would
31/// be discarded. This is a single relaxed atomic load.
33
34/// @brief If "-debug", "-info", "-warn", "-error" or "-fatal" is found
35/// in the given array of command-line arguments, set the logging level
36/// appropriately and remove the relevant argument(s) from the array.
37OPENVDB_API void setLevel(int& argc, char* argv[]);
38
39/// @brief Receives formatted log messages. Subclass this to route OpenVDB
40/// diagnostics into a host application.
41/// @details Sinks are called on the thread that logged the message, so an
42/// implementation must be thread safe. A sink must not throw.
43///
44/// @par Example
45/// @code
46/// class MySink: public openvdb::logging::Sink
47/// {
48/// public:
49/// MySink(): Sink("mysink") {}
50/// void append(openvdb::logging::Level level, const std::string& message,
51/// const char* file, int line) override
52/// {
53/// // forward to the host application's own logging system
54/// }
55/// };
56///
57/// openvdb::logging::addSink(std::make_shared<MySink>());
58/// @endcode
60{
61public:
62 using Ptr = std::shared_ptr<Sink>;
63
64 /// @param name Unique identifier, used by removeSink() and findSink().
65 /// @param threshold Messages below this level are not delivered to this sink,
66 /// in addition to the global threshold from setLevel().
67 explicit Sink(const std::string& name, Level threshold = Level::Debug);
68 virtual ~Sink();
69
70 const std::string& name() const;
71
74
75 /// @param level Severity of the message.
76 /// @param message The formatted message text, without a trailing newline.
77 /// @param file Source file the message was logged from, may be null.
78 /// @param line Line in @a file, or 0 if unknown.
79 virtual void append(Level level, const std::string& message,
80 const char* file, int line) = 0;
81
82private:
83 const std::string mName;
84 std::atomic<Level> mThreshold;
85};
86
87/// @brief Register a sink. Replaces any existing sink with the same name.
89
90/// @brief Remove the sink with the given name. Returns true if one was removed.
91OPENVDB_API bool removeSink(const std::string& name);
92
93/// @brief Return the sink with the given name, or nullptr.
94OPENVDB_API Sink::Ptr findSink(const std::string& name);
95
96/// @brief The sink installed by default, writing to std::cerr.
98{
99public:
100 /// The name under which this sink is registered.
101 static const char* defaultName();
102
103 /// @brief Return true if stderr is connected to a terminal.
104 static bool stderrIsTerminal();
105
107
108 bool useColor() const;
109 void setUseColor(bool);
110
111 void append(Level, const std::string& message, const char* file, int line) override;
112
113private:
114 std::atomic<bool> mUseColor;
115};
116
117/// @brief Install the default console sink if no sink has been installed yet.
118/// @details By default, color is enabled only if stderr is connected to a terminal.
120
121/// @brief Initialize and then apply any level flags found in the arguments.
122/// @details By default, color is enabled only if stderr is connected to a terminal.
123OPENVDB_API void initialize(int& argc, char* argv[], bool useColor = ConsoleSink::stderrIsTerminal());
124
125/// @brief Sets the level on construction and restores the previous level on
126/// destruction.
128{
130 explicit LevelScope(Level newLevel): level(getLevel()) { setLevel(newLevel); }
132};
133
134/// @cond OPENVDB_DOCS_INTERNAL
135
136namespace internal {
137
138OPENVDB_API void dispatch(Level level, const std::string& message,
139 const char* file, int line);
140
141} // namespace internal
142
143/// @endcond
144
145} // namespace logging
146} // namespace OPENVDB_VERSION_NAME
147} // namespace openvdb
148
149
150#define OPENVDB_LOG(level, message) \
151 do { \
152 if (openvdb::logging::isEnabledFor(openvdb::logging::Level::level)) { \
153 std::ostringstream _buf; \
154 _buf << message; \
155 openvdb::logging::internal::dispatch( \
156 openvdb::logging::Level::level, _buf.str(), __FILE__, __LINE__); \
157 } \
158 } while (0)
159
160/// Log an info message of the form '<TT>someVar << "some text" << ...</TT>'.
161#define OPENVDB_LOG_INFO(message) OPENVDB_LOG(Info, message)
162/// Log a warning message of the form '<TT>someVar << "some text" << ...</TT>'.
163#define OPENVDB_LOG_WARN(message) OPENVDB_LOG(Warn, message)
164/// Log an error message of the form '<TT>someVar << "some text" << ...</TT>'.
165#define OPENVDB_LOG_ERROR(message) OPENVDB_LOG(Error, message)
166/// Log a fatal error message of the form '<TT>someVar << "some text" << ...</TT>'.
167#define OPENVDB_LOG_FATAL(message) OPENVDB_LOG(Fatal, message)
168#ifdef NDEBUG
169/// In debug builds only, log a debugging message of the form '<TT>someVar << "text" << ...</TT>'.
170#define OPENVDB_LOG_DEBUG(message)
171#else
172/// In debug builds only, log a debugging message of the form '<TT>someVar << "text" << ...</TT>'.
173#define OPENVDB_LOG_DEBUG(message) OPENVDB_LOG(Debug, message)
174#endif
175/// @brief Log a debugging message in both debug and optimized builds.
176/// @warning Don't use this in performance-critical code.
177#define OPENVDB_LOG_DEBUG_RUNTIME(message) OPENVDB_LOG(Debug, message)
178
179#endif // OPENVDB_UTIL_LOGGING_HAS_BEEN_INCLUDED
#define OPENVDB_API
Definition Platform.h:286
static bool stderrIsTerminal()
Return true if stderr is connected to a terminal.
ConsoleSink(bool useColor=stderrIsTerminal())
void append(Level, const std::string &message, const char *file, int line) override
static const char * defaultName()
The name under which this sink is registered.
const std::string & name() const
Sink(const std::string &name, Level threshold=Level::Debug)
virtual void append(Level level, const std::string &message, const char *file, int line)=0
std::shared_ptr< Sink > Ptr
Definition logging.h:62
Definition logging.h:18
Level
Message severity level, in increasing order of severity.
Definition logging.h:21
@ Info
Definition logging.h:21
@ Warn
Definition logging.h:21
@ Fatal
Definition logging.h:21
@ Error
Definition logging.h:21
@ Debug
Definition logging.h:21
Sink::Ptr findSink(const std::string &name)
Return the sink with the given name, or nullptr.
bool isEnabledFor(Level)
Return true if a message of the given level would be logged.
void addSink(const Sink::Ptr &)
Register a sink. Replaces any existing sink with the same name.
void setLevel(Level)
Set the severity threshold. Messages below this are dropped.
Level getLevel()
Return the current severity threshold. Messages below this are dropped.
bool removeSink(const std::string &name)
Remove the sink with the given name. Returns true if one was removed.
void initialize(bool useColor=ConsoleSink::stderrIsTerminal())
Install the default console sink if no sink has been installed yet.
Definition Exceptions.h:13
Level level
Definition logging.h:129
LevelScope(Level newLevel)
Definition logging.h:130
~LevelScope()
Definition logging.h:131
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:291