5.2. Logging#

The Logging system of the Belle II Software is rather flexible and allows extensive configurations. In the most simple case a call to set_log_level is all that is needed to set the minimum severity of messages to be printed. However in addition to this global log level one can set the log level for specific packages and even for individual modules separately. The existing log levels are defined as

class basf2.LogLevel#

Class for all possible log levels

DEBUG#

The lowest possible severity meant for expert only information and disabled by default. In contrast to all other log levels DEBUG messages have an additional numeric indication of their priority called the debug_level to allow for different levels of verbosity.

The agreed values for debug_level are

  • 0-9 for user code. These numbers are reserved for user analysis code and may not be used by any part of basf2.

  • 10-19 for analysis package code. The use case is that a user wants to debug problems in analysis jobs with the help of experts.

  • 20-29 for simulation/reconstruction code.

  • 30-39 for core framework code.

Note

The default maximum debug level which will be shown when running basf2 --debug without any argument for --debug is 10

INFO#

Used for informational messages which are of use for the average user but not very important. Should be used very sparsely, everything which is of no interest to the average user should be a debug message.

RESULT#

Informational message which don’t indicate an error condition but are more important than a mere information. For example the calculated cross section or the output file name.

Deprecated since version release-01-00-00: use INFO messages instead

WARNING#

For messages which indicate something which is not correct but not fatal to the processing. This should not be used to make informational messages more prominent and they should not be ignored by the user but they are not critical.

ERROR#

For messages which indicate a clear error condition which needs to be recovered. If error messages are produced before event processing is started the processing will be aborted. During processing errors don’t lead to a stop of the processing but still indicate a problem.

FATAL#

For errors so severe that no recovery is possible. Emitting a fatal error will always stop the processing and the B2FATAL function is guaranteed to not return.

basf2.set_log_level(level)[source]#

Sets the global log level which specifies up to which level the logging messages will be shown

Parameters:

level (basf2.LogLevel) – minimum severity of messages to be logged

basf2.set_debug_level(level)[source]#

Sets the global debug level which specifies up to which level the debug messages should be shown

Parameters:

level (int) – The debug level. The default value is 100

basf2.logging#

An instance of the LogPythonInterface class for fine grained control over all settings of the logging system.

5.2.1. Creating Log Messages#

Log messages can be created in a very similar way in python and C++. You can call one of the logging functions like B2INFO and supply the message as string, for example

B2INFO("This is a log message of severity INFO")

In Python you can supply multiple arguments which will all be converted to string and concatenated to form the log message

for i in range(1,4):
    B2INFO("This is log message number ", i)

which will produce

[INFO] This is log message number 1
[INFO] This is log message number 2
[INFO] This is log message number 3

This works almost the same way in C++ except that you need the << operator to construct the log message from multiple parts

for(int i=1; i<4; ++i) {
  B2INFO("This is log message " << i << " in C++");
}

Log Variables

Added in version release-03-00-00.

However, the log system has an additional feature to include variable parts in a fixed message to simplify grouping of similar log messages: If a log message only differs by a number or detector name it is very hard to filter repeating messages. So we have log message variables which can be used to specify varying parts while having a fixed message.

In Python these can just be given as keyword arguments to the logging functions

B2INFO("This is a log message", number=3.14, text="some text")

In C++ this again almost works the same way but we need to specify the variables a bit more explicitly.

B2INFO("This is a log message" << LogVar("number", 3.14) << LogVar("text", "some text"));

In both cases the names of the variables can be chosen feely and the output should be something like

[INFO] This is a log message
        number = 3.14
        text = some text

Logging functions

To emit log messages from within Python we have these functions:

basf2.B2DEBUG(debugLevel, message, *args, **kwargs)#

Print a DEBUG message. The first argument is the debug_level. All additional positional arguments are converted to strings and concatenated to the log message. All keyword arguments are added to the function as Log Variables.

basf2.B2INFO(message, *args, **kwargs)#

Print a INFO message. All additional positional arguments are converted to strings and concatenated to the log message. All keyword arguments are added to the function as Log Variables.

basf2.B2RESULT(message, *args, **kwargs)#

Print a RESULT message. All additional positional arguments are converted to strings and concatenated to the log message. All keyword arguments are added to the function as Log Variables.

Deprecated since version release-01-00-00: use B2INFO() instead

basf2.B2WARNING(message, *args, **kwargs)#

Print a WARNING message. All additional positional arguments are converted to strings and concatenated to the log message. All keyword arguments are added to the function as Log Variables.

basf2.B2ERROR(message, *args, **kwargs)#

Print a ERROR message. All additional positional arguments are converted to strings and concatenated to the log message. All keyword arguments are added to the function as Log Variables.

basf2.B2FATAL(message, *args, **kwargs)#

Print a FATAL message. All additional positional arguments are converted to strings and concatenated to the log message. All keyword arguments are added to the function as Log Variables.

Note

This also exits the program with an error and is guaranteed to not return.

The same functions are available in C++ as macros once you included <framework/logging/Logger.h>

5.2.2. The Logging Configuration Objects#

The logging object provides a more fine grained control over the settings of the logging system and should be used if more than just a global log level should be changed

class basf2.LogPythonInterface#

Logging configuration (for messages generated from C++ or Python), available as a global basf2.logging object in Python. See also basf2.set_log_level() and basf2.set_debug_level().

This class exposes a object called logging to the python interface. With this object it is possible to set all properties of the logging system directly in the steering file in a consistent manner This class also exposes the LogConfig class as well as the LogLevel and LogInfo enums to make setting of properties more transparent by using the names and not just the values. To set or get the log level, one can simply do:

>>> logging.log_level = LogLevel.FATAL
>>> print("Logging level set to", logging.log_level)
FATAL

This module also allows to send log messages directly from python to ease consistent error reporting throughout the framework

>>> B2WARNING("This is a warning message")

See also

For all features, see b2logging.py

property abort_level#

Attribute for setting/getting the log level at which to abort processing. Defaults to FATAL but can be set to a lower level in rare cases.

add_console([(bool)enable_color]) None :#

Write log output to console. (In addition to existing outputs). If enable_color is not specified color will be enabled if supported

add_file((str)filename[, (bool)append=False]) None :#

Write log output to given file. (In addition to existing outputs)nn”

Parameters:
  • filename (str) – Filename to to write log messages into

  • append (bool) – If set to True the file will be truncated before writing new messages.

add_json([(bool)complete_info=False]) None :#

Write log output to console, but format log messages as json objects for simplified parsing by other tools. Each log message will be printed as a one line JSON object.

Added in version release-03-00-00.

Parameters:

complete_info (bool) – If this is set to True the complete log information is printed regardless of the LogInfo setting.

add_udp((str)hostname, (int)port) None :#

Send the log output as a JSON object to the given hostname and port via UDP.

Added in version release-04-00-00.

Parameters:
  • hostname (str) – The hostname to send the message to. If it can not be resolved, an exception will be thrown.

  • port (int) – The port on the host to send the message via UDP.

See also

add_json()

property debug_level#

Attribute for getting/setting the debug level. If debug messages are enabled, their level needs to be at least this high to be printed. Defaults to 100.

property enable_escape_newlines#

Enable or disable escaping of newlines in log messages to the console. If this is set to true than any newline character in log messages printed to the console will be replaced by a “n” to ensure that every log messages fits exactly on one line.

Added in version release-04-02-00.

property enable_python_logging#

Enable or disable logging via python. If this is set to true than log messages will be sent via sys.stdout. This is probably slightly slower but is useful when running in jupyter notebooks or when trying to redirect stdout in python to a buffer. This setting affects all log connections to the console.

Added in version release-03-00-00.

enable_summary((bool)on) None :#

Enable or disable the error summary printed at the end of processing. Expects one argument whether or not the summary should be shown

get_info((LogLevel)log_level) int :#

Get info to print for given log level.

Parameters:

log_level (basf2.LogLevel) – Log level for which to get the display info

property log_level#

Attribute for setting/getting the current log level. Messages with a lower level are ignored.

property log_stats#

Returns dictionary with message counters.

property max_repetitions#

Set the maximum amount of times log messages with the same level and message text (excluding variables) will be repeated before it is suppressed. Suppressed messages will still be counted but not shown for the remainder of the processing.

This affects messages with the same text but different ref:Log Variables. If the same log message is repeated frequently with different variables all of these will be suppressed after the given amount of repetitions.

Added in version release-05-00-00.

package((str)package) LogConfig :#

Get the LogConfig for given package to set detailed logging pararameters for this package.

>>> logging.package('svd').debug_level = 10
>>> logging.package('svd').set_info(LogLevel.INFO, LogInfo.LEVEL | LogInfo.MESSAGE | LogInfo.FILE)
reset() None :#

Remove all configured logging outputs. You can then configure your own via add_file() or add_console()

set_info((LogLevel)log_level, (int)log_info) None :#

Set info to print for given log level. Should be an OR combination of basf2.LogInfo constants. As an example, to show only the level and text for all debug messages one could use

>>> basf2.logging.set_info(basf2.LogLevel.DEBUG, basf2.LogInfo.LEVEL | basf2.LogInfo.MESSAGE)
Parameters:
  • log_level (LogLevel) – log level for which to set the display info

  • log_info (int) – Bitmask of basf2.LogInfo constants.

set_package((str)package, (LogConfig)config) None :#

Set basf2.LogConfig for given package, see also package().

static terminal_supports_colors() bool :#

Returns true if the terminal supports colored output

zero_counters() None :#

Reset the per-level message counters.

class basf2.LogConfig#

Defines logging settings (log levels and items included in each message) for a certain context, e.g. a module or package.

property abort_level#

set or get the severity which causes program abort

property debug_level#

set or get the current debug level

get_info((LogLevel)log_level) int :#

get the current bitmask of which parts of the log message will be printed for a given log level

property log_level#

set or get the current log level

set_abort_level((LogLevel)abort_level) None :#

Set the severity which causes program abort.

This can be set to a LogLevel which will cause the processing to be aborted if a message with the given level or higher is encountered. The default is FATAL. It cannot be set any higher but can be lowered.

set_debug_level((int)debug_level) None :#

Set the maximum debug level to be shown. Any messages with log level DEBUG and a larger debug level will not be shown.

set_info((LogLevel)log_level, (int)log_info) None :#

set the bitmask of LogInfo members to show when printing messages for a given log level

set_log_level((LogLevel)log_level) None :#

Set the minimum log level to be shown. Messages with a log level below this value will not be shown at all.

class basf2.LogInfo#

The different fields of a log message.

These fields can be used as a bitmask to configure the appearance of log messages.

LEVEL#

The severity of the log message, one of basf2.LogLevel

MESSAGE#

The actual log message

MODULE#

The name of the module active when the message was emitted. Can be empty if no module was active (before/after processing or outside of the normal event loop)

PACKAGE#

The package the code that emitted the message belongs to. This is empty for messages emitted by python scripts

FUNCTION#

The function name that emitted the message

FILE#

The filename containing the code emitting the message

LINE#

The line number in the file emitting the message