log: allow dynamic updates of the global log level
This commit is contained in:
parent
cc4f91f393
commit
256e1c32b3
50
log.cpp
50
log.cpp
@ -54,6 +54,9 @@ ALL_LEVELS[] = {
|
|||||||
static util::level_t
|
static util::level_t
|
||||||
to_level (std::string name)
|
to_level (std::string name)
|
||||||
{
|
{
|
||||||
|
if (std::empty (name))
|
||||||
|
return util::EMERGENCY;
|
||||||
|
|
||||||
static const std::map<std::string, util::level_t> NAME_LEVELS = {
|
static const std::map<std::string, util::level_t> NAME_LEVELS = {
|
||||||
{ "EMERGENCY", util::EMERGENCY },
|
{ "EMERGENCY", util::EMERGENCY },
|
||||||
{ "ALERT", util::ALERT },
|
{ "ALERT", util::ALERT },
|
||||||
@ -106,8 +109,14 @@ util::operator<< (std::ostream& os, util::level_t l)
|
|||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
static util::level_t
|
// Determine what the value for LOG_LEVEL should be at the beginning of
|
||||||
log_level (void)
|
// execution given the system environment.
|
||||||
|
//
|
||||||
|
// Note that the LOG macros _cannot_ be used from within this function as it
|
||||||
|
// will likely result in infinite recursion.
|
||||||
|
static
|
||||||
|
util::level_t
|
||||||
|
initial_log_level (void)
|
||||||
{
|
{
|
||||||
const char *env = getenv ("LOG_LEVEL");
|
const char *env = getenv ("LOG_LEVEL");
|
||||||
if (!env)
|
if (!env)
|
||||||
@ -116,12 +125,42 @@ log_level (void)
|
|||||||
try {
|
try {
|
||||||
return to_level (env);
|
return to_level (env);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
LOG_ERROR("Invalid environment LOG_LEVEL: '%s'", env);
|
std::clog << "Invalid environment LOG_LEVEL: '" << env << "'\n";
|
||||||
return util::DEFAULT_LOG_LEVEL;
|
return util::DEFAULT_LOG_LEVEL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// We shouldn't ever actually get to use the default value, but we set it to
|
||||||
|
// the most verbose option just in case we've made a mistake elsewhere.
|
||||||
|
|
||||||
|
static bool s_log_level_done;
|
||||||
|
static util::level_t s_log_level_value;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
util::level_t
|
||||||
|
util::log_level (level_t _level)
|
||||||
|
{
|
||||||
|
s_log_level_value = _level;
|
||||||
|
s_log_level_done = true;
|
||||||
|
return s_log_level_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
util::level_t
|
||||||
|
util::log_level (void)
|
||||||
|
{
|
||||||
|
if (!s_log_level_done) {
|
||||||
|
s_log_level_value = initial_log_level ();
|
||||||
|
s_log_level_done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return s_log_level_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static bool
|
static bool
|
||||||
needs_break (util::level_t level)
|
needs_break (util::level_t level)
|
||||||
@ -195,8 +234,7 @@ level_width (void)
|
|||||||
void
|
void
|
||||||
util::log (util::level_t level, const std::string &msg)
|
util::log (util::level_t level, const std::string &msg)
|
||||||
{
|
{
|
||||||
static const util::level_t LOG_LEVEL = log_level ();
|
if (level <= log_level ()) {
|
||||||
if (level <= LOG_LEVEL) {
|
|
||||||
static const size_t time_len = strlen("YYYY-mm-dd HHMMhSS") + 1;
|
static const size_t time_len = strlen("YYYY-mm-dd HHMMhSS") + 1;
|
||||||
std::string time_string (time_len - 1, '\0');
|
std::string time_string (time_len - 1, '\0');
|
||||||
time_t unix_time = time (nullptr);
|
time_t unix_time = time (nullptr);
|
||||||
@ -209,7 +247,7 @@ util::log (util::level_t level, const std::string &msg)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << time_string << " ["
|
std::clog << time_string << " ["
|
||||||
<< level_colour (level)
|
<< level_colour (level)
|
||||||
<< std::setw (trunc_cast<int> (level_width ()))
|
<< std::setw (trunc_cast<int> (level_width ()))
|
||||||
<< std::left
|
<< std::left
|
||||||
|
30
log.hpp
30
log.hpp
@ -32,7 +32,6 @@ namespace util {
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// rfc5424 log levels. It is assumed they are contiguous to simplify array
|
// rfc5424 log levels. It is assumed they are contiguous to simplify array
|
||||||
// indexing in logging code.
|
// indexing in logging code.
|
||||||
//
|
|
||||||
enum level_t {
|
enum level_t {
|
||||||
EMERGENCY, /** system is unusable */
|
EMERGENCY, /** system is unusable */
|
||||||
ALERT, /** action must be taken immediately */
|
ALERT, /** action must be taken immediately */
|
||||||
@ -58,14 +57,39 @@ namespace util {
|
|||||||
operator<< (std::ostream&, level_t);
|
operator<< (std::ostream&, level_t);
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Query or set the global logging level filter. If the severity passed to
|
||||||
|
// a logging call is less than this then the output is discarded.
|
||||||
|
//
|
||||||
|
// The initial logging level can be controlled by setting the environment
|
||||||
|
// variable LOG_LEVEL to a string corresponding to the names of the values
|
||||||
|
// in level_t.
|
||||||
|
//
|
||||||
|
// Otherwise we fall back to the hard coded default from above.
|
||||||
|
//
|
||||||
|
// As a special case, a blank value for the environment variable LOG_LEVEL
|
||||||
|
// corresponds to the maximum log level. It indicates a preference for
|
||||||
|
// minimum output, and may be changed to disable all output in future
|
||||||
|
// updates.
|
||||||
|
level_t log_level (void);
|
||||||
|
level_t log_level (level_t);
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
void log (level_t, const std::string &msg);
|
void log (level_t, const std::string &msg);
|
||||||
|
|
||||||
|
|
||||||
template <typename ...Args, size_t N>
|
template <typename ...Args, size_t N>
|
||||||
void log (level_t, const char (&fmt)[N], const Args&...);
|
void
|
||||||
|
log (level_t, const char (&fmt)[N], const Args&...);
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
// Various convenience macros for logging specific strings with a well
|
||||||
|
// known severity.
|
||||||
|
//
|
||||||
|
// LOG_DEBUG is treated similarly to assert; if NDEBUG is defined then we
|
||||||
|
// compile out the statement so as to gain a little runtime efficiency
|
||||||
|
// speed.
|
||||||
#define LOG_EMERGENCY(...) do { util::log(util::EMERGENCY, ##__VA_ARGS__); } while (0)
|
#define LOG_EMERGENCY(...) do { util::log(util::EMERGENCY, ##__VA_ARGS__); } while (0)
|
||||||
#define LOG_ALERT(...) do { util::log(util::ALERT, ##__VA_ARGS__); } while (0)
|
#define LOG_ALERT(...) do { util::log(util::ALERT, ##__VA_ARGS__); } while (0)
|
||||||
#define LOG_CRITICAL(...) do { util::log(util::CRITICAL, ##__VA_ARGS__); } while (0)
|
#define LOG_CRITICAL(...) do { util::log(util::CRITICAL, ##__VA_ARGS__); } while (0)
|
||||||
@ -74,7 +98,7 @@ namespace util {
|
|||||||
#define LOG_WARN(...) do { util::log(util::WARN, ##__VA_ARGS__); } while (0)
|
#define LOG_WARN(...) do { util::log(util::WARN, ##__VA_ARGS__); } while (0)
|
||||||
#define LOG_NOTICE(...) do { util::log(util::NOTICE, ##__VA_ARGS__); } while (0)
|
#define LOG_NOTICE(...) do { util::log(util::NOTICE, ##__VA_ARGS__); } while (0)
|
||||||
#define LOG_INFO(...) do { util::log(util::INFO, ##__VA_ARGS__); } while (0)
|
#define LOG_INFO(...) do { util::log(util::INFO, ##__VA_ARGS__); } while (0)
|
||||||
#if defined(ENABLE_DEBUGGING)
|
#if !defined(NDEBUG)
|
||||||
#define LOG_DEBUG(...) do { util::log(util::DEBUG, ##__VA_ARGS__); } while (0)
|
#define LOG_DEBUG(...) do { util::log(util::DEBUG, ##__VA_ARGS__); } while (0)
|
||||||
#else
|
#else
|
||||||
#define LOG_DEBUG(...) do { ; } while (0)
|
#define LOG_DEBUG(...) do { ; } while (0)
|
||||||
|
Loading…
Reference in New Issue
Block a user