mirror of
https://github.com/gabime/spdlog.git
synced 2025-09-29 01:29:35 +08:00
@@ -1,99 +0,0 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#include "spdlog/cfg/helpers.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "spdlog/details/registry.h"
|
||||
|
||||
namespace spdlog {
|
||||
namespace cfg {
|
||||
namespace helpers {
|
||||
|
||||
// inplace convert to lowercase
|
||||
inline std::string &to_lower_(std::string &str) {
|
||||
std::transform(str.begin(), str.end(), str.begin(),
|
||||
[](char ch) { return static_cast<char>((ch >= 'A' && ch <= 'Z') ? ch + ('a' - 'A') : ch); });
|
||||
return str;
|
||||
}
|
||||
|
||||
// inplace trim spaces
|
||||
inline std::string &trim_(std::string &str) {
|
||||
const char *spaces = " \n\r\t";
|
||||
str.erase(str.find_last_not_of(spaces) + 1);
|
||||
str.erase(0, str.find_first_not_of(spaces));
|
||||
return str;
|
||||
}
|
||||
|
||||
// return (name,value) trimmed pair from given "name=value" string.
|
||||
// return empty string on missing parts
|
||||
// "key=val" => ("key", "val")
|
||||
// " key = val " => ("key", "val")
|
||||
// "key=" => ("key", "")
|
||||
// "val" => ("", "val")
|
||||
|
||||
inline std::pair<std::string, std::string> extract_kv_(char sep, const std::string &str) {
|
||||
auto n = str.find(sep);
|
||||
std::string k, v;
|
||||
if (n == std::string::npos) {
|
||||
v = str;
|
||||
} else {
|
||||
k = str.substr(0, n);
|
||||
v = str.substr(n + 1);
|
||||
}
|
||||
return std::make_pair(trim_(k), trim_(v));
|
||||
}
|
||||
|
||||
// return vector of key/value pairs from sequence of "K1=V1,K2=V2,.."
|
||||
// "a=AAA,b=BBB,c=CCC,.." => {("a","AAA"),("b","BBB"),("c", "CCC"),...}
|
||||
inline std::unordered_map<std::string, std::string> extract_key_vals_(const std::string &str) {
|
||||
std::string token;
|
||||
std::istringstream token_stream(str);
|
||||
std::unordered_map<std::string, std::string> rv{};
|
||||
while (std::getline(token_stream, token, ',')) {
|
||||
if (token.empty()) {
|
||||
continue;
|
||||
}
|
||||
auto kv = extract_kv_('=', token);
|
||||
rv[kv.first] = kv.second;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
void load_levels(const std::string &input) {
|
||||
if (input.empty() || input.size() > 512) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto key_vals = extract_key_vals_(input);
|
||||
std::unordered_map<std::string, level> levels;
|
||||
level global_level = level::info;
|
||||
bool global_level_found = false;
|
||||
|
||||
for (auto &name_level : key_vals) {
|
||||
const auto &logger_name = name_level.first;
|
||||
auto level_name = to_lower_(name_level.second);
|
||||
auto level = level_from_str(level_name);
|
||||
// ignore unrecognized level names
|
||||
if (level == level::off && level_name != "off") {
|
||||
continue;
|
||||
}
|
||||
if (logger_name.empty()) // no logger name indicate global level
|
||||
{
|
||||
global_level_found = true;
|
||||
global_level = level;
|
||||
} else {
|
||||
levels[logger_name] = level;
|
||||
}
|
||||
}
|
||||
|
||||
details::registry::instance().set_levels(std::move(levels), global_level_found ? &global_level : nullptr);
|
||||
}
|
||||
|
||||
} // namespace helpers
|
||||
} // namespace cfg
|
||||
} // namespace spdlog
|
49
src/details/context.cpp
Normal file
49
src/details/context.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#include "spdlog/details/context.h"
|
||||
|
||||
#include "spdlog/logger.h"
|
||||
|
||||
#ifndef SPDLOG_DISABLE_GLOBAL_LOGGER
|
||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||
#endif // SPDLOG_DISABLE_GLOBAL_LOGGER
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
|
||||
context::context(std::unique_ptr<logger> global_logger) { global_logger_ = std::move(global_logger); }
|
||||
|
||||
std::shared_ptr<logger> context::global_logger() { return global_logger_; }
|
||||
|
||||
// Return raw ptr to the global logger.
|
||||
// To be used directly by the spdlog default api (e.g. spdlog::info)
|
||||
// This make the default API faster, but cannot be used concurrently with set_global_logger().
|
||||
// e.g do not call set_global_logger() from one thread while calling spdlog::info() from another.
|
||||
logger *context::global_logger_raw() const noexcept { return global_logger_.get(); }
|
||||
|
||||
// set global logger
|
||||
void context::set_logger(std::shared_ptr<logger> new_global_logger) { global_logger_ = std::move(new_global_logger); }
|
||||
|
||||
void context::set_tp(std::shared_ptr<thread_pool> tp) {
|
||||
std::lock_guard lock(tp_mutex_);
|
||||
tp_ = std::move(tp);
|
||||
}
|
||||
|
||||
std::shared_ptr<thread_pool> context::get_tp() {
|
||||
std::lock_guard lock(tp_mutex_);
|
||||
return tp_;
|
||||
}
|
||||
|
||||
// clean all resources and threads started by the registry
|
||||
void context::shutdown() {
|
||||
std::lock_guard lock(tp_mutex_);
|
||||
tp_.reset();
|
||||
}
|
||||
|
||||
std::recursive_mutex &context::tp_mutex() { return tp_mutex_; }
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
@@ -1,13 +1,13 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#include "spdlog/details/file_helper.h"
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
#include <utility>
|
||||
#include <filesystem>
|
||||
#include <utility>
|
||||
|
||||
#include "spdlog/details/file_helper.h"
|
||||
#include "spdlog/common.h"
|
||||
#include "spdlog/details/os.h"
|
||||
|
||||
@@ -29,9 +29,11 @@ void file_helper::open(const filename_t &fname, bool truncate) {
|
||||
if (event_handlers_.before_open) {
|
||||
event_handlers_.before_open(filename_);
|
||||
}
|
||||
|
||||
// create containing folder if not exists already.
|
||||
os::create_dir(os::dir_name(fname));
|
||||
|
||||
for (int tries = 0; tries < open_tries_; ++tries) {
|
||||
// create containing folder if not exists already.
|
||||
os::create_dir(os::dir_name(fname));
|
||||
if (truncate) {
|
||||
// Truncate by opening-and-closing a tmp file in "wb" mode, always
|
||||
// opening the actual log-we-write-to in "ab" mode, since that
|
||||
@@ -108,6 +110,5 @@ size_t file_helper::size() const {
|
||||
|
||||
const filename_t &file_helper::filename() const { return filename_; }
|
||||
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
|
@@ -11,9 +11,7 @@ namespace spdlog {
|
||||
namespace details {
|
||||
namespace os {
|
||||
|
||||
bool remove(const filename_t &filename) {
|
||||
return std::filesystem::remove(filename);
|
||||
}
|
||||
bool remove(const filename_t &filename) { return std::filesystem::remove(filename); }
|
||||
|
||||
bool remove_if_exists(const filename_t &filename) {
|
||||
if (path_exists(filename)) {
|
||||
@@ -42,7 +40,6 @@ bool path_exists(const filename_t &filename) noexcept { return std::filesystem::
|
||||
// "abc///" => "abc//"
|
||||
filename_t dir_name(const filename_t &path) { return path.parent_path(); }
|
||||
|
||||
|
||||
// Create the given directory - and all directories leading to it
|
||||
// return true on success or if the directory already exists
|
||||
bool create_dir(const filename_t &path) {
|
||||
@@ -50,19 +47,13 @@ bool create_dir(const filename_t &path) {
|
||||
return std::filesystem::create_directories(path, ec) || !ec;
|
||||
}
|
||||
|
||||
|
||||
// Return file path and its extension:
|
||||
//
|
||||
// "mylog.txt" => ("mylog", ".txt")
|
||||
// "mylog" => ("mylog", "")
|
||||
// "mylog." => ("mylog", ".")
|
||||
// "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt")
|
||||
//
|
||||
// the starting dot in filenames is ignored (hidden files):
|
||||
//
|
||||
// ".mylog" => (".mylog". "")
|
||||
// "my_folder/.mylog" => ("my_folder/.mylog", "")
|
||||
// "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
|
||||
// ".mylog" => (".mylog", "")
|
||||
std::tuple<filename_t, filename_t> split_by_extension(const filename_t &fname) {
|
||||
const auto ext = fname.extension();
|
||||
auto without_ext = filename_t(fname).replace_extension();
|
||||
|
@@ -99,7 +99,6 @@ bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode) {
|
||||
return *fp == nullptr;
|
||||
}
|
||||
|
||||
|
||||
// Return file size according to open FILE* object
|
||||
size_t filesize(FILE *f) {
|
||||
if (f == nullptr) {
|
||||
@@ -231,9 +230,9 @@ void sleep_for_millis(unsigned int milliseconds) noexcept {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
|
||||
}
|
||||
|
||||
std::string filename_to_str(const filename_t &filename) {
|
||||
std::string filename_to_str(const filename_t &filename) {
|
||||
static_assert(std::is_same_v<filename_t::value_type, char>, "filename_t type must be char");
|
||||
return filename;
|
||||
return filename;
|
||||
}
|
||||
|
||||
int pid() noexcept { return static_cast<int>(::getpid()); }
|
||||
|
@@ -6,7 +6,7 @@
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
#include "spdlog/details/windows_include.h"
|
||||
#include "spdlog/details/windows_include.h" // must be included before fileapi.h etc.
|
||||
// clang-format on
|
||||
|
||||
#include <fileapi.h> // for FlushFileBuffers
|
||||
@@ -75,8 +75,6 @@ bool fopen_s(FILE **fp, const filename_t &filename, const filename_t &mode) {
|
||||
return *fp == nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// avoid warning about unreachable statement at the end of filesize()
|
||||
#pragma warning(push)
|
||||
@@ -151,15 +149,13 @@ void sleep_for_millis(unsigned int milliseconds) noexcept { ::Sleep(milliseconds
|
||||
// Try tp convert wstring filename to string. Return "???" if failed
|
||||
std::string filename_to_str(const filename_t &filename) {
|
||||
static_assert(std::is_same_v<filename_t::value_type, wchar_t>, "filename_t type must be wchar_t");
|
||||
try {
|
||||
try {
|
||||
memory_buf_t buf;
|
||||
wstr_to_utf8buf(filename.wstring(), buf);
|
||||
return std::string(buf.data(), buf.size());
|
||||
} catch (...) {
|
||||
return "???";
|
||||
}
|
||||
catch (...) {
|
||||
return "???";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int pid() noexcept { return static_cast<int>(::GetCurrentProcessId()); }
|
||||
@@ -224,7 +220,6 @@ void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target) {
|
||||
throw_spdlog_ex(fmt_lib::format("MultiByteToWideChar failed. Last error: {}", ::GetLastError()));
|
||||
}
|
||||
|
||||
|
||||
std::string getenv(const char *field) {
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(__cplusplus_winrt)
|
||||
|
@@ -1,22 +0,0 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#include "spdlog/details/periodic_worker.h"
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
|
||||
// stop the worker thread and join it
|
||||
periodic_worker::~periodic_worker() {
|
||||
if (worker_thread_.joinable()) {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
active_ = false;
|
||||
}
|
||||
cv_.notify_one();
|
||||
worker_thread_.join();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
@@ -1,263 +0,0 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#include "spdlog/details/registry.h"
|
||||
|
||||
#include "spdlog/common.h"
|
||||
#include "spdlog/logger.h"
|
||||
#include "spdlog/pattern_formatter.h"
|
||||
|
||||
#ifndef SPDLOG_DISABLE_DEFAULT_LOGGER
|
||||
// support for the default stdout color logger
|
||||
#ifdef _WIN32
|
||||
#include "spdlog/sinks/wincolor_sink.h"
|
||||
#else
|
||||
|
||||
#include "spdlog/sinks/ansicolor_sink.h"
|
||||
|
||||
#endif
|
||||
#endif // SPDLOG_DISABLE_DEFAULT_LOGGER
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
static constexpr size_t small_map_threshold = 10;
|
||||
|
||||
namespace spdlog {
|
||||
namespace details {
|
||||
|
||||
registry::registry()
|
||||
: formatter_(new pattern_formatter()) {
|
||||
#ifndef SPDLOG_DISABLE_DEFAULT_LOGGER
|
||||
// create default logger (ansicolor_stdout_sink_mt or wincolor_stdout_sink_mt in windows).
|
||||
#ifdef _WIN32
|
||||
auto color_sink = std::make_shared<sinks::wincolor_stdout_sink_mt>();
|
||||
#else
|
||||
auto color_sink = std::make_shared<sinks::ansicolor_stdout_sink_mt>();
|
||||
#endif
|
||||
const char *default_logger_name = "";
|
||||
default_logger_ = std::make_shared<spdlog::logger>(default_logger_name, std::move(color_sink));
|
||||
loggers_[default_logger_name] = default_logger_;
|
||||
|
||||
#endif // SPDLOG_DISABLE_DEFAULT_LOGGER
|
||||
}
|
||||
|
||||
registry::~registry() = default;
|
||||
|
||||
void registry::register_logger(std::shared_ptr<logger> new_logger) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
register_logger_(std::move(new_logger));
|
||||
}
|
||||
|
||||
void registry::initialize_logger(std::shared_ptr<logger> new_logger) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
new_logger->set_formatter(formatter_->clone());
|
||||
|
||||
if (err_handler_) {
|
||||
new_logger->set_error_handler(err_handler_);
|
||||
}
|
||||
|
||||
// set new level according to previously configured level or default level
|
||||
auto it = log_levels_.find(new_logger->name());
|
||||
auto new_level = it != log_levels_.end() ? it->second : global_log_level_;
|
||||
new_logger->set_level(new_level);
|
||||
|
||||
new_logger->flush_on(flush_level_);
|
||||
|
||||
if (automatic_registration_) {
|
||||
register_logger_(std::move(new_logger));
|
||||
}
|
||||
}
|
||||
|
||||
// if the map is small do a sequential search, otherwise use the standard find()
|
||||
std::shared_ptr<logger> registry::get(const std::string &logger_name) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
if (loggers_.size() <= small_map_threshold) {
|
||||
for (const auto &[key, val] : loggers_) {
|
||||
if (logger_name == key) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
auto found = loggers_.find(logger_name);
|
||||
return found == loggers_.end() ? nullptr : found->second;
|
||||
}
|
||||
|
||||
// if the map is small do a sequential search and avoid creating string for find(logger_name)
|
||||
// otherwise use the standard find()
|
||||
std::shared_ptr<logger> registry::get(std::string_view logger_name) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
if (loggers_.size() <= small_map_threshold) {
|
||||
for (const auto &[key, val] : loggers_) {
|
||||
if (logger_name == key) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
// otherwise use the normal map lookup
|
||||
const auto found = loggers_.find(std::string(logger_name));
|
||||
return found == loggers_.end() ? nullptr : found->second;
|
||||
}
|
||||
|
||||
std::shared_ptr<logger> registry::get(const char *logger_name) { return get(std::string_view(logger_name)); }
|
||||
|
||||
std::shared_ptr<logger> registry::default_logger() {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
return default_logger_;
|
||||
}
|
||||
|
||||
// Return raw ptr to the default logger.
|
||||
// To be used directly by the spdlog default api (e.g. spdlog::info)
|
||||
// This make the default API faster, but cannot be used concurrently with set_default_logger().
|
||||
// e.g do not call set_default_logger() from one thread while calling spdlog::info() from another.
|
||||
logger *registry::get_default_raw() const { return default_logger_.get(); }
|
||||
|
||||
// set default logger.
|
||||
// default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
|
||||
void registry::set_default_logger(std::shared_ptr<logger> new_default_logger) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
if (new_default_logger != nullptr) {
|
||||
loggers_[new_default_logger->name()] = new_default_logger;
|
||||
}
|
||||
default_logger_ = std::move(new_default_logger);
|
||||
}
|
||||
|
||||
void registry::set_tp(std::shared_ptr<thread_pool> tp) {
|
||||
std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
|
||||
tp_ = std::move(tp);
|
||||
}
|
||||
|
||||
std::shared_ptr<thread_pool> registry::get_tp() {
|
||||
std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
|
||||
return tp_;
|
||||
}
|
||||
|
||||
// Set global formatter. Each sink in each logger will get a clone of this object
|
||||
void registry::set_formatter(std::unique_ptr<formatter> formatter) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
formatter_ = std::move(formatter);
|
||||
for (auto &l : loggers_) {
|
||||
l.second->set_formatter(formatter_->clone());
|
||||
}
|
||||
}
|
||||
|
||||
void registry::set_level(level level) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
for (auto &l : loggers_) {
|
||||
l.second->set_level(level);
|
||||
}
|
||||
global_log_level_ = level;
|
||||
}
|
||||
|
||||
void registry::flush_on(level level) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
for (auto &l : loggers_) {
|
||||
l.second->flush_on(level);
|
||||
}
|
||||
flush_level_ = level;
|
||||
}
|
||||
|
||||
void registry::set_error_handler(err_handler handler) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
for (auto &l : loggers_) {
|
||||
l.second->set_error_handler(handler);
|
||||
}
|
||||
err_handler_ = std::move(handler);
|
||||
}
|
||||
|
||||
void registry::apply_all(const std::function<void(const std::shared_ptr<logger>)> &fun) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
for (auto &l : loggers_) {
|
||||
fun(l.second);
|
||||
}
|
||||
}
|
||||
|
||||
void registry::flush_all() {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
for (auto &l : loggers_) {
|
||||
l.second->flush();
|
||||
}
|
||||
}
|
||||
|
||||
void registry::drop(const std::string &logger_name) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
auto is_default_logger = default_logger_ && default_logger_->name() == logger_name;
|
||||
loggers_.erase(logger_name);
|
||||
if (is_default_logger) {
|
||||
default_logger_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void registry::drop_all() {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
loggers_.clear();
|
||||
default_logger_.reset();
|
||||
}
|
||||
|
||||
// clean all resources and threads started by the registry
|
||||
void registry::shutdown() {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(flusher_mutex_);
|
||||
periodic_flusher_.reset();
|
||||
}
|
||||
|
||||
drop_all();
|
||||
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(tp_mutex_);
|
||||
tp_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
std::recursive_mutex ®istry::tp_mutex() { return tp_mutex_; }
|
||||
|
||||
void registry::set_automatic_registration(bool automatic_registration) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
automatic_registration_ = automatic_registration;
|
||||
}
|
||||
|
||||
void registry::set_levels(log_levels levels, level *global_level) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
log_levels_ = std::move(levels);
|
||||
auto global_level_requested = global_level != nullptr;
|
||||
global_log_level_ = global_level_requested ? *global_level : global_log_level_;
|
||||
|
||||
for (auto &logger : loggers_) {
|
||||
auto logger_entry = log_levels_.find(logger.first);
|
||||
if (logger_entry != log_levels_.end()) {
|
||||
logger.second->set_level(logger_entry->second);
|
||||
} else if (global_level_requested) {
|
||||
logger.second->set_level(*global_level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registry ®istry::instance() {
|
||||
static registry s_instance;
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
void registry::apply_logger_env_levels(std::shared_ptr<logger> new_logger) {
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
auto it = log_levels_.find(new_logger->name());
|
||||
auto new_level = it != log_levels_.end() ? it->second : global_log_level_;
|
||||
new_logger->set_level(new_level);
|
||||
}
|
||||
|
||||
void registry::throw_if_exists_(const std::string &logger_name) {
|
||||
if (loggers_.find(logger_name) != loggers_.end()) {
|
||||
throw_spdlog_ex("logger with name '" + logger_name + "' already exists");
|
||||
}
|
||||
}
|
||||
|
||||
void registry::register_logger_(std::shared_ptr<logger> new_logger) {
|
||||
auto logger_name = new_logger->name();
|
||||
throw_if_exists_(logger_name);
|
||||
loggers_[logger_name] = std::move(new_logger);
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
@@ -5,9 +5,9 @@
|
||||
|
||||
#include <cerrno>
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <sstream>
|
||||
|
||||
#include "spdlog/common.h"
|
||||
#include "spdlog/details/file_helper.h"
|
||||
@@ -51,10 +51,10 @@ filename_t rotating_file_sink<Mutex>::calc_filename(const filename_t &filename,
|
||||
|
||||
filename_t basename;
|
||||
filename_t ext;
|
||||
std::tie(basename, ext) = details::os::split_by_extension(filename);
|
||||
std::tie(basename, ext) = details::os::split_by_extension(filename);
|
||||
std::basic_ostringstream<filename_t::value_type> oss;
|
||||
oss << basename.native() << '.' << index << ext.native();
|
||||
return oss.str();
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
template <typename Mutex>
|
||||
@@ -132,7 +132,7 @@ void rotating_file_sink<Mutex>::rotate_() {
|
||||
// delete the target if exists, and rename the src file to target
|
||||
// return true on success, false otherwise.
|
||||
template <typename Mutex>
|
||||
bool rotating_file_sink<Mutex>::rename_file_(const filename_t &src_filename, const filename_t &target_filename) noexcept{
|
||||
bool rotating_file_sink<Mutex>::rename_file_(const filename_t &src_filename, const filename_t &target_filename) noexcept {
|
||||
return details::os::rename(src_filename, target_filename);
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
|
||||
#include "spdlog/common.h"
|
||||
@@ -12,55 +13,45 @@
|
||||
|
||||
namespace spdlog {
|
||||
|
||||
void initialize_logger(std::shared_ptr<logger> logger) { details::registry::instance().initialize_logger(std::move(logger)); }
|
||||
static std::shared_ptr s_context =
|
||||
#ifndef SPDLOG_DISABLE_GLOBAL_LOGGER
|
||||
std::make_unique<details::context>(std::make_unique<logger>(std::string(), std::make_unique<sinks::stdout_color_sink_mt>()));
|
||||
#else
|
||||
std::make_unique<details::context>(); // empty context
|
||||
#endif
|
||||
|
||||
std::shared_ptr<logger> get(const std::string &name) { return details::registry::instance().get(name); }
|
||||
void set_context(std::shared_ptr<details::context> context) { s_context = std::move(context); }
|
||||
|
||||
std::shared_ptr<logger> get(std::string_view name) { return details::registry::instance().get(name); }
|
||||
std::shared_ptr<details::context> context() { return s_context; }
|
||||
|
||||
std::shared_ptr<logger> get(const char *name) { return details::registry::instance().get(name); }
|
||||
const std::shared_ptr<details::context> &context_ref() { return s_context; }
|
||||
|
||||
void set_formatter(std::unique_ptr<spdlog::formatter> formatter) {
|
||||
details::registry::instance().set_formatter(std::move(formatter));
|
||||
std::shared_ptr<logger> global_logger() { return context_ref()->global_logger(); }
|
||||
|
||||
void set_global_logger(std::shared_ptr<logger> global_logger) { context()->set_logger(std::move(global_logger)); }
|
||||
|
||||
logger *global_logger_raw() noexcept {
|
||||
auto *rv = context_ref()->global_logger_raw();
|
||||
assert(rv != nullptr);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void set_formatter(std::unique_ptr<formatter> formatter) { global_logger()->set_formatter(std::move(formatter)); }
|
||||
|
||||
void set_pattern(std::string pattern, pattern_time_type time_type) {
|
||||
set_formatter(std::make_unique<spdlog::pattern_formatter>(std::move(pattern), time_type));
|
||||
set_formatter(std::make_unique<pattern_formatter>(std::move(pattern), time_type));
|
||||
}
|
||||
|
||||
level get_level() { return default_logger_raw()->log_level(); }
|
||||
level get_level() { return global_logger()->log_level(); }
|
||||
|
||||
bool should_log(level level) { return default_logger_raw()->should_log(level); }
|
||||
bool should_log(level level) { return global_logger()->should_log(level); }
|
||||
|
||||
void set_level(level level) { details::registry::instance().set_level(level); }
|
||||
void set_level(level level) { global_logger()->set_level(level); }
|
||||
|
||||
void flush_on(level level) { details::registry::instance().flush_on(level); }
|
||||
void flush_on(level level) { global_logger()->flush_on(level); }
|
||||
|
||||
void set_error_handler(void (*handler)(const std::string &msg)) { details::registry::instance().set_error_handler(handler); }
|
||||
void set_error_handler(void (*handler)(const std::string &msg)) { global_logger()->set_error_handler(handler); }
|
||||
|
||||
void register_logger(std::shared_ptr<logger> logger) { details::registry::instance().register_logger(std::move(logger)); }
|
||||
void shutdown() { s_context.reset(); }
|
||||
|
||||
void apply_all(const std::function<void(std::shared_ptr<logger>)> &fun) { details::registry::instance().apply_all(fun); }
|
||||
|
||||
void drop(const std::string &name) { details::registry::instance().drop(name); }
|
||||
|
||||
void drop_all() { details::registry::instance().drop_all(); }
|
||||
|
||||
void shutdown() { details::registry::instance().shutdown(); }
|
||||
|
||||
void set_automatic_registration(bool automatic_registration) {
|
||||
details::registry::instance().set_automatic_registration(automatic_registration);
|
||||
}
|
||||
|
||||
std::shared_ptr<spdlog::logger> default_logger() { return details::registry::instance().default_logger(); }
|
||||
|
||||
spdlog::logger *default_logger_raw() { return details::registry::instance().get_default_raw(); }
|
||||
|
||||
void set_default_logger(std::shared_ptr<spdlog::logger> default_logger) {
|
||||
details::registry::instance().set_default_logger(std::move(default_logger));
|
||||
}
|
||||
|
||||
void apply_logger_env_levels(std::shared_ptr<logger> logger) {
|
||||
details::registry::instance().apply_logger_env_levels(std::move(logger));
|
||||
}
|
||||
} // namespace spdlog
|
||||
|
Reference in New Issue
Block a user