From 8224f2b067ea91dbcdb79c0df49f06f0c6dbc0ac Mon Sep 17 00:00:00 2001 From: Remy Prechelt <prechelt@hawaii.edu> Date: Mon, 20 Jul 2020 13:00:02 -1000 Subject: [PATCH] Added SetLevel, -DDEBUG, and AddSourceInfo. --- CMakeLists.txt | 3 + Framework/Logging/Logging.h | 113 ++++++++++++++++++++++++++++--- Framework/Logging/testLogging.cc | 41 ++++++++--- ThirdParty/spdlog | 2 +- 4 files changed, 138 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b2a52509..7e0d2ca7b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,9 @@ set (CMAKE_SHARED_LINKER_FLAGS_COVERAGE "--coverage") # clang produces a lot of unecessary warnings without this: add_compile_options ("$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:AppleClang>>:-Wno-nonportable-include-path>") +# set a flag to inform code that we are in debug mode +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG") + # COAST - interface, this requires CORSIKA7 to be installed first # COAST will allow you to program code in CORSIKA8 and execute it inside CORSIKA7 if (WITH_COAST) diff --git a/Framework/Logging/Logging.h b/Framework/Logging/Logging.h index a06756e05..21664424d 100644 --- a/Framework/Logging/Logging.h +++ b/Framework/Logging/Logging.h @@ -7,25 +7,63 @@ */ /** - @File Logging.h - - CORSIKA8 logging utilities. + * @File Logging.h + * + * CORSIKA8 logging utilities. + * + * See testLogging.cc for a complete set of examples for + * how the logging functions should be used. */ #pragma once +// Configure some behaviour of sdlog. +// This must be done before spdlog is included. + +// use the coarse system clock. This is *much* faster +// but introduces a real time error of O(10 ms). +#define SPDLOG_CLOCK_COARSE + +// do not create a default logger (we provide our own "corsika" logger) +#define SPDLOG_DISABLE_DEFAULT_LOGGER + +// use __PRETTY_FUNCTION__ instead of __FUNCTION__ where +// printing function names in trace statements. This is much +// nicer than __FUNCTION__ under GCC/clang. +#define SPDLOG_FUNCTION __PRETTY_FUNCTION__ + +// if this is a Debug build, include debug messages in objects +#ifdef DEBUG +// trace is the highest level of logging (ALL messages will be printed) +#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE +#else // otherwise, remove everything but "critical" messages +#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_CRITICAL +#endif + #include <spdlog/spdlog.h> #include "spdlog/sinks/stdout_color_sinks.h" - namespace corsika::logging { // bring spdlog into the corsika::logging namespace using namespace spdlog; + /* + * The default pattern for CORSIKA8 loggers. + */ + const std::string default_pattern{"[%n:%^%-8l%$] %v"}; + /** * Create a new C8-style logger. * + * Use this if you are explicitly (and can guarantee) that you + * are creating a logger for the first time. It is recommended + * that for regular usage, the `GetLogger` function is used instead + * as that will also create the logger if it has not yet been created. + * + * Calling `CreateLogger` twice to create the same logger will + * result in an spdlog duplicate exception. + * * @param name The unique name of the logger. * @param defaultlog If True, set this as the default logger. * @returns The constructed and formatted logger. @@ -33,10 +71,11 @@ namespace corsika::logging { auto CreateLogger(std::string const& name, bool const defaultlog = false) { // create the logger + // this is currently a colorized multi-threading safe logger auto logger = spdlog::stdout_color_mt(name); // set the default C8 format - logger->set_pattern("[%n:%^%-8l%$] %v"); + logger->set_pattern(default_pattern); // if defaultlog is True, we set this as the default spdlog logger. if (defaultlog) { spdlog::set_default_logger(logger); } @@ -48,7 +87,11 @@ namespace corsika::logging { /** * Get a smart pointer to an existing logger. * - * If the logger does not exist, it is created and returned. + * This should be the default method for code to obtain a + * logger. If the logger *does not* exist, it is *created* and + * returned to the caller. + * + * This should be preferred over `CreateLogger`. * * @param name The name of the logger to get. * @param defaultlog If True, make this the default logger. @@ -68,19 +111,66 @@ namespace corsika::logging { } /** - * Set the default log level for all loggers. + * The default "corsika" logger. + */ + inline auto corsika = GetLogger("corsika", true); + + /** + * Set the default log level for all *newly* created loggers. * - * @param name The minimum log level required to print. + * @param name The minimum log level required to print. * */ - auto SetDefaultLevel(level::level_enum minlevel) -> void { + auto SetDefaultLevel(level::level_enum const minlevel) -> void { spdlog::set_level(minlevel); } - // create the default CORSIKA logger - inline auto corsika = GetLogger("corsika", true); + /** + * Set the log level for the "corsika" logger. + * + * @param name The minimum log level required to print. + * + */ + auto SetLevel(level::level_enum const minlevel) -> void { + corsika->set_level(minlevel); + } + + /** + * Set the log level for a specific logger. + * + * @param logger The logger to set the level of. + * @param name The minimum log level required to print. + * + */ + template <typename TLogger> + auto SetLevel(TLogger& logger, level::level_enum const minlevel) -> void { + logger->set_level(minlevel); + } + + /** + * Add the source (filename, line no) info to the logger. + * + * @param logger The logger to set the level of. + * + */ + template <typename TLogger> + auto AddSourceInfo(TLogger& logger) -> void { + logger->set_pattern("[%n:%^%-8l%$(%s:%!:%#)] %v"); + } + + /** + * Reset the logging pattern to the default. + * + * @param logger The logger to set the level of. + * + */ + template <typename TLogger> + auto ResetPattern(TLogger& logger) -> void { + logger->set_pattern(default_pattern); + } // define our macro-style loggers +#define C8LOG_TRACE SPDLOG_TRACE #define C8LOG_DEBUG SPDLOG_DEBUG #define C8LOG_INFO SPDLOG_INFO #define C8LOG_WARN SPDLOG_WARN @@ -88,6 +178,7 @@ namespace corsika::logging { #define C8LOG_CRITICAL SPDLOG_CRITICAL // and the specific logger versions +#define C8LOG_LOGGER_TRACE SPDLOG_LOGGER_TRACE #define C8LOG_LOGGER_DEBUG SPDLOG_LOGGER_DEBUG #define C8LOG_LOGGER_INFO SPDLOG_LOGGER_INFO #define C8LOG_LOGGER_WARN SPDLOG_LOGGER_WARN diff --git a/Framework/Logging/testLogging.cc b/Framework/Logging/testLogging.cc index 2bead9a54..bf9190580 100644 --- a/Framework/Logging/testLogging.cc +++ b/Framework/Logging/testLogging.cc @@ -72,23 +72,46 @@ TEST_CASE("Logging", "[Logging]") { logging::error("This should NOT be printed!"); logging::critical("This SHOULD BE printed!!"); + // get a reference to an unknown logger + auto logger = logging::GetLogger("loggerD"); + + // now set the default log level for this logger + logging::SetLevel(logger, logging::level::critical); + + // now try the various logging functions + logger->info("This should NOT be printed!"); + logger->warn("This should NOT be printed!"); + logger->debug("This should NOT be printed!"); + logger->error("This should NOT be printed!"); + logger->critical("This SHOULD BE printed!!"); + // and reset it for the next tests logging::SetDefaultLevel(logging::level::debug); + logging::SetLevel(logging::level::debug); } - SECTION("test macro style printing") { + SECTION("test macro style logging") { // these print with the "corsika" logger - C8LOG_INFO("This is a macro info msg!"); - C8LOG_DEBUG("This is a macro debug msg!"); - C8LOG_ERROR("This is a macro error msg!"); - C8LOG_CRITICAL("This is a macro critical msg!"); + C8LOG_INFO("test macro style logging"); + C8LOG_DEBUG("test macro style logging"); + C8LOG_ERROR("test macro style logging"); + C8LOG_CRITICAL("test macro style logging"); // get a reference to an unknown logger - auto logger = logging::GetLogger("loggerD"); + auto logger = logging::GetLogger("loggerE"); + + // add the filename, source information to this logger + logging::AddSourceInfo(logger); + + // these print with the "loggerE" logger + C8LOG_LOGGER_INFO(logger, "test macro style logging"); + C8LOG_LOGGER_WARN(logger, "test macro style logging"); + + // reset the logging pattern + logging::ResetPattern(logger); - // these print with the "loggerD" logger - C8LOG_LOGGER_INFO(logger, "This is a macro info msg!"); - C8LOG_LOGGER_WARN(logger, "This is a macro warn msg!"); + // these trace macros should not print file, function, and line + C8LOG_LOGGER_TRACE(logger, "test macro style logging:"); } } diff --git a/ThirdParty/spdlog b/ThirdParty/spdlog index 616caa5d3..58875bdcd 160000 --- a/ThirdParty/spdlog +++ b/ThirdParty/spdlog @@ -1 +1 @@ -Subproject commit 616caa5d30172b65cc3a06800894c575d70cb8e6 +Subproject commit 58875bdcd790dd2f5cb8d95ef1da7970de0a4530 -- GitLab