Back to home page

EIC code displayed by LXR

 
 

    


Warning, /acts/docs/core/misc/logging.md is written in an unsupported language. File is not indexed.

0001 # Logging
0002 
0003 The ACTS logging facility supports several severity levels which allow you to
0004 control the amount of information displayed at run-time. Logger objects can
0005 easily be created using the {func}`Acts::getDefaultLogger` function which
0006 should be sufficient to get you started. In case you need more customized debug
0007 output, you can make use of the output decorators defined in
0008 `Acts::Logging` or even write your own implementation of
0009 {class}`Acts::Logging::OutputDecorator`. In order to add debug messages to your
0010 program, you should use the provided macros for the different severity levels:
0011 
0012 ```cpp
0013 ACTS_VERBOSE(...);
0014 ACTS_DEBUG(...);
0015 ACTS_INFO(...);
0016 ACTS_WARNING(...);
0017 ACTS_ERROR(...);
0018 ACTS_FATAL(...);
0019 ```
0020 
0021 These macros correspond to the available log levels:
0022 
0023 :::{doxygenenum} Acts::Logging::Level
0024 :outline:
0025 :::
0026 
0027 
0028 The macros require that a function `logger` returning a {class}`Acts::Logger`
0029 object is available in the scope in which the macros are used:
0030 
0031 ```cpp
0032 const Logger& logger() const;
0033 ```
0034 
0035 Inside classes
0036 containing an {class}`Acts::Logger` object as member variable, this could be
0037 achieved by providing a private class method called `logger()` (for an example
0038 see e.g.  {func}`Acts::CylinderVolumeBuilder::logger`). Inside free functions
0039 or member methods with local logger objects, the macros are also usable, since
0040 {class}`Acts::Logger` is callable and returns a reference to itself.
0041 
0042 Code example illustrating the usage:
0043 
0044 :::{doxygenfunction} Acts::getDefaultLogger
0045 :::
0046 
0047 ```cpp
0048 #include <fstream>
0049 #include <memory>
0050 
0051 #include "Acts/Utilities/Logger.hpp"
0052 
0053 void myFunction() {
0054   // open the logfile
0055   std::ofstream logfile("log.txt");
0056   // set up a logger instance for >= INFO messages, streaming into the log file
0057   std::unique_ptr<const Acts::Logger> logger
0058       = Acts::getDefaultLogger("MyLogger", Acts::Logging::INFO, &logfile);
0059   // make sure the ACTS debug macros can work with your logger
0060   ACTS_VERBOSE("This message will not appear in the logfile.");
0061   ACTS_INFO("But this one will: Hello World!");
0062   // do not forget to close the logfile
0063   logfile.close();
0064 }
0065 ```
0066 
0067 ## Logger integration
0068 
0069 In case you are using ACTS in another framework which comes with its own
0070 logging facility (e.g. Gaudi) you can pipe the logging output from ACTS
0071 tools and algorithms to your framework's logging system by supplying different
0072 implementations of:
0073 
0074 - {class}`Acts::Logging::OutputFilterPolicy` (for mapping logging levels)
0075 - {class}`Acts::Logging::OutputPrintPolicy` (for passing the Acts output
0076   to your internal logging system)
0077 
0078 There are two approaches to logger integration:
0079 
0080 1. [](override_deflog).
0081    This has the downside that log levels cannot be controlled from top-level
0082    experiment specific code. This means that it is non-trivial to steer the log
0083    level of an e.g. Gaudi algorithm via the `OutputLevel` property, and have
0084    the ACTS code respect this log level. It is therefore now **discouraged** to
0085    use this approach.
0086 
0087     :::{note}
0088     ACTS code has iteratively moved to not construct loggers via
0089     {func}`Acts::getDefaultLogger` as much as possible, in favor of using a
0090     const-reference to {class}`Acts::Logger`. The latter can be defaulted to a
0091     dummy logger using {func}`Acts::getDummyLogger`. It is more suitable to
0092     pass into functions that might be called from other ACTS functions (rather
0093     than construction a local logger via `getDefaultLogger`, or creating logger
0094     instances on the fly).
0095     :::
0096 
0097 2. Passing logger instances to high level components, and rely on ACTS code to
0098    pass them into lower level classes / functions.
0099 
0100 
0101 (override_deflog)=
0102 ### Overriding `Acts::getDefaultLogger`
0103 
0104 :::{attention}
0105 Using this mechanism is now **discouraged** for integration with an experiment
0106 framework.
0107 :::
0108 
0109 Since ACTS makes extensive use of {func}`Acts::getDefaultLogger` to provide
0110 sufficient information for debugging, you might want to provide a modified
0111 implementation of this function (using your output filter and printing
0112 policies) to also pipe this output to your framework. You can use the following
0113 approach using the possibility to inject custom code by preloading shared
0114 libraries with `LD_PRELOAD`. You need to provide an appropriate implementation
0115 for a function of the following signature into a separate source file and
0116 compile it in a shared library
0117 
0118 
0119 ```cpp
0120 namespace Acts {
0121 std::unique_ptr<const Logger> getDefaultLogger(const std::string&,
0122                                                const Logging::Level&,
0123                                                std::ostream*);
0124 }
0125 ```
0126 
0127 Then you can run your executable, which uses ACTS tools and algorithms, in
0128 the following way (tested under Unix)
0129 
0130 ```console
0131 $ LD_PRELOAD=<YOUR_SHARED_LIBRARY> path/to/your/executable
0132 ```
0133 
0134 ## Logging thresholds
0135 
0136 Generally, log levels in ACTS are only of informative value: even
0137 {enumerator}`Acts::Logging::Level::ERROR` and {enumerator}`Acts::Logging::Level::FATAL` will only print a
0138 messages, **and not terminate execution**.
0139 
0140 This is desirable in an experiment context, where jobs should not immediately
0141 terminate when ACTS encounters something that is logged as an error.  In a test
0142 context, however, this behavior is not optimal: the tests should ensure in
0143 known configurations errors do not occur, or only in specific circumstances. To
0144 solve this, ACTS implements an optional log *threshold* mechanism.
0145 
0146 The threshold mechanism is steered via two CMake options:
0147 `ACTS_ENABLE_LOG_FAILURE_THRESHOLD` and `ACTS_LOG_FAILURE_THRESHOLD`. Depending
0148 on their configuration, the logging can operate in three modes:
0149 
0150 1. **No log failure threshold** exists, log levels are informative only. This is
0151    the default behavior.
0152 2. A **compile-time log failure threshold** is set. If
0153    `ACTS_ENABLE_LOG_FAILURE_THRESHOLD=ON` and
0154    `ACTS_LOG_FAILURE_THRESHOLD=<LEVEL>` are set, the logger code will compile
0155    in a fixed check if the log level of a particular message exceeds `<LEVEL>`.
0156    If that is the case, an exception of type {class}`Acts::Logging::ThresholdFailure` is
0157    thrown.
0158 3. A **runtime log failure threshold** is set. If only
0159    `ACTS_ENABLE_LOG_FAILURE_THRESHOLD=ON` and no fixed threshold level is set,
0160    the logger code will compile in a check of a global runtime threshold
0161    variable.
0162 
0163 :::{note}
0164 If only `ACTS_LOG_FAILURE_THRESHOLD` is set,
0165 `ACTS_ENABLE_LOG_FAILURE_THRESHOLD` will be set automatically, i.e. a
0166 compile-time threshold will be set
0167 :::
0168 
0169 Two functions exist to interact with the failure threshold:
0170 
0171 :::{doxygenfunction} Acts::Logging::getFailureThreshold
0172 :::
0173 
0174 :::{doxygenfunction} Acts::Logging::setFailureThreshold
0175 :::