mirror of
https://github.com/gabime/spdlog.git
synced 2025-11-16 09:28:56 +08:00
@@ -19,13 +19,13 @@
|
||||
#include <mutex>
|
||||
|
||||
#include "./async_logger.h"
|
||||
#include "./details/registry.h"
|
||||
#include "./details/context.h"
|
||||
#include "./details/thread_pool.h"
|
||||
#include "spdlog.h"
|
||||
|
||||
namespace spdlog {
|
||||
|
||||
namespace details {
|
||||
static const size_t default_async_q_size = 8192;
|
||||
static constexpr size_t default_async_q_size = 8192;
|
||||
}
|
||||
|
||||
// async logger factory - creates async loggers backed with thread pool.
|
||||
@@ -35,20 +35,17 @@ template <async_overflow_policy OverflowPolicy = async_overflow_policy::block>
|
||||
struct async_factory_impl {
|
||||
template <typename Sink, typename... SinkArgs>
|
||||
static std::shared_ptr<async_logger> create(std::string logger_name, SinkArgs &&...args) {
|
||||
auto ®istry_inst = details::registry::instance();
|
||||
|
||||
auto context = spdlog::context();
|
||||
// create global thread pool if not already exists
|
||||
auto &mutex = registry_inst.tp_mutex();
|
||||
auto &mutex = context->tp_mutex();
|
||||
std::lock_guard<std::recursive_mutex> tp_lock(mutex);
|
||||
auto tp = registry_inst.get_tp();
|
||||
auto tp = context->get_tp();
|
||||
if (tp == nullptr) {
|
||||
tp = std::make_shared<details::thread_pool>(details::default_async_q_size, 1U);
|
||||
registry_inst.set_tp(tp);
|
||||
context->set_tp(tp);
|
||||
}
|
||||
|
||||
auto sink = std::make_shared<Sink>(std::forward<SinkArgs>(args)...);
|
||||
auto new_logger = std::make_shared<async_logger>(std::move(logger_name), std::move(sink), std::move(tp), OverflowPolicy);
|
||||
registry_inst.initialize_logger(new_logger);
|
||||
return new_logger;
|
||||
}
|
||||
};
|
||||
@@ -72,7 +69,7 @@ inline void init_thread_pool(size_t q_size,
|
||||
std::function<void()> on_thread_start,
|
||||
std::function<void()> on_thread_stop) {
|
||||
auto tp = std::make_shared<details::thread_pool>(q_size, thread_count, on_thread_start, on_thread_stop);
|
||||
details::registry::instance().set_tp(std::move(tp));
|
||||
spdlog::context()->set_tp(std::move(tp));
|
||||
}
|
||||
|
||||
inline void init_thread_pool(size_t q_size, size_t thread_count, std::function<void()> on_thread_start) {
|
||||
@@ -84,5 +81,5 @@ inline void init_thread_pool(size_t q_size, size_t thread_count) {
|
||||
}
|
||||
|
||||
// get the global thread pool.
|
||||
inline std::shared_ptr<spdlog::details::thread_pool> thread_pool() { return details::registry::instance().get_tp(); }
|
||||
inline std::shared_ptr<spdlog::details::thread_pool> thread_pool() { return spdlog::context()->get_tp(); }
|
||||
} // namespace spdlog
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
#include "./helpers.h"
|
||||
|
||||
//
|
||||
// Init log levels using each argv entry that starts with "SPDLOG_LEVEL="
|
||||
//
|
||||
// set all loggers to debug level:
|
||||
// example.exe "SPDLOG_LEVEL=debug"
|
||||
|
||||
// set logger1 to trace level
|
||||
// example.exe "SPDLOG_LEVEL=logger1=trace"
|
||||
|
||||
// turn off all logging except for logger1 and logger2:
|
||||
// example.exe "SPDLOG_LEVEL=off,logger1=debug,logger2=info"
|
||||
|
||||
namespace spdlog {
|
||||
namespace cfg {
|
||||
|
||||
// search for SPDLOG_LEVEL= in the args and use it to init the levels
|
||||
inline void load_argv_levels(int argc, const char **argv) {
|
||||
const std::string spdlog_level_prefix = "SPDLOG_LEVEL=";
|
||||
for (int i = 1; i < argc; i++) {
|
||||
std::string arg = argv[i];
|
||||
if (arg.find(spdlog_level_prefix) == 0) {
|
||||
auto levels_string = arg.substr(spdlog_level_prefix.size());
|
||||
helpers::load_levels(levels_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void load_argv_levels(int argc, char **argv) { load_argv_levels(argc, const_cast<const char **>(argv)); }
|
||||
|
||||
} // namespace cfg
|
||||
} // namespace spdlog
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
#include "../details/os.h"
|
||||
#include "../details/registry.h"
|
||||
#include "./helpers.h"
|
||||
|
||||
//
|
||||
// Init levels and patterns from env variables SPDLOG_LEVEL
|
||||
// Inspired from Rust's "env_logger" crate (https://crates.io/crates/env_logger).
|
||||
// Note - fallback to "info" level on unrecognized levels
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// set global level to debug:
|
||||
// export SPDLOG_LEVEL=debug
|
||||
//
|
||||
// turn off all logging except for logger1:
|
||||
// export SPDLOG_LEVEL="*=off,logger1=debug"
|
||||
//
|
||||
|
||||
// turn off all logging except for logger1 and logger2:
|
||||
// export SPDLOG_LEVEL="off,logger1=debug,logger2=info"
|
||||
|
||||
namespace spdlog {
|
||||
namespace cfg {
|
||||
inline void load_env_levels() {
|
||||
auto env_val = details::os::getenv("SPDLOG_LEVEL");
|
||||
if (!env_val.empty()) {
|
||||
helpers::load_levels(env_val);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cfg
|
||||
} // namespace spdlog
|
||||
@@ -1,25 +0,0 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "../common.h"
|
||||
|
||||
namespace spdlog {
|
||||
namespace cfg {
|
||||
namespace helpers {
|
||||
//
|
||||
// Init levels from given string
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// set global level to debug: "debug"
|
||||
// turn off all logging except for logger1: "off,logger1=debug"
|
||||
// turn off all logging except for logger1 and logger2: "off,logger1=debug,logger2=info"
|
||||
//
|
||||
SPDLOG_API void load_levels(const std::string &input);
|
||||
} // namespace helpers
|
||||
} // namespace cfg
|
||||
} // namespace spdlog
|
||||
@@ -5,13 +5,12 @@
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <cstdio>
|
||||
#include <chrono>
|
||||
#include <exception>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <string_view>
|
||||
|
||||
#include "./source_loc.h"
|
||||
|
||||
59
include/spdlog/details/context.h
Normal file
59
include/spdlog/details/context.h
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
// Loggers registry of unique name->logger pointer
|
||||
// An attempt to create a logger with an already existing name will result with spdlog_ex exception.
|
||||
// If user requests a non-existing logger, nullptr will be returned
|
||||
// This class is thread safe
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include "../common.h"
|
||||
#include "./periodic_worker.h"
|
||||
|
||||
namespace spdlog {
|
||||
class logger;
|
||||
|
||||
namespace details {
|
||||
class thread_pool;
|
||||
|
||||
class SPDLOG_API context {
|
||||
public:
|
||||
context() = default;
|
||||
explicit context(std::unique_ptr<logger> global_logger);
|
||||
~context() = default;
|
||||
context(const context &) = delete;
|
||||
context &operator=(const context &) = delete;
|
||||
|
||||
[[nodiscard]] std::shared_ptr<logger> global_logger();
|
||||
|
||||
// Return raw ptr to the global logger.
|
||||
// To be used directly by the spdlog global api (e.g. spdlog::info)
|
||||
// This make the global 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.
|
||||
[[nodiscard]] logger *global_logger_raw() const noexcept;
|
||||
|
||||
// set logger instance.
|
||||
void set_logger(std::shared_ptr<logger> new_logger);
|
||||
|
||||
void set_tp(std::shared_ptr<thread_pool> tp);
|
||||
|
||||
[[nodiscard]] std::shared_ptr<thread_pool> get_tp();
|
||||
|
||||
// clean all resources
|
||||
void shutdown();
|
||||
[[nodiscard]] std::recursive_mutex &tp_mutex();
|
||||
|
||||
private:
|
||||
std::recursive_mutex tp_mutex_;
|
||||
std::shared_ptr<thread_pool> tp_;
|
||||
std::shared_ptr<logger> global_logger_;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <ctime> // std::time_t
|
||||
#include <tuple>
|
||||
|
||||
#include "../common.h"
|
||||
#include "../filename_t.h"
|
||||
|
||||
@@ -66,7 +67,6 @@ SPDLOG_API void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target);
|
||||
SPDLOG_API void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target);
|
||||
#endif
|
||||
|
||||
|
||||
// non thread safe, cross platform getenv/getenv_s
|
||||
// return empty string if field not found
|
||||
SPDLOG_API std::string getenv(const char *field);
|
||||
@@ -106,7 +106,6 @@ SPDLOG_API bool rename(const filename_t &filename1, const filename_t &filename2)
|
||||
// Return if file exists.
|
||||
SPDLOG_API bool path_exists(const filename_t &filename) noexcept;
|
||||
|
||||
|
||||
// Return file path and its extension:
|
||||
//
|
||||
// "mylog.txt" => ("mylog", ".txt")
|
||||
@@ -124,7 +123,6 @@ SPDLOG_API std::tuple<filename_t, filename_t> split_by_extension(const filename_
|
||||
// Try tp convert filename to string. Return "??" if failed
|
||||
SPDLOG_API std::string filename_to_str(const filename_t &filename);
|
||||
|
||||
|
||||
} // namespace os
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
// Loggers registry of unique name->logger pointer
|
||||
// An attempt to create a logger with an already existing name will result with spdlog_ex exception.
|
||||
// If user requests a non-existing logger, nullptr will be returned
|
||||
// This class is thread safe
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "../common.h"
|
||||
#include "./periodic_worker.h"
|
||||
|
||||
namespace spdlog {
|
||||
class logger;
|
||||
|
||||
namespace details {
|
||||
class thread_pool;
|
||||
|
||||
class SPDLOG_API registry {
|
||||
public:
|
||||
using log_levels = std::unordered_map<std::string, level>;
|
||||
|
||||
static registry &instance();
|
||||
registry(const registry &) = delete;
|
||||
registry &operator=(const registry &) = delete;
|
||||
|
||||
void register_logger(std::shared_ptr<logger> new_logger);
|
||||
void initialize_logger(std::shared_ptr<logger> new_logger);
|
||||
std::shared_ptr<logger> get(const std::string &logger_name);
|
||||
std::shared_ptr<logger> get(std::string_view logger_name);
|
||||
std::shared_ptr<logger> get(const char *logger_name);
|
||||
std::shared_ptr<logger> 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 *get_default_raw() const;
|
||||
|
||||
// set default logger.
|
||||
// default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
|
||||
void set_default_logger(std::shared_ptr<logger> new_default_logger);
|
||||
|
||||
void set_tp(std::shared_ptr<thread_pool> tp);
|
||||
|
||||
std::shared_ptr<thread_pool> get_tp();
|
||||
|
||||
// Set global formatter. Each sink in each logger will get a clone of this object
|
||||
void set_formatter(std::unique_ptr<formatter> formatter);
|
||||
|
||||
void set_level(level level);
|
||||
|
||||
void flush_on(level level);
|
||||
|
||||
template <typename Rep, typename Period>
|
||||
void flush_every(std::chrono::duration<Rep, Period> interval) {
|
||||
std::lock_guard<std::mutex> lock(flusher_mutex_);
|
||||
auto clbk = [this]() { this->flush_all(); };
|
||||
periodic_flusher_ = std::make_unique<periodic_worker>(clbk, interval);
|
||||
}
|
||||
|
||||
std::unique_ptr<periodic_worker> &get_flusher() {
|
||||
std::lock_guard<std::mutex> lock(flusher_mutex_);
|
||||
return periodic_flusher_;
|
||||
}
|
||||
|
||||
void set_error_handler(err_handler handler);
|
||||
|
||||
void apply_all(const std::function<void(const std::shared_ptr<logger>)> &fun);
|
||||
|
||||
void flush_all();
|
||||
|
||||
void drop(const std::string &logger_name);
|
||||
|
||||
void drop_all();
|
||||
|
||||
// clean all resources and threads started by the registry
|
||||
void shutdown();
|
||||
|
||||
std::recursive_mutex &tp_mutex();
|
||||
|
||||
void set_automatic_registration(bool automatic_registration);
|
||||
|
||||
// set levels for all existing/future loggers. global_level can be null if should not set.
|
||||
void set_levels(log_levels levels, level *global_level);
|
||||
|
||||
void apply_logger_env_levels(std::shared_ptr<logger> new_logger);
|
||||
|
||||
private:
|
||||
registry();
|
||||
~registry();
|
||||
|
||||
void throw_if_exists_(const std::string &logger_name);
|
||||
void register_logger_(std::shared_ptr<logger> new_logger);
|
||||
std::mutex logger_map_mutex_, flusher_mutex_;
|
||||
std::recursive_mutex tp_mutex_;
|
||||
std::unordered_map<std::string, std::shared_ptr<logger>> loggers_;
|
||||
log_levels log_levels_;
|
||||
std::unique_ptr<formatter> formatter_;
|
||||
spdlog::level global_log_level_ = level::info;
|
||||
level flush_level_ = level::off;
|
||||
err_handler err_handler_;
|
||||
std::shared_ptr<thread_pool> tp_;
|
||||
std::unique_ptr<periodic_worker> periodic_flusher_;
|
||||
std::shared_ptr<logger> default_logger_;
|
||||
bool automatic_registration_ = true;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "./registry.h"
|
||||
#include "./context.h"
|
||||
|
||||
namespace spdlog {
|
||||
|
||||
@@ -15,7 +15,6 @@ struct synchronous_factory {
|
||||
static std::shared_ptr<spdlog::logger> create(std::string logger_name, SinkArgs &&...args) {
|
||||
auto sink = std::make_shared<Sink>(std::forward<SinkArgs>(args)...);
|
||||
auto new_logger = std::make_shared<spdlog::logger>(std::move(logger_name), std::move(sink));
|
||||
details::registry::instance().initialize_logger(new_logger);
|
||||
return new_logger;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "./filename_t.h"
|
||||
|
||||
namespace spdlog {
|
||||
|
||||
@@ -88,10 +88,8 @@ inline details::dump_info<It> to_hex(const It range_begin, const It range_end, s
|
||||
|
||||
} // namespace spdlog
|
||||
|
||||
namespace fmt {
|
||||
|
||||
template <typename T>
|
||||
struct formatter<spdlog::details::dump_info<T>, char> {
|
||||
struct fmt::formatter<spdlog::details::dump_info<T>, char> {
|
||||
const char delimiter = ' ';
|
||||
bool put_newlines = true;
|
||||
bool put_delimiters = true;
|
||||
@@ -123,6 +121,7 @@ struct formatter<spdlog::details::dump_info<T>, char> {
|
||||
show_ascii = true;
|
||||
}
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
|
||||
++it;
|
||||
@@ -202,5 +201,4 @@ struct formatter<spdlog::details::dump_info<T>, char> {
|
||||
spdlog::fmt_lib::format_to(inserter, SPDLOG_FMT_STRING("{:04X}: "), pos);
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace fmt
|
||||
}; // namespace fmt
|
||||
|
||||
@@ -11,13 +11,12 @@
|
||||
#include <string>
|
||||
|
||||
#include "../common.h"
|
||||
#include "./base_sink.h"
|
||||
#include "../details/circular_q.h"
|
||||
#include "../details/file_helper.h"
|
||||
#include "../details/null_mutex.h"
|
||||
#include "../details/os.h"
|
||||
#include "../details/synchronous_factory.h"
|
||||
|
||||
#include "./base_sink.h"
|
||||
|
||||
namespace spdlog {
|
||||
namespace sinks {
|
||||
@@ -25,21 +24,21 @@ namespace sinks {
|
||||
/*
|
||||
* Generator of daily log file names in format basename_YYYY-MM-DD.ext
|
||||
*/
|
||||
struct daily_filename_calculator {
|
||||
struct daily_filename_calculator {
|
||||
static filename_t calc_filename(const filename_t &filename, const tm &now_tm) {
|
||||
filename_t basename, ext;
|
||||
std::tie(basename, ext) = details::os::split_by_extension(filename);
|
||||
std::basic_ostringstream<filename_t::value_type> oss;
|
||||
std::basic_ostringstream<filename_t::value_type> oss;
|
||||
oss << basename.native() << '_' << std::setfill(SPDLOG_FILENAME_T('0')) << std::setw(4) << now_tm.tm_year + 1900 << '-'
|
||||
<< std::setw(2) << now_tm.tm_mon + 1 << '-' << std::setw(2) << now_tm.tm_mday << ext.native();
|
||||
return oss.str();
|
||||
return oss.str();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Generator of daily log file names with strftime format.
|
||||
* Usages:
|
||||
*
|
||||
*
|
||||
* std::make_shared<spdlog::sinks::daily_file_format_sink_mt>("myapp-%Y-%m-%d:%H:%M:%S.log", hour, minute);
|
||||
* or
|
||||
* spdlog::daily_logger_format_mt("loggername, "myapp-%Y-%m-%d:%X.log", hour, minute)"
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
namespace spdlog {
|
||||
namespace sinks {
|
||||
template <typename Mutex>
|
||||
class dup_filter_sink : public dist_sink<Mutex> {
|
||||
class dup_filter_sink final : public dist_sink<Mutex> {
|
||||
public:
|
||||
template <class Rep, class Period>
|
||||
explicit dup_filter_sink(std::chrono::duration<Rep, Period> max_skip_duration, level notification_level = level::info)
|
||||
|
||||
@@ -28,11 +28,11 @@ struct hourly_filename_calculator {
|
||||
static filename_t calc_filename(const filename_t &filename, const tm &now_tm) {
|
||||
filename_t basename, ext;
|
||||
std::tie(basename, ext) = details::os::split_by_extension(filename);
|
||||
std::basic_ostringstream<filename_t::value_type> oss;
|
||||
std::basic_ostringstream<filename_t::value_type> oss;
|
||||
oss << basename.native() << '_' << std::setfill(SPDLOG_FILENAME_T('0')) << std::setw(4) << now_tm.tm_year + 1900 << '-'
|
||||
<< std::setw(2) << now_tm.tm_mon + 1 << '-' << std::setw(2) << now_tm.tm_mday << '_' << std::setw(2) << now_tm.tm_hour
|
||||
<< ext.native();
|
||||
return oss.str();
|
||||
return oss.str();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -47,10 +47,10 @@ template <typename Mutex, typename FileNameCalc = hourly_filename_calculator>
|
||||
class hourly_file_sink final : public base_sink<Mutex> {
|
||||
public:
|
||||
// create hourly file sink which rotates on given time
|
||||
hourly_file_sink(filename_t base_filename,
|
||||
bool truncate = false,
|
||||
uint16_t max_files = 0,
|
||||
const file_event_handlers &event_handlers = {})
|
||||
explicit hourly_file_sink(filename_t base_filename,
|
||||
bool truncate = false,
|
||||
uint16_t max_files = 0,
|
||||
const file_event_handlers &event_handlers = {})
|
||||
: base_filename_(std::move(base_filename)),
|
||||
file_helper_{event_handlers},
|
||||
truncate_(truncate),
|
||||
|
||||
@@ -21,7 +21,7 @@ template <typename Mutex>
|
||||
class msvc_sink final : public base_sink<Mutex> {
|
||||
public:
|
||||
msvc_sink() = default;
|
||||
msvc_sink(bool check_debugger_present)
|
||||
explicit msvc_sink(bool check_debugger_present)
|
||||
: check_debugger_present_{check_debugger_present} {}
|
||||
|
||||
protected:
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace sinks {
|
||||
* Sink that write to syslog using the `syscall()` library call.
|
||||
*/
|
||||
template <typename Mutex>
|
||||
class syslog_sink : public base_sink<Mutex> {
|
||||
class syslog_sink final : public base_sink<Mutex> {
|
||||
public:
|
||||
syslog_sink(std::string ident, int syslog_option, int syslog_facility, bool enable_formatting)
|
||||
: enable_formatting_{enable_formatting},
|
||||
|
||||
@@ -9,14 +9,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "./common.h"
|
||||
#include "./details/registry.h"
|
||||
#include "./details/context.h"
|
||||
#include "./details/synchronous_factory.h"
|
||||
#include "./logger.h"
|
||||
|
||||
@@ -24,153 +22,107 @@ namespace spdlog {
|
||||
|
||||
using default_factory = synchronous_factory;
|
||||
|
||||
// Create and register a logger with a templated sink type
|
||||
// The logger's level, formatter and flush level will be set according the
|
||||
// global settings.
|
||||
//
|
||||
SPDLOG_API void set_context(std::shared_ptr<details::context> context);
|
||||
SPDLOG_API std::shared_ptr<details::context> context();
|
||||
SPDLOG_API const std::shared_ptr<details::context> &context_ref();
|
||||
|
||||
// Create a logger with a templated sink type
|
||||
// Example:
|
||||
// spdlog::create<daily_file_sink_st>("logger_name", "dailylog_filename", 11, 59);
|
||||
template <typename Sink, typename... SinkArgs>
|
||||
inline std::shared_ptr<spdlog::logger> create(std::string logger_name, SinkArgs &&...sink_args) {
|
||||
std::shared_ptr<logger> create(std::string logger_name, SinkArgs &&...sink_args) {
|
||||
return default_factory::create<Sink>(std::move(logger_name), std::forward<SinkArgs>(sink_args)...);
|
||||
}
|
||||
|
||||
// Initialize and register a logger,
|
||||
// formatter and flush level will be set according the global settings.
|
||||
//
|
||||
// Useful for initializing manually created loggers with the global settings.
|
||||
//
|
||||
// Example:
|
||||
// auto mylogger = std::make_shared<spdlog::logger>("mylogger", ...);
|
||||
// spdlog::initialize_logger(mylogger);
|
||||
SPDLOG_API void initialize_logger(std::shared_ptr<logger> logger);
|
||||
// Set formatter of the global logger. Each sink in each logger will get a clone of this object
|
||||
SPDLOG_API void set_formatter(std::unique_ptr<formatter> formatter);
|
||||
|
||||
// Return an existing logger or nullptr if a logger with such name doesn't
|
||||
// exist.
|
||||
// example: spdlog::get("my_logger")->info("hello {}", "world");
|
||||
SPDLOG_API std::shared_ptr<logger> get(const std::string &name);
|
||||
SPDLOG_API std::shared_ptr<logger> get(std::string_view name);
|
||||
SPDLOG_API std::shared_ptr<logger> get(const char *name);
|
||||
|
||||
// Set global formatter. Each sink in each logger will get a clone of this object
|
||||
SPDLOG_API void set_formatter(std::unique_ptr<spdlog::formatter> formatter);
|
||||
|
||||
// Set global format string.
|
||||
// Set format string of the global logger.
|
||||
// example: spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %v");
|
||||
SPDLOG_API void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local);
|
||||
|
||||
// Get global logging level
|
||||
// Get logging level of the global logger
|
||||
SPDLOG_API level get_level();
|
||||
|
||||
// Set global logging level
|
||||
// Set logging level of the global logger
|
||||
SPDLOG_API void set_level(level level);
|
||||
|
||||
// Determine whether the default logger should log messages with a certain level
|
||||
// Determine whether the global logger should log messages with a certain level
|
||||
SPDLOG_API bool should_log(level level);
|
||||
|
||||
// Set global flush level
|
||||
// Set flush level of the global logger.
|
||||
SPDLOG_API void flush_on(level level);
|
||||
|
||||
// Start/Restart a periodic flusher thread
|
||||
// Warning: Use only if all your loggers are thread safe!
|
||||
template <typename Rep, typename Period>
|
||||
inline void flush_every(std::chrono::duration<Rep, Period> interval) {
|
||||
details::registry::instance().flush_every(interval);
|
||||
}
|
||||
|
||||
// Set global error handler
|
||||
// Set error handler for the global logger
|
||||
SPDLOG_API void set_error_handler(void (*handler)(const std::string &msg));
|
||||
|
||||
// Register the given logger with the given name
|
||||
SPDLOG_API void register_logger(std::shared_ptr<logger> logger);
|
||||
|
||||
// Apply a user defined function on all registered loggers
|
||||
// Example:
|
||||
// spdlog::apply_all([&](std::shared_ptr<spdlog::logger> l) {l->flush();});
|
||||
SPDLOG_API void apply_all(const std::function<void(std::shared_ptr<logger>)> &fun);
|
||||
|
||||
// Drop the reference to the given logger
|
||||
SPDLOG_API void drop(const std::string &name);
|
||||
|
||||
// Drop all references from the registry
|
||||
SPDLOG_API void drop_all();
|
||||
|
||||
// stop any running threads started by spdlog and clean registry loggers
|
||||
// calls context::shutdown() to perform final cleanups
|
||||
SPDLOG_API void shutdown();
|
||||
|
||||
// Automatic registration of loggers when using spdlog::create() or spdlog::create_async
|
||||
SPDLOG_API void set_automatic_registration(bool automatic_registration);
|
||||
|
||||
// API for using default logger (stdout_color_mt),
|
||||
// API for using global logger (stdout_color_mt),
|
||||
// e.g: spdlog::info("Message {}", 1);
|
||||
//
|
||||
// The default logger object can be accessed using the spdlog::default_logger():
|
||||
// The global logger object can be accessed using the spdlog::global_logger():
|
||||
// For example, to add another sink to it:
|
||||
// spdlog::default_logger()->sinks().push_back(some_sink);
|
||||
// spdlog::global_logger()->sinks().push_back(some_sink);
|
||||
//
|
||||
// The default logger can replaced using spdlog::set_default_logger(new_logger).
|
||||
// The global logger can be replaced using spdlog::set_global_logger(new_logger).
|
||||
// For example, to replace it with a file logger.
|
||||
//
|
||||
// IMPORTANT:
|
||||
// The default API is thread safe (for _mt loggers), but:
|
||||
// set_default_logger() *should not* be used concurrently with the default API.
|
||||
// e.g do not call set_default_logger() from one thread while calling spdlog::info() from another.
|
||||
// Do not call set_global_logger() from one thread while calling spdlog::info() from another.
|
||||
SPDLOG_API std::shared_ptr<logger> global_logger();
|
||||
|
||||
SPDLOG_API std::shared_ptr<spdlog::logger> default_logger();
|
||||
// Set the global logger. (for example, to replace the global logger with a custom logger)
|
||||
SPDLOG_API void set_global_logger(std::shared_ptr<logger> global_logger);
|
||||
|
||||
SPDLOG_API spdlog::logger *default_logger_raw();
|
||||
|
||||
SPDLOG_API void set_default_logger(std::shared_ptr<spdlog::logger> default_logger);
|
||||
|
||||
// Initialize logger level based on environment configs.
|
||||
//
|
||||
// Useful for applying SPDLOG_LEVEL to manually created loggers.
|
||||
//
|
||||
// Example:
|
||||
// auto mylogger = std::make_shared<spdlog::logger>("mylogger", ...);
|
||||
// spdlog::apply_logger_env_levels(mylogger);
|
||||
SPDLOG_API void apply_logger_env_levels(std::shared_ptr<logger> logger);
|
||||
// Return the global logger raw pointer.
|
||||
// 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.
|
||||
SPDLOG_API logger *global_logger_raw() noexcept;
|
||||
|
||||
template <typename... Args>
|
||||
inline void log(source_loc source, level lvl, format_string_t<Args...> fmt, Args &&...args) {
|
||||
default_logger_raw()->log(source, lvl, fmt, std::forward<Args>(args)...);
|
||||
void log(source_loc source, level lvl, format_string_t<Args...> fmt, Args &&...args) {
|
||||
global_logger_raw()->log(source, lvl, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void log(level lvl, format_string_t<Args...> fmt, Args &&...args) {
|
||||
default_logger_raw()->log(lvl, fmt, std::forward<Args>(args)...);
|
||||
void log(level lvl, format_string_t<Args...> fmt, Args &&...args) {
|
||||
global_logger_raw()->log(lvl, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
inline void log(level lvl, std::string_view msg) { default_logger_raw()->log(lvl, msg); }
|
||||
inline void log(source_loc loc, level lvl, std::string_view msg) { default_logger_raw()->log(loc, lvl, msg); }
|
||||
inline void log(level lvl, std::string_view msg) { global_logger_raw()->log(lvl, msg); }
|
||||
|
||||
inline void log(source_loc loc, level lvl, std::string_view msg) { global_logger_raw()->log(loc, lvl, msg); }
|
||||
|
||||
template <typename... Args>
|
||||
inline void trace(format_string_t<Args...> fmt, Args &&...args) {
|
||||
void trace(format_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::trace, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void debug(format_string_t<Args...> fmt, Args &&...args) {
|
||||
void debug(format_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::debug, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void info(format_string_t<Args...> fmt, Args &&...args) {
|
||||
void info(format_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::info, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void warn(format_string_t<Args...> fmt, Args &&...args) {
|
||||
void warn(format_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::warn, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void error(format_string_t<Args...> fmt, Args &&...args) {
|
||||
void error(format_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::err, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
inline void critical(format_string_t<Args...> fmt, Args &&...args) {
|
||||
void critical(format_string_t<Args...> fmt, Args &&...args) {
|
||||
log(level::critical, fmt, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
@@ -211,7 +163,7 @@ inline void critical(std::string_view msg) { log(level::critical, msg); }
|
||||
|
||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE
|
||||
#define SPDLOG_LOGGER_TRACE(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::trace, __VA_ARGS__)
|
||||
#define SPDLOG_TRACE(...) SPDLOG_LOGGER_TRACE(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||
#define SPDLOG_TRACE(...) SPDLOG_LOGGER_TRACE(spdlog::global_logger_raw(), __VA_ARGS__)
|
||||
#else
|
||||
#define SPDLOG_LOGGER_TRACE(logger, ...) (void)0
|
||||
#define SPDLOG_TRACE(...) (void)0
|
||||
@@ -219,7 +171,7 @@ inline void critical(std::string_view msg) { log(level::critical, msg); }
|
||||
|
||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_DEBUG
|
||||
#define SPDLOG_LOGGER_DEBUG(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::debug, __VA_ARGS__)
|
||||
#define SPDLOG_DEBUG(...) SPDLOG_LOGGER_DEBUG(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||
#define SPDLOG_DEBUG(...) SPDLOG_LOGGER_DEBUG(spdlog::global_logger(), __VA_ARGS__)
|
||||
#else
|
||||
#define SPDLOG_LOGGER_DEBUG(logger, ...) (void)0
|
||||
#define SPDLOG_DEBUG(...) (void)0
|
||||
@@ -227,7 +179,7 @@ inline void critical(std::string_view msg) { log(level::critical, msg); }
|
||||
|
||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_INFO
|
||||
#define SPDLOG_LOGGER_INFO(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::info, __VA_ARGS__)
|
||||
#define SPDLOG_INFO(...) SPDLOG_LOGGER_INFO(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||
#define SPDLOG_INFO(...) SPDLOG_LOGGER_INFO(spdlog::global_logger(), __VA_ARGS__)
|
||||
#else
|
||||
#define SPDLOG_LOGGER_INFO(logger, ...) (void)0
|
||||
#define SPDLOG_INFO(...) (void)0
|
||||
@@ -235,7 +187,7 @@ inline void critical(std::string_view msg) { log(level::critical, msg); }
|
||||
|
||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_WARN
|
||||
#define SPDLOG_LOGGER_WARN(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::warn, __VA_ARGS__)
|
||||
#define SPDLOG_WARN(...) SPDLOG_LOGGER_WARN(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||
#define SPDLOG_WARN(...) SPDLOG_LOGGER_WARN(spdlog::global_logger(), __VA_ARGS__)
|
||||
#else
|
||||
#define SPDLOG_LOGGER_WARN(logger, ...) (void)0
|
||||
#define SPDLOG_WARN(...) (void)0
|
||||
@@ -243,7 +195,7 @@ inline void critical(std::string_view msg) { log(level::critical, msg); }
|
||||
|
||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_ERROR
|
||||
#define SPDLOG_LOGGER_ERROR(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::err, __VA_ARGS__)
|
||||
#define SPDLOG_ERROR(...) SPDLOG_LOGGER_ERROR(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||
#define SPDLOG_ERROR(...) SPDLOG_LOGGER_ERROR(spdlog::global_logger(), __VA_ARGS__)
|
||||
#else
|
||||
#define SPDLOG_LOGGER_ERROR(logger, ...) (void)0
|
||||
#define SPDLOG_ERROR(...) (void)0
|
||||
@@ -251,7 +203,7 @@ inline void critical(std::string_view msg) { log(level::critical, msg); }
|
||||
|
||||
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_CRITICAL
|
||||
#define SPDLOG_LOGGER_CRITICAL(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::critical, __VA_ARGS__)
|
||||
#define SPDLOG_CRITICAL(...) SPDLOG_LOGGER_CRITICAL(spdlog::default_logger_raw(), __VA_ARGS__)
|
||||
#define SPDLOG_CRITICAL(...) SPDLOG_LOGGER_CRITICAL(spdlog::global_logger(), __VA_ARGS__)
|
||||
#else
|
||||
#define SPDLOG_LOGGER_CRITICAL(logger, ...) (void)0
|
||||
#define SPDLOG_CRITICAL(...) (void)0
|
||||
|
||||
@@ -51,13 +51,10 @@ public:
|
||||
} // namespace spdlog
|
||||
|
||||
// Support for fmt formatting (e.g. "{:012.9}" or just "{}")
|
||||
namespace fmt {
|
||||
|
||||
template <>
|
||||
struct formatter<spdlog::stopwatch> : formatter<double> {
|
||||
struct fmt::formatter<spdlog::stopwatch> : formatter<double> {
|
||||
template <typename FormatContext>
|
||||
auto format(const spdlog::stopwatch &sw, FormatContext &ctx) const -> decltype(ctx.out()) {
|
||||
return formatter<double>::format(sw.elapsed().count(), ctx);
|
||||
}
|
||||
};
|
||||
} // namespace fmt
|
||||
}; // namespace fmt
|
||||
|
||||
Reference in New Issue
Block a user