wip static_only

This commit is contained in:
gabime
2023-09-24 20:26:32 +03:00
parent ab86471489
commit 2a1959c2ce
39 changed files with 360 additions and 1777 deletions

View File

@@ -1,7 +0,0 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include <spdlog/async.h>
#include <spdlog/async_logger-inl.h>
#include <spdlog/details/periodic_worker-inl.h>
#include <spdlog/details/thread_pool-inl.h>

95
src/async_logger.cpp Normal file
View File

@@ -0,0 +1,95 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include <spdlog/async_logger.h>
#include <spdlog/sinks/sink.h>
#include <spdlog/details/thread_pool.h>
#include <memory>
#include <string>
spdlog::async_logger::async_logger(
std::string logger_name, sinks_init_list sinks_list, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy)
: async_logger(std::move(logger_name), sinks_list.begin(), sinks_list.end(), std::move(tp), overflow_policy)
{}
spdlog::async_logger::async_logger(
std::string logger_name, sink_ptr single_sink, std::weak_ptr<details::thread_pool> tp, async_overflow_policy overflow_policy)
: async_logger(std::move(logger_name), {std::move(single_sink)}, std::move(tp), overflow_policy)
{}
// send the log message to the thread pool
void spdlog::async_logger::sink_it_(const details::log_msg &msg)
{
SPDLOG_TRY
{
if (auto pool_ptr = thread_pool_.lock())
{
pool_ptr->post_log(shared_from_this(), msg, overflow_policy_);
}
else
{
throw_spdlog_ex("async log: thread pool doesn't exist anymore");
}
}
SPDLOG_LOGGER_CATCH(msg.source)
}
// send flush request to the thread pool
void spdlog::async_logger::flush_()
{
SPDLOG_TRY
{
if (auto pool_ptr = thread_pool_.lock())
{
pool_ptr->post_flush(shared_from_this(), overflow_policy_);
}
else
{
throw_spdlog_ex("async flush: thread pool doesn't exist anymore");
}
}
SPDLOG_LOGGER_CATCH(source_loc())
}
//
// backend functions - called from the thread pool to do the actual job
//
void spdlog::async_logger::backend_sink_it_(const details::log_msg &msg)
{
for (auto &sink : sinks_)
{
if (sink->should_log(msg.log_level))
{
SPDLOG_TRY
{
sink->log(msg);
}
SPDLOG_LOGGER_CATCH(msg.source)
}
}
if (should_flush_(msg))
{
backend_flush_();
}
}
void spdlog::async_logger::backend_flush_()
{
for (auto &sink : sinks_)
{
SPDLOG_TRY
{
sink->flush();
}
SPDLOG_LOGGER_CATCH(source_loc())
}
}
std::shared_ptr<spdlog::logger> spdlog::async_logger::clone(std::string new_name)
{
auto cloned = std::make_shared<spdlog::async_logger>(*this);
cloned->name_ = std::move(new_name);
return cloned;
}

View File

@@ -1,4 +0,0 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include <spdlog/cfg/helpers-inl.h>

115
src/cfg/.helpers.cpp Normal file
View File

@@ -0,0 +1,115 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include <spdlog/cfg/helpers.h>
#include <spdlog/spdlog.h>
#include <spdlog/details/registry.h>
#include <algorithm>
#include <string>
#include <utility>
#include <sstream>
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

59
src/common.cpp Normal file
View File

@@ -0,0 +1,59 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include <spdlog/common.h>
#include <algorithm>
#include <iterator>
namespace spdlog {
spdlog::level level_from_str(const std::string &name) noexcept
{
auto it = std::find(std::begin(level_string_views), std::end(level_string_views), name);
if (it != std::end(level_string_views))
return static_cast<level>(std::distance(std::begin(level_string_views), it));
// check also for "warn" and "err" before giving up..
if (name == "warn")
{
return spdlog::level::warn;
}
if (name == "err")
{
return level::err;
}
return level::off;
}
spdlog_ex::spdlog_ex(std::string msg)
: msg_(std::move(msg))
{}
spdlog_ex::spdlog_ex(const std::string &msg, int last_errno)
{
#ifdef SPDLOG_USE_STD_FORMAT
msg_ = std::system_error(std::error_code(last_errno, std::generic_category()), msg).what();
#else
memory_buf_t outbuf;
fmt::format_system_error(outbuf, last_errno, msg.c_str());
msg_ = fmt::to_string(outbuf);
#endif
}
const char *spdlog_ex::what() const noexcept
{
return msg_.c_str();
}
void throw_spdlog_ex(const std::string &msg, int last_errno)
{
SPDLOG_THROW(spdlog_ex(msg, last_errno));
}
void throw_spdlog_ex(std::string msg)
{
SPDLOG_THROW(spdlog_ex(std::move(msg)));
}
} // namespace spdlog

View File

@@ -1,19 +1,13 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
#include <spdlog/details/file_helper.h>
#include <spdlog/details/os.h>
#include <spdlog/common.h>
#include <cerrno>
#include <chrono>
#include <cstdio>
#include <string>
#include <thread>
#include <tuple>
namespace spdlog {

View File

@@ -1,10 +1,7 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
# include <spdlog/details/log_msg.h>
#include <spdlog/details/log_msg.h>
#include <spdlog/details/os.h>
namespace spdlog {

View File

@@ -1,9 +1,7 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
# include <spdlog/details/log_msg_buffer.h>
#include <spdlog/details/log_msg_buffer.h>
namespace spdlog {
namespace details {

View File

@@ -1,10 +1,7 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
# include <spdlog/details/os.h>
#include <spdlog/details/os.h>
#include <spdlog/common.h>
#include <algorithm>
@@ -17,7 +14,6 @@
#include <thread>
#include <array>
#include <sys/stat.h>
#include <sys/types.h>
#ifdef _WIN32

View File

@@ -1,9 +1,7 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
# include <spdlog/details/periodic_worker.h>
#include <spdlog/details/periodic_worker.h>
namespace spdlog {
namespace details {

View File

@@ -1,9 +1,7 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
# include <spdlog/details/registry.h>
#include <spdlog/details/registry.h>
#include <spdlog/common.h>
#include <spdlog/details/periodic_worker.h>

View File

@@ -1,10 +1,7 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
#include <spdlog/details/thread_pool.h>
#include <spdlog/common.h>
#include <cassert>

159
src/logger.cpp Normal file
View File

@@ -0,0 +1,159 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include <spdlog/logger.h>
#include <spdlog/sinks/sink.h>
#include <spdlog/pattern_formatter.h>
#include <cstdio>
#include <mutex>
namespace spdlog {
// public methods
logger::logger(const logger &other) noexcept
: name_(other.name_)
, sinks_(other.sinks_)
, level_(other.level_.load(std::memory_order_relaxed))
, flush_level_(other.flush_level_.load(std::memory_order_relaxed))
, custom_err_handler_(other.custom_err_handler_)
{}
logger::logger(logger &&other) noexcept
: name_(std::move(other.name_))
, sinks_(std::move(other.sinks_))
, level_(other.level_.load(std::memory_order_relaxed))
, flush_level_(other.flush_level_.load(std::memory_order_relaxed))
, custom_err_handler_(std::move(other.custom_err_handler_))
{}
void logger::set_level(level level)
{
level_.store(level);
}
level logger::log_level() const
{
return static_cast<level>(level_.load(std::memory_order_relaxed));
}
const std::string &logger::name() const
{
return name_;
}
// set formatting for the sinks in this logger.
// each sink will get a separate instance of the formatter object.
void logger::set_formatter(std::unique_ptr<formatter> f)
{
for (auto it = sinks_.begin(); it != sinks_.end(); ++it)
{
if (std::next(it) == sinks_.end())
{
// last element - we can be move it.
(*it)->set_formatter(std::move(f));
break; // to prevent clang-tidy warning
}
else
{
(*it)->set_formatter(f->clone());
}
}
}
void logger::set_pattern(std::string pattern, pattern_time_type time_type)
{
auto new_formatter = std::make_unique<pattern_formatter>(std::move(pattern), time_type);
set_formatter(std::move(new_formatter));
}
// flush functions
void logger::flush()
{
flush_();
}
void logger::flush_on(level level)
{
flush_level_.store(level);
}
level logger::flush_level() const
{
return static_cast<level>(flush_level_.load(std::memory_order_relaxed));
}
// sinks
const std::vector<sink_ptr> &logger::sinks() const
{
return sinks_;
}
std::vector<sink_ptr> &logger::sinks()
{
return sinks_;
}
// error handler
void logger::set_error_handler(err_handler handler)
{
custom_err_handler_ = std::move(handler);
}
// create new logger with same sinks and configuration.
std::shared_ptr<logger> logger::clone(std::string logger_name)
{
auto cloned = std::make_shared<logger>(*this);
cloned->name_ = std::move(logger_name);
return cloned;
}
void logger::flush_()
{
for (auto &sink : sinks_)
{
SPDLOG_TRY
{
sink->flush();
}
SPDLOG_LOGGER_CATCH(source_loc())
}
}
bool logger::should_flush_(const details::log_msg &msg)
{
auto flush_level = flush_level_.load(std::memory_order_relaxed);
return (msg.log_level >= flush_level) && (msg.log_level != level::off);
}
void logger::err_handler_(const std::string &msg)
{
if (custom_err_handler_)
{
custom_err_handler_(msg);
}
else
{
using std::chrono::system_clock;
static std::mutex mutex;
static std::chrono::system_clock::time_point last_report_time;
static size_t err_counter = 0;
std::lock_guard<std::mutex> lk{mutex};
auto now = system_clock::now();
err_counter++;
if (now - last_report_time < std::chrono::seconds(1))
{
return;
}
last_report_time = now;
auto tm_time = details::os::localtime(system_clock::to_time_t(now));
char date_buf[64];
std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time);
#if defined(USING_R) && defined(R_R_H) // if in R environment
REprintf("[*** LOG ERROR #%04zu ***] [%s] [%s] %s\n", err_counter, date_buf, name().c_str(), msg.c_str());
#else
std::fprintf(stderr, "[*** LOG ERROR #%04zu ***] [%s] [%s] %s\n", err_counter, date_buf, name().c_str(), msg.c_str());
#endif
}
}
} // namespace spdlog

1426
src/pattern_formatter.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,150 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include <spdlog/sinks/ansicolor_sink.h>
#include <spdlog/pattern_formatter.h>
#include <spdlog/details/os.h>
namespace spdlog {
namespace sinks {
template<typename ConsoleMutex>
ansicolor_sink<ConsoleMutex>::ansicolor_sink(FILE *target_file, color_mode mode)
: target_file_(target_file)
, mutex_(ConsoleMutex::mutex())
, formatter_(std::make_unique<spdlog::pattern_formatter>())
{
set_color_mode(mode);
colors_.at(level_to_number(level::trace)) = to_string_(white);
colors_.at(level_to_number(level::debug)) = to_string_(cyan);
colors_.at(level_to_number(level::info)) = to_string_(green);
colors_.at(level_to_number(level::warn)) = to_string_(yellow_bold);
colors_.at(level_to_number(level::err)) = to_string_(red_bold);
colors_.at(level_to_number(level::critical)) = to_string_(bold_on_red);
colors_.at(level_to_number(level::off)) = to_string_(reset);
}
template<typename ConsoleMutex>
void ansicolor_sink<ConsoleMutex>::set_color(level color_level, string_view_t color)
{
std::lock_guard<mutex_t> lock(mutex_);
colors_.at(level_to_number(color_level)) = to_string_(color);
}
template<typename ConsoleMutex>
void ansicolor_sink<ConsoleMutex>::log(const details::log_msg &msg)
{
// Wrap the originally formatted message in color codes.
// If color is not supported in the terminal, log as is instead.
std::lock_guard<mutex_t> lock(mutex_);
msg.color_range_start = 0;
msg.color_range_end = 0;
memory_buf_t formatted;
formatter_->format(msg, formatted);
if (should_do_colors_ && msg.color_range_end > msg.color_range_start)
{
// before color range
print_range_(formatted, 0, msg.color_range_start);
// in color range
print_ccode_(colors_.at(level_to_number(msg.log_level)));
print_range_(formatted, msg.color_range_start, msg.color_range_end);
print_ccode_(reset);
// after color range
print_range_(formatted, msg.color_range_end, formatted.size());
}
else // no color
{
print_range_(formatted, 0, formatted.size());
}
fflush(target_file_);
}
template<typename ConsoleMutex>
void ansicolor_sink<ConsoleMutex>::flush()
{
std::lock_guard<mutex_t> lock(mutex_);
fflush(target_file_);
}
template<typename ConsoleMutex>
void ansicolor_sink<ConsoleMutex>::set_pattern(const std::string &pattern)
{
std::lock_guard<mutex_t> lock(mutex_);
formatter_ = std::unique_ptr<spdlog::formatter>(new pattern_formatter(pattern));
}
template<typename ConsoleMutex>
void ansicolor_sink<ConsoleMutex>::set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter)
{
std::lock_guard<mutex_t> lock(mutex_);
formatter_ = std::move(sink_formatter);
}
template<typename ConsoleMutex>
bool ansicolor_sink<ConsoleMutex>::should_color()
{
return should_do_colors_;
}
template<typename ConsoleMutex>
void ansicolor_sink<ConsoleMutex>::set_color_mode(color_mode mode)
{
switch (mode)
{
case color_mode::always:
should_do_colors_ = true;
return;
case color_mode::automatic:
should_do_colors_ = details::os::in_terminal(target_file_) && details::os::is_color_terminal();
return;
case color_mode::never:
should_do_colors_ = false;
return;
default:
should_do_colors_ = false;
}
}
template<typename ConsoleMutex>
void ansicolor_sink<ConsoleMutex>::print_ccode_(const string_view_t &color_code)
{
fwrite(color_code.data(), sizeof(char), color_code.size(), target_file_);
}
template<typename ConsoleMutex>
void ansicolor_sink<ConsoleMutex>::print_range_(const memory_buf_t &formatted, size_t start, size_t end)
{
fwrite(formatted.data() + start, sizeof(char), end - start, target_file_);
}
template<typename ConsoleMutex>
std::string ansicolor_sink<ConsoleMutex>::to_string_(const string_view_t &sv)
{
return {sv.data(), sv.size()};
}
// ansicolor_stdout_sink
template<typename ConsoleMutex>
ansicolor_stdout_sink<ConsoleMutex>::ansicolor_stdout_sink(color_mode mode)
: ansicolor_sink<ConsoleMutex>(stdout, mode)
{}
// ansicolor_stderr_sink
template<typename ConsoleMutex>
ansicolor_stderr_sink<ConsoleMutex>::ansicolor_stderr_sink(color_mode mode)
: ansicolor_sink<ConsoleMutex>(stderr, mode)
{}
} // namespace sinks
} // namespace spdlog
// template instantiations
template SPDLOG_API class spdlog::sinks::ansicolor_stdout_sink<spdlog::details::console_mutex>;
template SPDLOG_API class spdlog::sinks::ansicolor_stdout_sink<spdlog::details::console_nullmutex>;
template SPDLOG_API class spdlog::sinks::ansicolor_stderr_sink<spdlog::details::console_mutex>;
template SPDLOG_API class spdlog::sinks::ansicolor_stderr_sink<spdlog::details::console_nullmutex>;

66
src/sinks/base_sink.cpp Normal file
View File

@@ -0,0 +1,66 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include <spdlog/sinks/base_sink.h>
#include <spdlog/common.h>
#include <spdlog/pattern_formatter.h>
#include <memory>
#include <mutex>
template<typename Mutex>
spdlog::sinks::base_sink<Mutex>::base_sink()
: formatter_{std::make_unique<spdlog::pattern_formatter>()}
{}
template<typename Mutex>
spdlog::sinks::base_sink<Mutex>::base_sink(std::unique_ptr<spdlog::formatter> formatter)
: formatter_{std::move(formatter)}
{}
template<typename Mutex>
void spdlog::sinks::base_sink<Mutex>::log(const details::log_msg &msg)
{
std::lock_guard<Mutex> lock(mutex_);
sink_it_(msg);
}
template<typename Mutex>
void spdlog::sinks::base_sink<Mutex>::flush()
{
std::lock_guard<Mutex> lock(mutex_);
flush_();
}
template<typename Mutex>
void spdlog::sinks::base_sink<Mutex>::set_pattern(const std::string &pattern)
{
std::lock_guard<Mutex> lock(mutex_);
set_pattern_(pattern);
}
template<typename Mutex>
void spdlog::sinks::base_sink<Mutex>::set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter)
{
std::lock_guard<Mutex> lock(mutex_);
set_formatter_(std::move(sink_formatter));
}
template<typename Mutex>
void spdlog::sinks::base_sink<Mutex>::set_pattern_(const std::string &pattern)
{
set_formatter_(std::make_unique<spdlog::pattern_formatter>(pattern));
}
template<typename Mutex>
void spdlog::sinks::base_sink<Mutex>::set_formatter_(std::unique_ptr<spdlog::formatter> sink_formatter)
{
formatter_ = std::move(sink_formatter);
}
// template instantiations
template class SPDLOG_API spdlog::sinks::base_sink<std::mutex>;
template class SPDLOG_API spdlog::sinks::base_sink<spdlog::details::null_mutex>;

View File

@@ -0,0 +1,44 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/common.h>
#include <spdlog/details/os.h>
namespace spdlog {
namespace sinks {
template<typename Mutex>
basic_file_sink<Mutex>::basic_file_sink(const filename_t &filename, bool truncate, const file_event_handlers &event_handlers)
: file_helper_{event_handlers}
{
file_helper_.open(filename, truncate);
}
template<typename Mutex>
const filename_t &basic_file_sink<Mutex>::filename() const
{
return file_helper_.filename();
}
template<typename Mutex>
void basic_file_sink<Mutex>::sink_it_(const details::log_msg &msg)
{
memory_buf_t formatted;
base_sink<Mutex>::formatter_->format(msg, formatted);
file_helper_.write(formatted);
}
template<typename Mutex>
void basic_file_sink<Mutex>::flush_()
{
file_helper_.flush();
}
} // namespace sinks
} // namespace spdlog
// template instantiations
template class SPDLOG_API spdlog::sinks::basic_file_sink<std::mutex>;
template class SPDLOG_API spdlog::sinks::basic_file_sink<spdlog::details::null_mutex>;

View File

@@ -9,7 +9,7 @@
// color sinks
//
#ifdef _WIN32
# include <spdlog/sinks/wincolor_sink-inl.h>
# include <spdlog/sinks/wincolor_sink.h>
template class SPDLOG_API spdlog::sinks::wincolor_sink<spdlog::details::console_mutex>;
template class SPDLOG_API spdlog::sinks::wincolor_sink<spdlog::details::console_nullmutex>;
template class SPDLOG_API spdlog::sinks::wincolor_stdout_sink<spdlog::details::console_mutex>;
@@ -17,7 +17,7 @@ template class SPDLOG_API spdlog::sinks::wincolor_stdout_sink<spdlog::details::c
template class SPDLOG_API spdlog::sinks::wincolor_stderr_sink<spdlog::details::console_mutex>;
template class SPDLOG_API spdlog::sinks::wincolor_stderr_sink<spdlog::details::console_nullmutex>;
#else
# include "spdlog/sinks/ansicolor_sink-inl.h"
# include <spdlog/sinks/ansicolor_sink.h>
template class SPDLOG_API spdlog::sinks::ansicolor_sink<spdlog::details::console_mutex>;
template class SPDLOG_API spdlog::sinks::ansicolor_sink<spdlog::details::console_nullmutex>;
template class SPDLOG_API spdlog::sinks::ansicolor_stdout_sink<spdlog::details::console_mutex>;
@@ -27,21 +27,21 @@ template class SPDLOG_API spdlog::sinks::ansicolor_stderr_sink<spdlog::details::
#endif
// factory methods for color loggers
#include "spdlog/sinks/stdout_color_sinks-inl.h"
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt<spdlog::synchronous_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_st<spdlog::synchronous_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt<spdlog::synchronous_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_st<spdlog::synchronous_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt<spdlog::async_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_st<spdlog::async_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt<spdlog::async_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_st<spdlog::async_factory>(
const std::string &logger_name, color_mode mode);
//#include <spdlog/sinks/stdout_color_sinks.h>
//template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt<spdlog::synchronous_factory>(
// const std::string &logger_name, color_mode mode);
//template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_st<spdlog::synchronous_factory>(
// const std::string &logger_name, color_mode mode);
//template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt<spdlog::synchronous_factory>(
// const std::string &logger_name, color_mode mode);
//template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_st<spdlog::synchronous_factory>(
// const std::string &logger_name, color_mode mode);
//
//template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt<spdlog::async_factory>(
// const std::string &logger_name, color_mode mode);
//template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_st<spdlog::async_factory>(
// const std::string &logger_name, color_mode mode);
//template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt<spdlog::async_factory>(
// const std::string &logger_name, color_mode mode);
//template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_st<spdlog::async_factory>(
// const std::string &logger_name, color_mode mode);

View File

@@ -1,16 +0,0 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include <spdlog/details/null_mutex.h>
#include <spdlog/details/file_helper-inl.h>
#include <spdlog/sinks/basic_file_sink-inl.h>
#include <spdlog/sinks/base_sink-inl.h>
#include <mutex>
template class SPDLOG_API spdlog::sinks::basic_file_sink<std::mutex>;
template class SPDLOG_API spdlog::sinks::basic_file_sink<spdlog::details::null_mutex>;
#include <spdlog/sinks/rotating_file_sink-inl.h>
template class SPDLOG_API spdlog::sinks::rotating_file_sink<std::mutex>;
template class SPDLOG_API spdlog::sinks::rotating_file_sink<spdlog::details::null_mutex>;

View File

@@ -0,0 +1,149 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/common.h>
#include <spdlog/details/file_helper.h>
#include <spdlog/details/os.h>
#include <spdlog/fmt/fmt.h>
#include <cerrno>
#include <mutex>
#include <string>
#include <tuple>
namespace spdlog {
namespace sinks {
template<typename Mutex>
rotating_file_sink<Mutex>::rotating_file_sink(
filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open, const file_event_handlers &event_handlers)
: base_filename_(std::move(base_filename))
, max_size_(max_size)
, max_files_(max_files)
, file_helper_{event_handlers}
{
if (max_size == 0)
{
throw_spdlog_ex("rotating sink constructor: max_size arg cannot be zero");
}
if (max_files > 200000)
{
throw_spdlog_ex("rotating sink constructor: max_files arg cannot exceed 200000");
}
file_helper_.open(calc_filename(base_filename_, 0));
current_size_ = file_helper_.size(); // expensive. called only once
if (rotate_on_open && current_size_ > 0)
{
rotate_();
current_size_ = 0;
}
}
// calc filename according to index and file extension if exists.
// e.g. calc_filename("logs/mylog.txt, 3) => "logs/mylog.3.txt".
template<typename Mutex>
filename_t rotating_file_sink<Mutex>::calc_filename(const filename_t &filename, std::size_t index)
{
if (index == 0u)
{
return filename;
}
filename_t basename, ext;
std::tie(basename, ext) = details::file_helper::split_by_extension(filename);
return fmt_lib::format(SPDLOG_FILENAME_T("{}.{}{}"), basename, index, ext);
}
template<typename Mutex>
filename_t rotating_file_sink<Mutex>::filename()
{
std::lock_guard<Mutex> lock(base_sink<Mutex>::mutex_);
return file_helper_.filename();
}
template<typename Mutex>
void rotating_file_sink<Mutex>::sink_it_(const details::log_msg &msg)
{
memory_buf_t formatted;
base_sink<Mutex>::formatter_->format(msg, formatted);
auto new_size = current_size_ + formatted.size();
// rotate if the new estimated file size exceeds max size.
// rotate only if the real size > 0 to better deal with full disk (see issue #2261).
// we only check the real size when new_size > max_size_ because it is relatively expensive.
if (new_size > max_size_)
{
file_helper_.flush();
if (file_helper_.size() > 0)
{
rotate_();
new_size = formatted.size();
}
}
file_helper_.write(formatted);
current_size_ = new_size;
}
template<typename Mutex>
void rotating_file_sink<Mutex>::flush_()
{
file_helper_.flush();
}
// Rotate files:
// log.txt -> log.1.txt
// log.1.txt -> log.2.txt
// log.2.txt -> log.3.txt
// log.3.txt -> delete
template<typename Mutex>
void rotating_file_sink<Mutex>::rotate_()
{
using details::os::filename_to_str;
using details::os::path_exists;
file_helper_.close();
for (auto i = max_files_; i > 0; --i)
{
filename_t src = calc_filename(base_filename_, i - 1);
if (!path_exists(src))
{
continue;
}
filename_t target = calc_filename(base_filename_, i);
if (!rename_file_(src, target))
{
// if failed try again after a small delay.
// this is a workaround to a windows issue, where very high rotation
// rates can cause the rename to fail with permission denied (because of antivirus?).
details::os::sleep_for_millis(100);
if (!rename_file_(src, target))
{
file_helper_.reopen(true); // truncate the log file anyway to prevent it to grow beyond its limit!
current_size_ = 0;
throw_spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), errno);
}
}
}
file_helper_.reopen(true);
}
// 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)
{
// try to delete the target file in case it already exists.
(void)details::os::remove(target_filename);
return details::os::rename(src_filename, target_filename) == 0;
}
} // namespace sinks
} // namespace spdlog
// template instantiations
template class SPDLOG_API spdlog::sinks::rotating_file_sink<std::mutex>;
template class SPDLOG_API spdlog::sinks::rotating_file_sink<spdlog::details::null_mutex>;

21
src/sinks/sink.cpp Normal file
View File

@@ -0,0 +1,21 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include <spdlog/sinks/sink.h>
#include <spdlog/common.h>
bool spdlog::sinks::sink::should_log(spdlog::level msg_level) const
{
return msg_level >= level_.load(std::memory_order_relaxed);
}
void spdlog::sinks::sink::set_level(level level)
{
level_.store(level, std::memory_order_relaxed);
}
spdlog::level spdlog::sinks::sink::log_level() const {
return static_cast<spdlog::level>(level_.load(std::memory_order_relaxed));
}

View File

@@ -0,0 +1,58 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/details/synchronous_factory.h>
#include <spdlog/async.h>
#include <spdlog/logger.h>
#include <spdlog/common.h>
namespace spdlog {
template<typename Factory>
std::shared_ptr<logger> stdout_color_mt(const std::string &logger_name, color_mode mode) {
return Factory::template create<sinks::stdout_color_sink_mt>(logger_name, mode);
}
template<typename Factory>
std::shared_ptr<logger> stdout_color_st(const std::string &logger_name, color_mode mode) {
return Factory::template create<sinks::stdout_color_sink_st>(logger_name, mode);
}
template<typename Factory>
std::shared_ptr<logger> stderr_color_mt(const std::string &logger_name, color_mode mode) {
return Factory::template create<sinks::stderr_color_sink_mt>(logger_name, mode);
}
template<typename Factory>
std::shared_ptr<logger> stderr_color_st(const std::string &logger_name, color_mode mode) {
return Factory::template create<sinks::stderr_color_sink_st>(logger_name, mode);
}
} // namespace spdlog
// template instantiations
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt<spdlog::synchronous_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_st<spdlog::synchronous_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt<spdlog::synchronous_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_st<spdlog::synchronous_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt<spdlog::async_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_color_st<spdlog::async_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt<spdlog::async_factory>(
const std::string &logger_name, color_mode mode);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_color_st<spdlog::async_factory>(
const std::string &logger_name, color_mode mode);

View File

@@ -1,12 +1,138 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include <mutex>
#include <spdlog/sinks/stdout_sinks.h>
#include <spdlog/pattern_formatter.h>
#include <memory>
#include <spdlog/details/null_mutex.h>
#include <spdlog/async.h>
#include <spdlog/sinks/stdout_sinks-inl.h>
#ifdef _WIN32
// under windows using fwrite to non-binary stream results in \r\r\n (see issue #1675)
// so instead we use ::FileWrite
# include <spdlog/details/windows_include.h>
# ifndef _USING_V110_SDK71_ // fileapi.h doesn't exist in winxp
# include <fileapi.h> // WriteFile (..)
# endif
# include <io.h> // _get_osfhandle(..)
# include <stdio.h> // _fileno(..)
#endif // WIN32
namespace spdlog {
namespace sinks {
template<typename ConsoleMutex>
stdout_sink_base<ConsoleMutex>::stdout_sink_base(FILE *file)
: mutex_(ConsoleMutex::mutex())
, file_(file)
, formatter_(std::make_unique<spdlog::pattern_formatter>())
{
#ifdef _WIN32
// get windows handle from the FILE* object
handle_ = reinterpret_cast<HANDLE>(::_get_osfhandle(::_fileno(file_)));
// don't throw to support cases where no console is attached,
// and let the log method to do nothing if (handle_ == INVALID_HANDLE_VALUE).
// throw only if non stdout/stderr target is requested (probably regular file and not console).
if (handle_ == INVALID_HANDLE_VALUE && file != stdout && file != stderr)
{
throw_spdlog_ex("spdlog::stdout_sink_base: _get_osfhandle() failed", errno);
}
#endif // WIN32
}
template<typename ConsoleMutex>
void stdout_sink_base<ConsoleMutex>::log(const details::log_msg &msg)
{
#ifdef _WIN32
if (handle_ == INVALID_HANDLE_VALUE)
{
return;
}
std::lock_guard<mutex_t> lock(mutex_);
memory_buf_t formatted;
formatter_->format(msg, formatted);
auto size = static_cast<DWORD>(formatted.size());
DWORD bytes_written = 0;
bool ok = ::WriteFile(handle_, formatted.data(), size, &bytes_written, nullptr) != 0;
if (!ok)
{
throw_spdlog_ex("stdout_sink_base: WriteFile() failed. GetLastError(): " + std::to_string(::GetLastError()));
}
#else
std::lock_guard<mutex_t> lock(mutex_);
memory_buf_t formatted;
formatter_->format(msg, formatted);
::fwrite(formatted.data(), sizeof(char), formatted.size(), file_);
#endif // WIN32
::fflush(file_); // flush every line to terminal
}
template<typename ConsoleMutex>
void stdout_sink_base<ConsoleMutex>::flush()
{
std::lock_guard<mutex_t> lock(mutex_);
fflush(file_);
}
template<typename ConsoleMutex>
void stdout_sink_base<ConsoleMutex>::set_pattern(const std::string &pattern)
{
std::lock_guard<mutex_t> lock(mutex_);
formatter_ = std::unique_ptr<spdlog::formatter>(new pattern_formatter(pattern));
}
template<typename ConsoleMutex>
void stdout_sink_base<ConsoleMutex>::set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter)
{
std::lock_guard<mutex_t> lock(mutex_);
formatter_ = std::move(sink_formatter);
}
// stdout sink
template<typename ConsoleMutex>
stdout_sink<ConsoleMutex>::stdout_sink()
: stdout_sink_base<ConsoleMutex>(stdout)
{}
// stderr sink
template<typename ConsoleMutex>
stderr_sink<ConsoleMutex>::stderr_sink()
: stdout_sink_base<ConsoleMutex>(stderr)
{}
} // namespace sinks
// factory methods
template<typename Factory>
std::shared_ptr<logger> stdout_logger_mt(const std::string &logger_name)
{
return Factory::template create<sinks::stdout_sink_mt>(logger_name);
}
template<typename Factory>
std::shared_ptr<logger> stdout_logger_st(const std::string &logger_name)
{
return Factory::template create<sinks::stdout_sink_st>(logger_name);
}
template<typename Factory>
std::shared_ptr<logger> stderr_logger_mt(const std::string &logger_name)
{
return Factory::template create<sinks::stderr_sink_mt>(logger_name);
}
template<typename Factory>
std::shared_ptr<logger> stderr_logger_st(const std::string &logger_name)
{
return Factory::template create<sinks::stderr_sink_st>(logger_name);
}
} // namespace spdlog
// template instantiations for stdout/stderr loggers
#include <spdlog/details/console_globals.h>
template class SPDLOG_API spdlog::sinks::stdout_sink_base<spdlog::details::console_mutex>;
template class SPDLOG_API spdlog::sinks::stdout_sink_base<spdlog::details::console_nullmutex>;
template class SPDLOG_API spdlog::sinks::stdout_sink<spdlog::details::console_mutex>;
@@ -14,6 +140,10 @@ template class SPDLOG_API spdlog::sinks::stdout_sink<spdlog::details::console_nu
template class SPDLOG_API spdlog::sinks::stderr_sink<spdlog::details::console_mutex>;
template class SPDLOG_API spdlog::sinks::stderr_sink<spdlog::details::console_nullmutex>;
// template instantiations for stdout/stderr factory functions
#include <spdlog/details/synchronous_factory.h>
#include <spdlog/async.h>
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_logger_mt<spdlog::synchronous_factory>(const std::string &logger_name);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_logger_st<spdlog::synchronous_factory>(const std::string &logger_name);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_logger_mt<spdlog::synchronous_factory>(const std::string &logger_name);
@@ -23,3 +153,5 @@ template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_logger_mt<spd
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stdout_logger_st<spdlog::async_factory>(const std::string &logger_name);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_logger_mt<spdlog::async_factory>(const std::string &logger_name);
template SPDLOG_API std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st<spdlog::async_factory>(const std::string &logger_name);

176
src/sinks/wincolor_sink.cpp Normal file
View File

@@ -0,0 +1,176 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#ifdef _WIN32
#pragma once
#include <spdlog/sinks/wincolor_sink.h>
#include <spdlog/details/windows_include.h>
#include <wincon.h>
#include <spdlog/common.h>
#include <spdlog/pattern_formatter.h>
namespace spdlog {
namespace sinks {
template<typename ConsoleMutex>
wincolor_sink<ConsoleMutex>::wincolor_sink(void *out_handle, color_mode mode)
: out_handle_(out_handle)
, mutex_(ConsoleMutex::mutex())
, formatter_(std::make_unique<spdlog::pattern_formatter>())
{
set_color_mode_impl(mode);
// set level colors
colors_.at(level_to_number(level::trace)) = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; // white
colors_.at(level_to_number(level::debug)) = FOREGROUND_GREEN | FOREGROUND_BLUE; // cyan
colors_.at(level_to_number(level::info)) = FOREGROUND_GREEN; // green
colors_.at(level_to_number(level::warn)) = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY; // intense yellow
colors_.at(level_to_number(level::err)) = FOREGROUND_RED | FOREGROUND_INTENSITY; // intense red
colors_.at(level_to_number(level::critical)) =
BACKGROUND_RED | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY; // intense white on red background
colors_.at(level_to_number(level::off)) = 0;
}
template<typename ConsoleMutex>
wincolor_sink<ConsoleMutex>::~wincolor_sink()
{
this->flush();
}
// change the color for the given level
template<typename ConsoleMutex>
void wincolor_sink<ConsoleMutex>::set_color(level level, std::uint16_t color)
{
std::lock_guard<mutex_t> lock(mutex_);
colors_[level_to_number(level)] = color;
}
template<typename ConsoleMutex>
void wincolor_sink<ConsoleMutex>::log(const details::log_msg &msg)
{
if (out_handle_ == nullptr || out_handle_ == INVALID_HANDLE_VALUE)
{
return;
}
std::lock_guard<mutex_t> lock(mutex_);
msg.color_range_start = 0;
msg.color_range_end = 0;
memory_buf_t formatted;
formatter_->format(msg, formatted);
if (should_do_colors_ && msg.color_range_end > msg.color_range_start)
{
// before color range
print_range_(formatted, 0, msg.color_range_start);
// in color range
auto orig_attribs = static_cast<WORD>(set_foreground_color_(colors_[static_cast<size_t>(msg.log_level)]));
print_range_(formatted, msg.color_range_start, msg.color_range_end);
// reset to orig colors
::SetConsoleTextAttribute(static_cast<HANDLE>(out_handle_), orig_attribs);
print_range_(formatted, msg.color_range_end, formatted.size());
}
else // print without colors if color range is invalid (or color is disabled)
{
write_to_file_(formatted);
}
}
template<typename ConsoleMutex>
void wincolor_sink<ConsoleMutex>::flush()
{
// windows console always flushed?
}
template<typename ConsoleMutex>
void wincolor_sink<ConsoleMutex>::set_pattern(const std::string &pattern)
{
std::lock_guard<mutex_t> lock(mutex_);
formatter_ = std::unique_ptr<spdlog::formatter>(new pattern_formatter(pattern));
}
template<typename ConsoleMutex>
void wincolor_sink<ConsoleMutex>::set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter)
{
std::lock_guard<mutex_t> lock(mutex_);
formatter_ = std::move(sink_formatter);
}
template<typename ConsoleMutex>
void wincolor_sink<ConsoleMutex>::set_color_mode(color_mode mode)
{
std::lock_guard<mutex_t> lock(mutex_);
set_color_mode_impl(mode);
}
template<typename ConsoleMutex>
void wincolor_sink<ConsoleMutex>::set_color_mode_impl(color_mode mode)
{
if (mode == color_mode::automatic)
{
// should do colors only if out_handle_ points to actual console.
DWORD console_mode;
bool in_console = ::GetConsoleMode(static_cast<HANDLE>(out_handle_), &console_mode) != 0;
should_do_colors_ = in_console;
}
else
{
should_do_colors_ = mode == color_mode::always ? true : false;
}
}
// set foreground color and return the orig console attributes (for resetting later)
template<typename ConsoleMutex>
std::uint16_t wincolor_sink<ConsoleMutex>::set_foreground_color_(std::uint16_t attribs)
{
CONSOLE_SCREEN_BUFFER_INFO orig_buffer_info;
if (!::GetConsoleScreenBufferInfo(static_cast<HANDLE>(out_handle_), &orig_buffer_info))
{
// just return white if failed getting console info
return FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
}
// change only the foreground bits (lowest 4 bits)
auto new_attribs = static_cast<WORD>(attribs) | (orig_buffer_info.wAttributes & 0xfff0);
auto ignored = ::SetConsoleTextAttribute(static_cast<HANDLE>(out_handle_), static_cast<WORD>(new_attribs));
(void)(ignored);
return static_cast<std::uint16_t>(orig_buffer_info.wAttributes); // return orig attribs
}
// print a range of formatted message to console
template<typename ConsoleMutex>
void wincolor_sink<ConsoleMutex>::print_range_(const memory_buf_t &formatted, size_t start, size_t end)
{
if (end > start)
{
auto size = static_cast<DWORD>(end - start);
auto ignored = ::WriteConsoleA(static_cast<HANDLE>(out_handle_), formatted.data() + start, size, nullptr, nullptr);
(void)(ignored);
}
}
template<typename ConsoleMutex>
void wincolor_sink<ConsoleMutex>::write_to_file_(const memory_buf_t &formatted)
{
auto size = static_cast<DWORD>(formatted.size());
DWORD bytes_written = 0;
auto ignored = ::WriteFile(static_cast<HANDLE>(out_handle_), formatted.data(), size, &bytes_written, nullptr);
(void)(ignored);
}
// wincolor_stdout_sink
template<typename ConsoleMutex>
wincolor_stdout_sink<ConsoleMutex>::wincolor_stdout_sink(color_mode mode)
: wincolor_sink<ConsoleMutex>(::GetStdHandle(STD_OUTPUT_HANDLE), mode)
{}
// wincolor_stderr_sink
template<typename ConsoleMutex>
wincolor_stderr_sink<ConsoleMutex>::wincolor_stderr_sink(color_mode mode)
: wincolor_sink<ConsoleMutex>(::GetStdHandle(STD_ERROR_HANDLE), mode)
{}
} // namespace sinks
} // namespace spdlog
#endif // _WIN32

View File

@@ -1,21 +1,105 @@
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#include <spdlog/spdlog-inl.h>
#include <spdlog/common-inl.h>
#include <spdlog/details/registry-inl.h>
#include <spdlog/details/os-inl.h>
#include <spdlog/pattern_formatter-inl.h>
#include <spdlog/details/log_msg-inl.h>
#include <spdlog/details/log_msg_buffer-inl.h>
#include <spdlog/logger-inl.h>
#include <spdlog/sinks/sink-inl.h>
#include <spdlog/sinks/base_sink-inl.h>
#include <spdlog/details/null_mutex.h>
#include <spdlog/spdlog.h>
#include <spdlog/common.h>
#include <spdlog/pattern_formatter.h>
#include <mutex>
namespace spdlog {
// template instantiate logger constructor with sinks init list
template SPDLOG_API spdlog::logger::logger(std::string name, sinks_init_list::iterator begin, sinks_init_list::iterator end);
template class SPDLOG_API spdlog::sinks::base_sink<std::mutex>;
template class SPDLOG_API spdlog::sinks::base_sink<spdlog::details::null_mutex>;
void initialize_logger(std::shared_ptr<logger> logger)
{
details::registry::instance().initialize_logger(std::move(logger));
}
std::shared_ptr<logger> get(const std::string &name)
{
return details::registry::instance().get(name);
}
void set_formatter(std::unique_ptr<spdlog::formatter> formatter)
{
details::registry::instance().set_formatter(std::move(formatter));
}
void set_pattern(std::string pattern, pattern_time_type time_type)
{
set_formatter(std::unique_ptr<spdlog::formatter>(new pattern_formatter(std::move(pattern), time_type)));
}
level get_level()
{
return default_logger_raw()->log_level();
}
bool should_log(level level)
{
return default_logger_raw()->should_log(level);
}
void set_level(level level)
{
details::registry::instance().set_level(level);
}
void flush_on(level level)
{
details::registry::instance().flush_on(level);
}
void set_error_handler(void (*handler)(const std::string &msg))
{
details::registry::instance().set_error_handler(handler);
}
void register_logger(std::shared_ptr<logger> logger)
{
details::registry::instance().register_logger(std::move(logger));
}
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