/* * 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 */ #include "log.hpp" #include "../cast.hpp" #include "../string.hpp" #include "sink/console.hpp" #include "sink/ostream.hpp" #include #include #include #include /////////////////////////////////////////////////////////////////////////////// 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; } /////////////////////////////////////////////////////////////////////////////// // 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 s_sink_init; static std::unique_ptr s_default_sink; //----------------------------------------------------------------------------- cruft::log::sink::base& cruft::log::default_sink (std::unique_ptr value) { s_default_sink = std::move (value); return *s_default_sink; } //----------------------------------------------------------------------------- cruft::log::sink::base& cruft::log::default_sink () { if (unlikely (!s_sink_init)) { 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 ( PACKAGE_NAME, log_path ) ); } else if (strcmp (log_sink, "CONSOLE")) { default_sink ( std::make_unique (PACKAGE_NAME) ); } else { std::clog << "Unknown logging sink. Falling back to console.\n"; default_sink ( std::make_unique (PACKAGE_NAME) ); } s_sink_init = true; } 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) ); }