OpenVDB: logging.h Source File

OpenVDB 6.0.0

logging.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2018 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30
31 #ifndef OPENVDB_UTIL_LOGGING_HAS_BEEN_INCLUDED
32 #define OPENVDB_UTIL_LOGGING_HAS_BEEN_INCLUDED
33
34 #include <openvdb/version.h>
35
36 #ifdef OPENVDB_USE_LOG4CPLUS
37
38 #include <log4cplus/appender.h>
39 #include <log4cplus/configurator.h>
40 #include <log4cplus/consoleappender.h>
41 #include <log4cplus/layout.h>
42 #include <log4cplus/logger.h>
43 #include <log4cplus/spi/loggingevent.h>
44 #include <algorithm> // for std::remove()
45 #include <cstring> // for ::strrchr()
46 #include <memory>
47 #include <sstream>
48 #include <string>
49 #include <vector>
50
51
52 namespace openvdb {
53 OPENVDB_USE_VERSION_NAMESPACE
54 namespace OPENVDB_VERSION_NAME {
55 namespace logging {
56
58 enum class Level {
59 Debug = log4cplus::DEBUG_LOG_LEVEL,
60 Info = log4cplus::INFO_LOG_LEVEL,
61 Warn = log4cplus::WARN_LOG_LEVEL,
62 Error = log4cplus::ERROR_LOG_LEVEL,
63 Fatal = log4cplus::FATAL_LOG_LEVEL
64 };
65
66
67 namespace internal {
68
71 class ColoredPatternLayout: public log4cplus::PatternLayout
72 {
73 public:
74 explicit ColoredPatternLayout(const std::string& progName_, bool useColor = true)
75 : log4cplus::PatternLayout(
76 progName_.empty() ? std::string{"%5p: %m%n"} : (progName_ + " %5p: %m%n"))
77 , mUseColor(useColor)
78 , mProgName(progName_)
79 {
80 }
81
82 ~ColoredPatternLayout() override {}
83
84 const std::string& progName() const { return mProgName; }
85
86 void formatAndAppend(log4cplus::tostream& strm,
87 const log4cplus::spi::InternalLoggingEvent& event) override
88 {
89 if (!mUseColor) {
90 log4cplus::PatternLayout::formatAndAppend(strm, event);
91 return;
92 }
93 log4cplus::tostringstream s;
94 switch (event.getLogLevel()) {
95 case log4cplus::DEBUG_LOG_LEVEL: s << "\033[32m"; break; // green
96 case log4cplus::ERROR_LOG_LEVEL:
97 case log4cplus::FATAL_LOG_LEVEL: s << "\033[31m"; break; // red
98 case log4cplus::INFO_LOG_LEVEL: s << "\033[36m"; break; // cyan
99 case log4cplus::WARN_LOG_LEVEL: s << "\033[35m"; break; // magenta
100 }
101 log4cplus::PatternLayout::formatAndAppend(s, event);
102 strm << s.str() << "\033[0m" << std::flush;
103 }
104
105 // Disable deprecation warnings for std::auto_ptr.
106 #if defined(__ICC)
107 #pragma warning push
108 #pragma warning disable:1478
109 #elif defined(__clang__)
110 #pragma clang diagnostic push
111 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
112 #elif defined(__GNUC__)
113 #pragma GCC diagnostic push
114 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
115 #endif
116
117 #if defined(LOG4CPLUS_VERSION) && defined(LOG4CPLUS_MAKE_VERSION)
118 #if LOG4CPLUS_VERSION >= LOG4CPLUS_MAKE_VERSION(2, 0, 0)
119 // In log4cplus 2.0.0, std::auto_ptr was replaced with std::unique_ptr.
120 using Ptr = std::unique_ptr<log4cplus::Layout>;
121 #else
122 using Ptr = std::auto_ptr<log4cplus::Layout>;
123 #endif
124 #else
125 using Ptr = std::auto_ptr<log4cplus::Layout>;
126 #endif
127
128 static Ptr create(const std::string& progName_, bool useColor = true)
129 {
130 return Ptr{new ColoredPatternLayout{progName_, useColor}};
131 }
132
133 #if defined(__ICC)
134 #pragma warning pop
135 #elif defined(__clang__)
136 #pragma clang diagnostic pop
137 #elif defined(__GNUC__)
138 #pragma GCC diagnostic pop
139 #endif
140
141 private:
142 bool mUseColor = true;
143 std::string mProgName;
144 }; // class ColoredPatternLayout
145
146
147 inline log4cplus::Logger
148 getLogger()
149 {
150 return log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("openvdb"));
151 }
152
153
154 inline log4cplus::SharedAppenderPtr
155 getAppender()
156 {
157 return getLogger().getAppender(LOG4CPLUS_TEXT("OPENVDB"));
158 }
159
160 } // namespace internal
161
162
164 inline Level
165 getLevel()
166 {
167 switch (internal::getLogger().getLogLevel()) {
168 case log4cplus::DEBUG_LOG_LEVEL: return Level::Debug;
169 case log4cplus::INFO_LOG_LEVEL: return Level::Info;
170 case log4cplus::WARN_LOG_LEVEL: return Level::Warn;
171 case log4cplus::ERROR_LOG_LEVEL: return Level::Error;
172 case log4cplus::FATAL_LOG_LEVEL: break;
173 }
174 return Level::Fatal;
175 }
176
177
179 inline void
180 setLevel(Level lvl)
181 {
182 internal::getLogger().setLogLevel(static_cast<log4cplus::LogLevel>(lvl));
183 }
184
185
189 inline void
190 setLevel(int& argc, char* argv[])
191 {
192 for (int i = 1; i < argc; ++i) { // note: skip argv[0]
193 const std::string arg{argv[i]};
194 bool remove = true;
195 if (arg == "-debug") { setLevel(Level::Debug); }
196 else if (arg == "-error") { setLevel(Level::Error); }
197 else if (arg == "-fatal") { setLevel(Level::Fatal); }
198 else if (arg == "-info") { setLevel(Level::Info); }
199 else if (arg == "-warn") { setLevel(Level::Warn); }
200 else { remove = false; }
201 if (remove) argv[i] = nullptr;
202 }
203 auto end = std::remove(argv + 1, argv + argc, nullptr);
204 argc = static_cast<int>(end - argv);
205 }
206
207
209 inline void
210 setProgramName(const std::string& progName, bool useColor = true)
211 {
212 // Change the layout of the OpenVDB appender to use colored text
213 // and to incorporate the supplied program name.
214 if (auto appender = internal::getAppender()) {
215 appender->setLayout(internal::ColoredPatternLayout::create(progName, useColor));
216 }
217 }
218
219
221 inline void
222 initialize(bool useColor = true)
223 {
224 log4cplus::initialize();
225
226 if (internal::getAppender()) return; // already initialized
227
228 // Create the OpenVDB logger if it doesn't already exist.
229 auto logger = internal::getLogger();
230
231 // Disable "additivity", so that OpenVDB-related messages are directed
232 // to the OpenVDB logger only and are not forwarded up the logger tree.
233 logger.setAdditivity(false);
234
235 // Attach a console appender to the OpenVDB logger.
236 if (auto appender = log4cplus::SharedAppenderPtr{new log4cplus::ConsoleAppender}) {
237 appender->setName(LOG4CPLUS_TEXT("OPENVDB"));
238 logger.addAppender(appender);
239 }
240
241 setLevel(Level::Warn);
242 setProgramName("", useColor);
243 }
244
245
250 inline void
251 initialize(int& argc, char* argv[], bool useColor = true)
252 {
253 initialize();
254
255 setLevel(argc, argv);
256
257 auto progName = (argc > 0 ? argv[0] : "");
258 if (const char* ptr = ::strrchr(progName, '/')) progName = ptr + 1;
259 setProgramName(progName, useColor);
260 }
261
262 } // namespace logging
263 } // namespace OPENVDB_VERSION_NAME
264 } // namespace openvdb
265
266
267 #define OPENVDB_LOG(level, message) \
268 do { \
269 auto _log = openvdb::logging::internal::getLogger(); \
270 if (_log.isEnabledFor(log4cplus::level##_LOG_LEVEL)) { \
271 std::ostringstream _buf; \
272 _buf << message; \
273 _log.forcedLog(log4cplus::level##_LOG_LEVEL, _buf.str(), __FILE__, __LINE__); \
274 } \
275 } while (0);
276
278 #define OPENVDB_LOG_INFO(message) OPENVDB_LOG(INFO, message)
279 #define OPENVDB_LOG_WARN(message) OPENVDB_LOG(WARN, message)
281 #define OPENVDB_LOG_ERROR(message) OPENVDB_LOG(ERROR, message)
283 #define OPENVDB_LOG_FATAL(message) OPENVDB_LOG(FATAL, message)
285 #ifdef DEBUG
286 #define OPENVDB_LOG_DEBUG(message) OPENVDB_LOG(DEBUG, message)
288 #else
289 #define OPENVDB_LOG_DEBUG(message)
291 #endif
292 #define OPENVDB_LOG_DEBUG_RUNTIME(message) OPENVDB_LOG(DEBUG, message)
295
296 #else // ifdef OPENVDB_USE_LOG4CPLUS
297
298 #include <iostream>
299
300 #define OPENVDB_LOG_INFO(mesg)
301 #define OPENVDB_LOG_WARN(mesg) do { std::cerr << "WARNING: " << mesg << std::endl; } while (0);
302 #define OPENVDB_LOG_ERROR(mesg) do { std::cerr << "ERROR: " << mesg << std::endl; } while (0);
303 #define OPENVDB_LOG_FATAL(mesg) do { std::cerr << "FATAL: " << mesg << std::endl; } while (0);
304 #define OPENVDB_LOG_DEBUG(mesg)
305 #define OPENVDB_LOG_DEBUG_RUNTIME(mesg)
306
307 namespace openvdb {
308 OPENVDB_USE_VERSION_NAMESPACE
309 namespace OPENVDB_VERSION_NAME {
310 namespace logging {
311
312 enum class Level { Debug, Info, Warn, Error, Fatal };
313
314 inline Level getLevel() { return Level::Warn; }
315 inline void setLevel(Level) {}
316 inline void setLevel(int&, char*[]) {}
317 inline void setProgramName(const std::string&, bool = true) {}
318 inline void initialize() {}
319 inline void initialize(int&, char*[], bool = true) {}
320
321 } // namespace logging
322 } // namespace OPENVDB_VERSION_NAME
323 } // namespace openvdb
324
325 #endif // OPENVDB_USE_LOG4CPLUS
326
327
328 namespace openvdb {
329 OPENVDB_USE_VERSION_NAMESPACE
330 namespace OPENVDB_VERSION_NAME {
331 namespace logging {
332
335 struct LevelScope
336 {
337 Level level;
338 explicit LevelScope(Level newLevel): level(getLevel()) { setLevel(newLevel); }
339 ~LevelScope() { setLevel(level); }
340 };
341
342 } // namespace logging
343 } // namespace OPENVDB_VERSION_NAME
344 } // namespace openvdb
345
346 #endif // OPENVDB_UTIL_LOGGING_HAS_BEEN_INCLUDED
347
348 // Copyright (c) 2012-2018 DreamWorks Animation LLC
349 // All rights reserved. This software is distributed under the
350 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
openvdb::v6_0::logging::internal::getAppender
log4cplus::SharedAppenderPtr getAppender()
Definition: logging.h:155
openvdb::v6_0::logging::setLevel
void setLevel(int &argc, char *argv[])
If "-debug", "-info", "-warn", "-error" or "-fatal" is found in the given array of command-line argum...
Definition: logging.h:190
openvdb::v6_0::logging::internal::ColoredPatternLayout::~ColoredPatternLayout
~ColoredPatternLayout() override
Definition: logging.h:82
openvdb::v6_0::logging::Level::Fatal
openvdb::v6_0::logging::internal::ColoredPatternLayout
log4cplus layout that outputs text in different colors for different log levels, using ANSI escape co...
Definition: logging.h:71
openvdb::v6_0::logging::internal::ColoredPatternLayout::formatAndAppend
void formatAndAppend(log4cplus::tostream &strm, const log4cplus::spi::InternalLoggingEvent &event) override
Definition: logging.h:86
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
openvdb::v6_0::logging::Level::Info
openvdb
Definition: Exceptions.h:40
openvdb::v6_0::logging::Level
Level
Message severity level.
Definition: logging.h:58
openvdb::v6_0::logging::setProgramName
void setProgramName(const std::string &progName, bool useColor=true)
Specify a program name to be displayed in log messages.
Definition: logging.h:210
openvdb::v6_0::logging::internal::getLogger
log4cplus::Logger getLogger()
Definition: logging.h:148
openvdb::v6_0::logging::LevelScope
A LevelScope object sets the logging level to a given level and restores it to the current level when...
Definition: logging.h:335
version.h
Library and file format version numbers.
openvdb::v6_0::logging::Level::Warn
openvdb::v6_0::logging::internal::ColoredPatternLayout::ColoredPatternLayout
ColoredPatternLayout(const std::string &progName_, bool useColor=true)
Definition: logging.h:74
openvdb::v6_0::logging::initialize
void initialize(int &argc, char *argv[], bool useColor=true)
Initialize the logging system from command-line arguments.
Definition: logging.h:251
openvdb::v6_0::logging::LevelScope::~LevelScope
~LevelScope()
Definition: logging.h:339
openvdb::v6_0::logging::LevelScope::LevelScope
LevelScope(Level newLevel)
Definition: logging.h:338
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
openvdb::v6_0::logging::getLevel
Level getLevel()
Return the current logging level.
Definition: logging.h:165
openvdb::v6_0::logging::LevelScope::level
Level level
Definition: logging.h:337
openvdb::v6_0::logging::Level::Debug
openvdb::v6_0::logging::internal::ColoredPatternLayout::create
static Ptr create(const std::string &progName_, bool useColor=true)
Definition: logging.h:128
openvdb::v6_0::logging::internal::ColoredPatternLayout::Ptr
std::auto_ptr< log4cplus::Layout > Ptr
Definition: logging.h:125
openvdb::v6_0::logging::Level::Error
openvdb::v6_0::logging::internal::ColoredPatternLayout::progName
const std::string & progName() const
Definition: logging.h:84