Classes | |
class | MsgLogger::MsgFormatter |
class | MsgLogger::MsgHandler |
class | MsgLogger::MsgLogger |
class | MsgLogger::MsgLogLevel |
class | MsgLogger::MsgLogRecord |
class | MsgLogger::MsgLogStream |
debug
trace
info
warning
error
fatal
Logging service can dispatch messages based on their severity. Allowing logging for one particular lever automatically allows logging for higher severity as well (enabling info
level will enable warning
, error
, and fatal
as well). Messages with hight severity such as error
and fatal
cannot be disabled at all. Difference between error
and fatal
is that fatal
messages automatically terminate application after the message handling is complete (meaning that message is printed or sent to destination).
In usual setup logging service is configured to enable only info
severity (plus warning
, error
, and fatal
). Default configuration can be changed via application-dependent options, usually via command line or environment variables.
These properties can be displayed as a part of the printed output produced by messaging service. Which properties are displayed and format of their output can be changed via configuration.
debug
level and accept all events.Currently there is only one type of handler implemented which logs messages to standard output or error (for warning, error, and fatal messages) streams.
Loggers like handlers have associated severity levels. Every logger has zero or more associated handlers. If logger's severity is the same or lower than message severity then the message is sent to every associated handler.
By default (if not configured specifically) the logger also sends all messages to the parent logger. Such hierarchical relations are used to simplify control over multiple loggers. Imagine for example that some library or facility uses following loggers for its messages: "Foo.Bar", "Foo.Baz", and "Foo.Qux". By enabling for example debugging logging for "Foo" logger all debug messages from every child logger "Foo.*" will be enabled as well.
MsgLog(logger, severity, message)
MsgLogRoot(severity, message)
WithMsgLog(logger, severity, stream)
WithMsgLogRoot(severity, stream)
Two of these macros take the logger name as the first argument, logger name can be either C-style character string (or char*) or C++ std::string
object. Two other macros do not the logger name and instead send the messages directly to root logger. Preferred forms are those which use logger name, providing logger name gives more flexibility in controlling the output. Severity
parameter to these macros should be a constant defined in MsgLogLevel class, one of debug
, trace
, info
, warning
, error
, or fatal
.
Two of the macros take an expression as the last argument which is used to generate message. this expression can be anything that can appera on the right side of the standard stream insertion operator (like cout << ...).
Two other macros (With* form) declare a stream object which can be used inside a compound statement which follows the macro. the stream is a regular C++ std::ostream
object and can be used to compose more complex messages with conditional expressions or loops.
Here is a simplified example of using MsgLog
macro which makes a message out of several variables and sends it to "MyPackage" logger with debug severity:
#include "MsgLogger/MsgLogger.h" ... MsgLog("MyPackage", debug, "key = " << key << " value = " << value << " count = " << count);
Here is a bit more complex example of using WithMsgLog
macro which makes similar message:
#include "MsgLogger/MsgLogger.h" ... WithMsgLog("MyPackage", debug, out) { if (not key.empty()) out << "key = " << key << ' '; out << " value = " << value << " count = " << count; }
info
severity (meaning that they will accept messages with info
, warning
, error
, or fatal
severities). Non-root loggers do not have any associated handlers, and only the root logger has a single handler that prints message contents to a standard output or standard error depending on message severity. All loggers send their messages to parent loggers and evenually to root logger which results in all messages with info
and higher severity being printed to terminal or log files.Many offline applications (including psana) provide simple way to change severity of the root logger via the command line switches (-v and -q):
trace
debug
warning
error
Currently configuration can be changed by providing simple configuration directives via MSGLOGCONFIG
environment variable. The format of the variable contents is:
format :: directive[; directive]* directive :: level directive :: logger=level[-]
Directive which contains only the level name changes severity level of the root logger:
export MSGLOGCONFIG=debug
Directive which also includes logger name does two things: 1) instantiate new message handler (with debug level) and associate this handler with the specified logger, 2) change logger severity level to the specified level. If the directive has a traling minus sign then the logger is also set to not propagate its messages to the parent logger. Right now only one type of handler exists which will print messages to standard streams.
Here are few examples:
export MSGLOGCONFIG="info; MyPackage=debug"
info
or higher severities because "MyPackage" handler will first send those message to its own handler and then also forward it to the root logger which will send it again to the associated handler. To avoid this duplication one can just disable propagation from "MyPackage" to root logger: export MSGLOGCONFIG="info; MyPackage=debug-"
MSGLOGFMT
environment variable which can contain a number of for formatting directives in the form "%(keyword)". Following keywords are defined:logger
- name of the loggerlevel
- logging level of the message (debug/trace/info/warning/error)LVL
- three-letter level code (DBG/TRC/INF/WRN/ERR)L
- one-letter level code (D/T/I/W/E)message
- the text of the messagepath
- full path of the file where message originatedfile
- base name of the file where message originatedline
- line number where message originatedtime
- timestamp of the messagepid
- process IDExample of the format string could be:
export MSGLOGFMT="%(time) [%(LVL)] {%(logger)} %(file):%(line) - %(message)"
Additionally the format of the time string can be controlled via the MSGLOGTIMEFMT
environment variable which provides strftime-format string with one additional format code "%f" for the number of milliseconds. Here is an example:
export MSGLOGTIMEFMT="%D %T.%f"