libcruft-util/log/log.cpp
Danny Robson 8bfb1e3d92 log: make once_flag constinit
This ensures we'll error out at compile time rather than encounter a
static initialisation ordering error.
2020-08-03 11:48:48 +10:00

107 lines
2.7 KiB
C++

/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 2012-2016 Danny Robson <danny@nerdcruft.net>
*/
#include "log.hpp"
#include "../cast.hpp"
#include "../string.hpp"
#include "sink/console.hpp"
#include "sink/path.hpp"
#include <iostream>
#include <mutex>
#include <map>
#include <string>
///////////////////////////////////////////////////////////////////////////////
bool
cruft::log::needs_break (level_t level)
{
static level_t break_level;
static bool has_level = [&] (void) {
const char *env = getenv ("BREAK_LEVEL");
if (!env)
return false;
try {
break_level = cruft::log::to_level (env);
return true;
} catch (...) {
return false;
}
} ();
return has_level && level <= break_level;
}
///////////////////////////////////////////////////////////////////////////////
static constinit std::once_flag s_sink_init;
static constinit std::unique_ptr<cruft::log::sink::base> s_default_sink;
//-----------------------------------------------------------------------------
cruft::log::sink::base&
cruft::log::default_sink (std::unique_ptr<sink::base> value)
{
s_default_sink = std::move (value);
return *s_default_sink;
}
//-----------------------------------------------------------------------------
cruft::log::sink::base&
cruft::log::default_sink ()
{
std::call_once (s_sink_init, [&] () {
static char const *DEFAULT_SINK = "CONSOLE";
char const *log_sink = getenv ("CRUFT_LOG_SINK") ?: DEFAULT_SINK;
if (!strcmp (log_sink, "PATH")) {
default_sink (std::make_unique<sink::path> (PACKAGE_NAME));
} else if (!strcmp (log_sink, "CONSOLE")) {
default_sink (std::make_unique<sink::console> (PACKAGE_NAME));
} else {
std::clog << "Unknown logging sink. Falling back to console.\n";
default_sink (std::make_unique<sink::console> (PACKAGE_NAME));
}
});
return *s_default_sink;
}
///////////////////////////////////////////////////////////////////////////////
void
cruft::log::write (level_t level, const std::string &msg)
{
return write (level, std::string_view (msg));
}
//-----------------------------------------------------------------------------
void
cruft::log::write (level_t level, char const *msg)
{
return write (level, std::string_view (msg));
}
//-----------------------------------------------------------------------------
void
cruft::log::write (level_t level, std::string_view msg)
{
return default_sink ().write (
packet (level, msg)
);
}