This document provides an overview of the logging capabilities in Cinder. You can use this, along with the sample in samples/Logging, to quickly begin utilizing Cinder's built in logging capabilities.
Cinder logging resides in the
All Cinder apps start with the default
CI_LOG_D( "Hello world!" );
Would produce the following trace in the application console:
|debug | virtual void TestApp::setup()[40] Hello world!
Using concise, but flexible calls, a user can enable any number of additional loggers. Below is an example of how you would log to a file by adding an instance of
log::makeLogger<log::LoggerFile>( "/tmp/cinder/cinder.log" );
Before getting deeper into the features in
LEVEL_VERBOSE
is considered the lowest logging level, and LEVEL_FATAL
the highest. This is important when understanding how to configure logging levels in Cinder. The supported logging levels and their corresonding functions are below:
Level | Function | Enum Value | Comment |
LEVEL_VERBOSE | CI_LOG_V | 0 | (lowest logging level) |
LEVEL_DEBUG | CI_LOG_D | 1 | |
LEVEL_INFO | CI_LOG_I | 2 | |
LEVEL_WARNING | CI_LOG_W | 3 | |
LEVEL_ERROR | CI_LOG_E | 4 | |
LEVEL_FATAL | CI_LOG_F | 5 | (highest logging level) |
triggerLevel
defines the minimum logging level that will break execution.
/var/log/system.log
and the Event Log on Windows with MSW applications. WinRT system logging is still being developed.
The minimum system logging level can be controlled by calling
Note: By default, logging messages that are lower than LOG_NOTICE do not show up in the system log. This can be adjusted by configuring the /etc/syslog.conf
file, but in order for OS X system logging to work out of the box, Cinder logging levels are never mapped to a logging level lower than LOG_NOTICE. The full mapping is shown below. The log messages themselves will contain the Cinder logging level.
Cinder Level | Event Log Level |
LEVEL_VERBOSE | LOG_NOTICE |
LEVEL_DEBUG | LOG_NOTICE |
LEVEL_INFO | LOG_NOTICE |
LEVEL_WARNING | LOG_WARNING |
LEVEL_ERROR | LOG_ERR |
LEVEL_FATAL | LOG_CRIT |
Note: On Windows, there is no direct conversion of Cinder logging levels to Event Log logging levels. Event levels are mapped as follows. The log messages themselves will contain the Cinder logging level.
Cinder Level | Event Log Level |
LEVEL_VERBOSE | EVENTLOG_INFORMATION_TYPE |
LEVEL_DEBUG | EVENTLOG_INFORMATION_TYPE |
LEVEL_INFO | EVENTLOG_INFORMATION_TYPE |
LEVEL_WARNING | EVENTLOG_WARNING_TYPE |
LEVEL_ERROR | EVENTLOG_ERROR_TYPE |
LEVEL_FATAL | EVENTLOG_ERROR_TYPE |
Note: For deployments on Windows systems, you may find that you need to create and register an application manifest file. We are exploring how this may be integrated into the Cinder workflow, but in the mean time, please reference issue #1109 for information.
Multiple logger types aren't much use if you can't easily create, enable, and disable loggers. The
The LogManager allows you to add individual logs to the stack of active loggers. You can either keep track of loggers after you've added them to the stack, or you can search for the logger at a later point in time.
Example 1: Adding and forgetting a LoggerFile:
log::makeLogger<log::LoggerFile>( "/tmp/logging/cinder.log", true );
This causes a
Example 2: Adding and keeping a
log::LoggerRef logger = log::makeLogger<log::LoggerFile>( "/tmp/logging/cinder.log", true );
... log some things to the console and file
// remove the logger
log::manager()->removeLogger( logger );
... log some things to the console only
Example 3: Getting an active logger:
// gets the active LoggerSystem and sets the minimum level to LEVEL_ERROR
log::manager()->getLoggers<log::LoggerSystem>()[0]->setLoggingLevel( log::LEVEL_ERROR );
The CI_MIN_LOG_LEVEL
directive allows you to configure the minimum logging level that is enabled. For example, if you you included the following code in your main application:
#define CI_MIN_LOG_LEVEL 4
#include "cinder/Log.h"
Then the lowest enabled logging level would be LEVEL_ERROR
. Calls to lower logging levels, such as CI_LOG_D
would incur no runtime costs because the method is optimized away at compile time.
By default, when compiling your application in debug mode, all logging levels are supported.
By default, when compiling your application in release mode, all levels including and above LEVEL_INFO
are supported.
When you set CI_MIN_LOG_LEVEL
these default settings are overwritten.
Note: this is why the minimum system logging level can never be lower than the currently enabled Cinder logging level.
Sticking with the Cinder mantra "make easy things easy, and hard things possible", Cinder allows for the insertion of custom loggers. For example, if I felt like creating a logger that prepended text to my logging string, I could use the following code:
class SpecialLogger: public log::LoggerConsole
{
virtual void write( const log::Metadata &meta, const std::string &text ) override
{
LoggerConsole::write( meta, "Special: " + text );
}
};
...
log::makeLogger<SpecialLogger>();
CI_LOG_D( "nothing special.");
Which would print the following to the console output:
|debug | virtual void LoggingApp::setup()[51] Special: nothing special.