2012-04-24 17:38:35 +10:00
|
|
|
/*
|
2018-08-04 15:14:06 +10:00
|
|
|
* 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/.
|
2012-04-24 17:38:35 +10:00
|
|
|
*
|
2016-01-20 15:37:52 +11:00
|
|
|
* Copyright 2012-2016 Danny Robson <danny@nerdcruft.net>
|
2012-04-24 17:38:35 +10:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "log.hpp"
|
|
|
|
|
2019-10-10 15:10:41 +11:00
|
|
|
#include "../cast.hpp"
|
|
|
|
#include "../string.hpp"
|
2012-04-24 17:38:35 +10:00
|
|
|
|
2019-10-10 15:52:37 +11:00
|
|
|
#include "sink/console.hpp"
|
2020-04-21 10:56:04 +10:00
|
|
|
#include "sink/ostream.hpp"
|
2019-10-10 15:52:37 +11:00
|
|
|
|
2020-04-21 10:56:04 +10:00
|
|
|
#include <iostream>
|
2019-10-10 16:02:10 +11:00
|
|
|
#include <mutex>
|
2012-04-26 18:22:05 +10:00
|
|
|
#include <map>
|
|
|
|
#include <string>
|
2016-03-21 14:21:14 +11:00
|
|
|
|
2012-04-24 17:38:35 +10:00
|
|
|
|
2015-07-23 17:37:02 +10:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2019-10-10 15:52:37 +11:00
|
|
|
bool
|
|
|
|
cruft::log::needs_break (level_t level)
|
2016-01-20 15:36:32 +11:00
|
|
|
{
|
2019-10-10 15:52:37 +11:00
|
|
|
static level_t break_level;
|
2017-01-31 20:30:38 +11:00
|
|
|
|
2016-01-21 13:55:23 +11:00
|
|
|
static bool has_level = [&] (void) {
|
|
|
|
const char *env = getenv ("BREAK_LEVEL");
|
|
|
|
if (!env)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
try {
|
2019-10-10 15:10:41 +11:00
|
|
|
break_level = cruft::log::to_level (env);
|
2016-01-21 13:55:23 +11:00
|
|
|
return true;
|
|
|
|
} catch (...) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} ();
|
|
|
|
|
|
|
|
return has_level && level <= break_level;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-10-10 15:52:37 +11:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2019-10-21 12:46:43 +11:00
|
|
|
// mingw#xxx: MinGW doesn't have once_flag so we just use an atomic bool.
|
|
|
|
// Pray that multiple threads don't run into an issue here.
|
|
|
|
static std::atomic<bool> s_sink_init;
|
2019-10-10 16:02:10 +11:00
|
|
|
static 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2019-10-10 15:52:37 +11:00
|
|
|
cruft::log::sink::base&
|
|
|
|
cruft::log::default_sink ()
|
2016-03-21 14:21:14 +11:00
|
|
|
{
|
2019-10-21 12:46:43 +11:00
|
|
|
if (unlikely (!s_sink_init)) {
|
2020-04-21 10:56:04 +10:00
|
|
|
static char const *DEFAULT_SINK = "CONSOLE";
|
|
|
|
char const *log_sink = getenv ("CRUFT_LOG_SINK") ?: DEFAULT_SINK;
|
|
|
|
|
|
|
|
if (!strcmp (log_sink, "FILE")) {
|
|
|
|
char const *log_path = getenv ("CRUFT_LOG_PATH");
|
|
|
|
default_sink (
|
|
|
|
std::make_unique<sink::ostream> (
|
|
|
|
PACKAGE_NAME,
|
|
|
|
log_path
|
|
|
|
)
|
|
|
|
);
|
|
|
|
} 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)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-10-21 12:46:43 +11:00
|
|
|
s_sink_init = true;
|
|
|
|
}
|
2019-10-10 16:02:10 +11:00
|
|
|
|
|
|
|
return *s_default_sink;
|
2016-03-21 14:21:14 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-07-23 17:37:02 +10:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
void
|
2019-10-10 12:32:03 +11:00
|
|
|
cruft::log::write (level_t level, const std::string &msg)
|
2019-10-10 15:10:41 +11:00
|
|
|
{
|
|
|
|
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)
|
2016-01-20 15:36:32 +11:00
|
|
|
{
|
2019-10-10 15:52:37 +11:00
|
|
|
return default_sink ().write (
|
|
|
|
packet (level, msg)
|
2019-10-10 12:32:03 +11:00
|
|
|
);
|
2015-07-23 17:37:43 +10:00
|
|
|
}
|