1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
//----------------------------------*-C++-*----------------------------------//
// Copyright 2020-2023 UT-Battelle, LLC, and other Celeritas developers.
// See the top-level COPYRIGHT file for details.
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
//---------------------------------------------------------------------------//
//! \file Logger.cpp
//---------------------------------------------------------------------------//
#include "VecGeom/management/Logger.h"
#include <algorithm>
#include <functional>
#include <iostream>
#include <cassert>
#include <mutex>
#include <sstream>
#include <string>
#include "VecGeom/management/LoggerTypes.h"
#include "VecGeom/management/Environment.h"
#include "VecGeom/management/ColorUtils.h"
namespace vecgeom {
namespace {
//---------------------------------------------------------------------------//
// HELPER CLASSES
//---------------------------------------------------------------------------//
//! Default global logger prints the error message with basic colors
void default_global_handler(Provenance prov, LogLevel lev, std::string msg)
{
static std::mutex log_mutex;
std::lock_guard<std::mutex> scoped_lock{log_mutex};
if (lev == LogLevel::debug || lev >= LogLevel::warning) {
// Output problem line/file for debugging or high level
std::clog << color_code('x') << prov.file;
if (prov.line) std::clog << ':' << prov.line;
std::clog << color_code(' ') << ": ";
}
// clang-format off
char c = ' ';
switch (lev)
{
case LogLevel::debug: c = 'x'; break;
case LogLevel::diagnostic: c = 'x'; break;
case LogLevel::status: c = 'b'; break;
case LogLevel::info: c = 'g'; break;
case LogLevel::warning: c = 'y'; break;
case LogLevel::error: c = 'r'; break;
case LogLevel::critical: c = 'R'; break;
case LogLevel::size_: assert(false);
};
// clang-format on
std::clog << color_code(c) << to_cstring(lev) << ": " << color_code(' ') << msg << std::endl;
}
//---------------------------------------------------------------------------//
/*!
* Set the log level from an environment variable, warn on failure.
*/
void set_log_level_from_env(Logger *log, std::string const &level_env)
{
assert(log);
try {
log->level(log_level_from_env(level_env));
} catch (std::runtime_error const &e) {
(*log)(VECGEOM_CODE_PROVENANCE, LogLevel::warning) << e.what();
}
}
//---------------------------------------------------------------------------//
} // namespace
//---------------------------------------------------------------------------//
/*!
* Construct with log handler.
*/
Logger::Logger(LogHandler handle) : handle_{std::move(handle)} {}
//---------------------------------------------------------------------------//
// FREE FUNCTIONS
//---------------------------------------------------------------------------//
/*!
* Get the log level from an environment variable.
*/
LogLevel log_level_from_env(std::string const &level_env)
{
// Search for the provided environment variable to set the default
// logging level using the `to_cstring` function in LoggerTypes.
std::string const &env_value = vecgeom::getenv(level_env);
if (env_value.empty()) {
return Logger::default_level();
}
for (int i = 0; i < static_cast<int>(LogLevel::size_); ++i) {
if (env_value == to_cstring(static_cast<LogLevel>(i))) {
return static_cast<LogLevel>(i);
}
}
throw std::runtime_error("invalid log level in environment variable");
}
//---------------------------------------------------------------------------//
/*!
* Create a default logger using the world communicator.
*
* This function can be useful when resetting a test harness.
*/
Logger make_default_logger()
{
Logger log{&default_global_handler};
set_log_level_from_env(&log, "VECGEOM_LOG");
return log;
}
//---------------------------------------------------------------------------//
/*!
* Parallel-enabled logger: print only on "main" process.
*
* Setting the "VECGEOM_LOG" environment variable to "debug", "info", "error",
* etc. will change the default log level.
*/
Logger &logger()
{
static Logger logger = make_default_logger();
return logger;
}
//---------------------------------------------------------------------------//
} // namespace vecgeom
|