|
|
|
|
|
# Logging Guidelines
|
|
|
|
|
|
CORSIKA provides a logging interface built around [spdlog](https://github.com/gabime/spdlog) which uses the [fmt](https://fmt.dev/latest/index.html)
|
|
|
library for easy string formatting similar to Python f-strings.
|
|
|
|
|
|
There are two different styles for logging: a runtime-removable interface
|
|
|
(`logging::info("Message")` or `logger->info("Message")`) and a
|
|
|
compile-time-removable interface built around C macros
|
|
|
(`CORSIKA_LOG_INFO("message")` or `CORSIKA_LOGGER_INFO(logger, "message")`). The
|
|
|
advantage of the macro-based logging API is that it can be completely removed at
|
|
|
compile-time for improved performance when for heavy logging uses.
|
|
|
|
|
|
By default, logging calls without a specific logger (i.e `logging::warn("A
|
|
|
warning message!")`) will use the global `corsika` logger; in general, this
|
|
|
should only be used by core CORSIKA framework and not by any physics processes.
|
|
|
For example, all of the below examples with use the global `corsika` logger.
|
|
|
|
|
|
logging::info("Welcome to the CORSIKA8 logging!");
|
|
|
logging::error("Some error message with arg: {}", 1);
|
|
|
|
|
|
logging::warn("Easy padding in numbers like {:08d}", 12);
|
|
|
logging::critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
|
|
|
logging::info("Support for floats {:03.2f}", 1.23456);
|
|
|
logging::info("Positional args are {1} {0}..", "too", "supported");
|
|
|
logging::info("{:<30}", "left aligned");
|
|
|
|
|
|
// you can change the log level at runtime to filter messages from individual loggers.
|
|
|
logging::set_level(logging::level::debug); // Set global log level to debug
|
|
|
CORSIKA_LOG_DEBUG("This message should be displayed.."); // these macro messages will be removed at compile-time
|
|
|
CORSIKA_LOG_TRACE("This message should be displayed.."); // this will also be removed
|
|
|
|
|
|
Further examples of how to format log messages can be found [here](https://github.com/gabime/spdlog#usage-samples), and [here](https://github.com/gabime/spdlog/blob/master/example/example.cpp).
|
|
|
|
|
|
All processes should create their own logger with the `get_logger("name")`
|
|
|
function in the `corsika/framework/logging/Logging.hpp` header file where `name`
|
|
|
is the ****lowercase name**** of this process. `get_logger` returns a smart pointer
|
|
|
to the logger and this should be stored in the process for fast access i.e.
|
|
|
|
|
|
auto logger{get_logger("process_name")};
|
|
|
|
|
|
Unlike the examples above that are free functions, you should use methods of
|
|
|
this instance to log messages. For example,
|
|
|
|
|
|
logger->error("This is an error message using my custom process logger!");
|
|
|
logger->info("Binary example: {}", spdlog::to_hex(buf));
|
|
|
logger->warn("Another binary example:{:n}", spdlog::to_hex(std::begin(buf), std::begin(buf) + 10));
|
|
|
CORSIKA_LOGGER_DEBUG(logger, "A compile-time removable log message!"); // note: CORSIKA_LOGG*ER* not CORSIKA_LOG
|
|
|
|
|
|
|
|
|
## Level Guides (or how to choose the right logging level)
|
|
|
|
|
|
The following log levels are provided (in the order defined by `spdlog`):
|
|
|
`trace`, `debug`, `info`, `warn`, `error`, and `critical`. The following
|
|
|
guidelines determine how to choose the appropriate log level for a given message:
|
|
|
|
|
|
- For messages that at most once or twice per event and contain information that
|
|
|
is not essential to the user (e.g. initialization, start parameters, some
|
|
|
statistics), use `logging::info("message")` or `logger->info("message")`.
|
|
|
- While we endeavour to have no warnings in C8, if there is a warning state
|
|
|
(i.e. if a user entered a parameter that is outside a suitable or sane range)
|
|
|
that only occurs once or twice per event, use `logging::warn("message")` or
|
|
|
`logger->warn("message")`.
|
|
|
- For ****recoverable**** error states where something has gone wrong but the
|
|
|
simulation can continue, (i.e. this shower must be stopped but other showers
|
|
|
can continue, or a specific particle must be killed abnormally), use
|
|
|
`logging::error("message")` or `logger->error("message")`.
|
|
|
- For ****unrecoverable**** errors where the only correct thing to do is to
|
|
|
immediately quit CORSIKA, use `logging::critical("message")` or
|
|
|
`logger->critical("message")`. A `critical` error message should always be
|
|
|
followed by an exception to terminate the simulation.
|
|
|
- For messages that occur several times per event (but not several times for
|
|
|
every particle) and contain detailed information, use
|
|
|
`CORSIKA_LOG_DEBUG("message")` or `CORSIKA_LOGGER_DEBUG(logger, "message")`.
|
|
|
These messages are removed during `Release` builds.
|
|
|
- For messages that occur for every particle or many times per event, use
|
|
|
`CORSIKA_LOG_TRACE("message")` or `CORSIKA_LOGGER_TRACE(logger, "message")`.
|
|
|
These are removed during `Release` builds.
|
|
|
|