mirror of
https://github.com/gabime/spdlog.git
synced 2024-12-25 01:51:38 +08:00
static lib wip
This commit is contained in:
parent
156b856a80
commit
17f9cdd401
@ -14,8 +14,9 @@ spdlog::logger *get_logger();
|
||||
int main(int, char *[])
|
||||
{
|
||||
auto *l = get_logger();
|
||||
l->info("HELLO {}", "GA");
|
||||
l->error("Some {}", "error");
|
||||
l->info("HE LO ", "GA");
|
||||
l->error("Some {} {} {}", "er or");
|
||||
l->error("Some {} {} {}", "er or");
|
||||
|
||||
|
||||
}
|
@ -9,22 +9,16 @@
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
|
||||
#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT)
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
#endif
|
||||
|
||||
#include "spdlog/details/null_mutex.h"
|
||||
|
||||
#include "spdlog/fmt/fmt.h"
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
@ -75,6 +69,17 @@
|
||||
#define SPDLOG_FUNCTION __FUNCTION__
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
|
||||
#define SPDLOG_FILENAME_T(s) L##s
|
||||
SPDLOG_INLINE std::string filename_to_str(const filename_t &filename)
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> c;
|
||||
return c.to_bytes(filename);
|
||||
}
|
||||
#else
|
||||
#define SPDLOG_FILENAME_T(s) s
|
||||
#endif
|
||||
|
||||
namespace spdlog {
|
||||
|
||||
class formatter;
|
||||
@ -86,7 +91,6 @@ class sink;
|
||||
using log_clock = std::chrono::system_clock;
|
||||
using sink_ptr = std::shared_ptr<sinks::sink>;
|
||||
using sinks_init_list = std::initializer_list<sink_ptr>;
|
||||
using log_err_handler = std::function<void(const std::string &err_msg)>;
|
||||
|
||||
// string_view type - either std::string_view or fmt::string_view (pre c++17)
|
||||
#if defined(FMT_USE_STD_STRING_VIEW)
|
||||
|
@ -38,9 +38,6 @@ inline spdlog::async_logger::async_logger(
|
||||
// send the log message to the thread pool
|
||||
inline void spdlog::async_logger::sink_it_(details::log_msg &msg)
|
||||
{
|
||||
#if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)
|
||||
incr_msg_counter_(msg);
|
||||
#endif
|
||||
if (auto pool_ptr = thread_pool_.lock())
|
||||
{
|
||||
pool_ptr->post_log(shared_from_this(), msg, overflow_policy_);
|
||||
@ -119,6 +116,6 @@ inline std::shared_ptr<spdlog::logger> spdlog::async_logger::clone(std::string n
|
||||
|
||||
cloned->set_level(this->level());
|
||||
cloned->flush_on(this->flush_level());
|
||||
cloned->set_error_handler(this->error_handler());
|
||||
cloned->set_error_handler(this->custom_err_handler_);
|
||||
return std::move(cloned);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -154,7 +154,7 @@ public:
|
||||
periodic_flusher_ = details::make_unique<periodic_worker>(clbk, interval);
|
||||
}
|
||||
|
||||
void set_error_handler(log_err_handler handler)
|
||||
void set_error_handler(void (*handler)(const std::string &msg))
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
for (auto &l : loggers_)
|
||||
@ -275,7 +275,7 @@ private:
|
||||
std::unique_ptr<formatter> formatter_;
|
||||
level::level_enum level_ = spdlog::logger::default_level();
|
||||
level::level_enum flush_level_ = level::off;
|
||||
log_err_handler err_handler_;
|
||||
void (*err_handler_)(const std::string &msg);
|
||||
std::shared_ptr<thread_pool> tp_;
|
||||
std::unique_ptr<periodic_worker> periodic_flusher_;
|
||||
std::shared_ptr<logger> default_logger_;
|
||||
|
@ -17,26 +17,21 @@
|
||||
// The use of private formatter per sink provides the opportunity to cache some
|
||||
// formatted data, and support for different format per sink.
|
||||
|
||||
|
||||
#include "spdlog/common.h"
|
||||
#include "spdlog/details/log_msg.h"
|
||||
|
||||
//#include "spdlog/formatter.h"
|
||||
//#include "spdlog/sinks/sink.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace spdlog
|
||||
namespace spdlog {
|
||||
class logger
|
||||
{
|
||||
class logger
|
||||
{
|
||||
public:
|
||||
public:
|
||||
template<typename It>
|
||||
logger(std::string name, It begin, It end)
|
||||
: name_(std::move(name))
|
||||
, sinks_(begin, end)
|
||||
, sinks_(begin, end)
|
||||
{
|
||||
}
|
||||
|
||||
@ -57,32 +52,32 @@ namespace spdlog
|
||||
template<typename... Args>
|
||||
void log(source_loc loc, level::level_enum lvl, const char *fmt, const Args &... args)
|
||||
{
|
||||
if (!should_log(lvl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!should_log(lvl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
fmt::memory_buffer buf;
|
||||
fmt::format_to(buf, fmt, args...);
|
||||
details::log_msg log_msg(loc, &name_, lvl, string_view_t(buf.data(), buf.size()));
|
||||
sink_it_(log_msg);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
err_handler_(ex.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
err_handler_("Unknown exception in logger");
|
||||
}
|
||||
try
|
||||
{
|
||||
fmt::memory_buffer buf;
|
||||
fmt::format_to(buf, fmt, args...);
|
||||
details::log_msg log_msg(loc, &name_, lvl, string_view_t(buf.data(), buf.size()));
|
||||
sink_it_(log_msg);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
err_handler_(ex.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
err_handler_("Unknown exception in logger");
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void log(level::level_enum lvl, const char *fmt, const Args &... args)
|
||||
{
|
||||
log(source_loc{}, lvl, fmt, args...);
|
||||
log(source_loc{}, lvl, fmt, args...);
|
||||
}
|
||||
void log(source_loc loc, level::level_enum lvl, const char *msg);
|
||||
void log(level::level_enum lvl, const char *msg);
|
||||
@ -90,37 +85,37 @@ namespace spdlog
|
||||
template<typename... Args>
|
||||
void trace(const char *fmt, const Args &... args)
|
||||
{
|
||||
log(level::trace, fmt, args...);
|
||||
log(level::trace, fmt, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void debug(const char *fmt, const Args &... args)
|
||||
{
|
||||
log(level::debug, fmt, args...);
|
||||
log(level::debug, fmt, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void info(const char *fmt, const Args &... args)
|
||||
{
|
||||
log(level::info, fmt, args...);
|
||||
log(level::info, fmt, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void warn(const char *fmt, const Args &... args)
|
||||
{
|
||||
log(level::warn, fmt, args...);
|
||||
log(level::warn, fmt, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void error(const char *fmt, const Args &... args)
|
||||
{
|
||||
log(level::err, fmt, args...);
|
||||
log(level::err, fmt, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void critical(const char *fmt, const Args &... args)
|
||||
{
|
||||
log(level::critical, fmt, args...);
|
||||
log(level::critical, fmt, args...);
|
||||
}
|
||||
|
||||
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||
@ -129,87 +124,87 @@ namespace spdlog
|
||||
#else
|
||||
inline void wbuf_to_utf8buf(const fmt::wmemory_buffer &wbuf, fmt::memory_buffer &target)
|
||||
{
|
||||
int wbuf_size = static_cast<int>(wbuf.size());
|
||||
if (wbuf_size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int wbuf_size = static_cast<int>(wbuf.size());
|
||||
if (wbuf_size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto result_size = ::WideCharToMultiByte(CP_UTF8, 0, wbuf.data(), wbuf_size, NULL, 0, NULL, NULL);
|
||||
auto result_size = ::WideCharToMultiByte(CP_UTF8, 0, wbuf.data(), wbuf_size, NULL, 0, NULL, NULL);
|
||||
|
||||
if (result_size > 0)
|
||||
{
|
||||
target.resize(result_size);
|
||||
::WideCharToMultiByte(CP_UTF8, 0, wbuf.data(), wbuf_size, &target.data()[0], result_size, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw spdlog::spdlog_ex(fmt::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError()));
|
||||
}
|
||||
if (result_size > 0)
|
||||
{
|
||||
target.resize(result_size);
|
||||
::WideCharToMultiByte(CP_UTF8, 0, wbuf.data(), wbuf_size, &target.data()[0], result_size, NULL, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw spdlog::spdlog_ex(fmt::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError()));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void log(source_loc source, level::level_enum lvl, const wchar_t *fmt, const Args &... args)
|
||||
{
|
||||
if (!should_log(lvl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!should_log(lvl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// format to wmemory_buffer and convert to utf8
|
||||
using details::fmt_helper::to_string_view;
|
||||
fmt::wmemory_buffer wbuf;
|
||||
fmt::format_to(wbuf, fmt, args...);
|
||||
fmt::memory_buffer buf;
|
||||
wbuf_to_utf8buf(wbuf, buf);
|
||||
details::log_msg log_msg(source, &name_, lvl, to_string_view(buf));
|
||||
sink_it_(log_msg);
|
||||
}
|
||||
SPDLOG_CATCH_AND_HANDLE
|
||||
try
|
||||
{
|
||||
// format to wmemory_buffer and convert to utf8
|
||||
using details::fmt_helper::to_string_view;
|
||||
fmt::wmemory_buffer wbuf;
|
||||
fmt::format_to(wbuf, fmt, args...);
|
||||
fmt::memory_buffer buf;
|
||||
wbuf_to_utf8buf(wbuf, buf);
|
||||
details::log_msg log_msg(source, &name_, lvl, to_string_view(buf));
|
||||
sink_it_(log_msg);
|
||||
}
|
||||
SPDLOG_CATCH_AND_HANDLE
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void log(level::level_enum lvl, const wchar_t *fmt, const Args &... args)
|
||||
{
|
||||
log(source_loc{}, lvl, fmt, args...);
|
||||
log(source_loc{}, lvl, fmt, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void trace(const wchar_t *fmt, const Args &... args)
|
||||
{
|
||||
log(level::trace, fmt, args...);
|
||||
log(level::trace, fmt, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void debug(const wchar_t *fmt, const Args &... args)
|
||||
{
|
||||
log(level::debug, fmt, args...);
|
||||
log(level::debug, fmt, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void info(const wchar_t *fmt, const Args &... args)
|
||||
{
|
||||
log(level::info, fmt, args...);
|
||||
log(level::info, fmt, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void warn(const wchar_t *fmt, const Args &... args)
|
||||
{
|
||||
log(level::warn, fmt, args...);
|
||||
log(level::warn, fmt, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void error(const wchar_t *fmt, const Args &... args)
|
||||
{
|
||||
log(level::err, fmt, args...);
|
||||
log(level::err, fmt, args...);
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void critical(const wchar_t *fmt, const Args &... args)
|
||||
{
|
||||
log(level::critical, fmt, args...);
|
||||
log(level::critical, fmt, args...);
|
||||
}
|
||||
#endif // _WIN32
|
||||
#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||
@ -217,92 +212,92 @@ namespace spdlog
|
||||
template<typename T>
|
||||
void log(level::level_enum lvl, const T &msg)
|
||||
{
|
||||
log(source_loc{}, lvl, msg);
|
||||
log(source_loc{}, lvl, msg);
|
||||
}
|
||||
|
||||
// T can be statically converted to string_view
|
||||
template<class T, typename std::enable_if<std::is_convertible<T, spdlog::string_view_t>::value, T>::type * = nullptr>
|
||||
void log(source_loc loc, level::level_enum lvl, const T &msg)
|
||||
{
|
||||
if (!should_log(lvl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
details::log_msg log_msg(loc, &name_, lvl, msg);
|
||||
sink_it_(log_msg);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
err_handler_(ex.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
err_handler_("Unknown exception in logger");
|
||||
}
|
||||
if (!should_log(lvl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
details::log_msg log_msg(loc, &name_, lvl, msg);
|
||||
sink_it_(log_msg);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
err_handler_(ex.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
err_handler_("Unknown exception in logger");
|
||||
}
|
||||
}
|
||||
|
||||
// T cannot be statically converted to string_view
|
||||
template<class T, typename std::enable_if<!std::is_convertible<T, spdlog::string_view_t>::value, T>::type * = nullptr>
|
||||
void log(source_loc loc, level::level_enum lvl, const T &msg)
|
||||
{
|
||||
if (!should_log(lvl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
using details::fmt_helper::to_string_view;
|
||||
fmt::memory_buffer buf;
|
||||
fmt::format_to(buf, "{}", msg);
|
||||
details::log_msg log_msg(loc, &name_, lvl, to_string_view(buf));
|
||||
sink_it_(log_msg);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
err_handler_(ex.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
err_handler_("Unknown exception in logger");
|
||||
}
|
||||
if (!should_log(lvl))
|
||||
{
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
using details::fmt_helper::to_string_view;
|
||||
fmt::memory_buffer buf;
|
||||
fmt::format_to(buf, "{}", msg);
|
||||
details::log_msg log_msg(loc, &name_, lvl, to_string_view(buf));
|
||||
sink_it_(log_msg);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
err_handler_(ex.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
err_handler_("Unknown exception in logger");
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void trace(const T &msg)
|
||||
{
|
||||
log(level::trace, msg);
|
||||
log(level::trace, msg);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void debug(const T &msg)
|
||||
{
|
||||
log(level::debug, msg);
|
||||
log(level::debug, msg);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void info(const T &msg)
|
||||
{
|
||||
log(level::info, msg);
|
||||
log(level::info, msg);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void warn(const T &msg)
|
||||
{
|
||||
log(level::warn, msg);
|
||||
log(level::warn, msg);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void error(const T &msg)
|
||||
{
|
||||
log(level::err, msg);
|
||||
log(level::err, msg);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void critical(const T &msg)
|
||||
{
|
||||
log(level::critical, msg);
|
||||
log(level::critical, msg);
|
||||
}
|
||||
|
||||
bool should_log(level::level_enum msg_level) const;
|
||||
@ -332,10 +327,8 @@ namespace spdlog
|
||||
std::vector<sink_ptr> &sinks();
|
||||
|
||||
// error handler
|
||||
void set_error_handler(log_err_handler err_handler);
|
||||
|
||||
log_err_handler error_handler() const;
|
||||
|
||||
void set_error_handler(void (*handler)(const std::string& msg));
|
||||
|
||||
// create new logger with same sinks and configuration.
|
||||
virtual std::shared_ptr<logger> clone(std::string logger_name);
|
||||
|
||||
@ -347,7 +340,7 @@ namespace spdlog
|
||||
|
||||
// default error handler.
|
||||
// print the error to stderr with the max rate of 1 message/minute.
|
||||
void default_err_handler_(const std::string &msg);
|
||||
void err_handler_(const std::string &msg);
|
||||
|
||||
// increment the message count (only if defined(SPDLOG_ENABLE_MESSAGE_COUNTER))
|
||||
void incr_msg_counter_(details::log_msg &msg);
|
||||
@ -356,10 +349,8 @@ namespace spdlog
|
||||
std::vector<sink_ptr> sinks_;
|
||||
spdlog::level_t level_{spdlog::logger::default_level()};
|
||||
spdlog::level_t flush_level_{level::off};
|
||||
log_err_handler err_handler_{[this](const std::string &msg) { this->default_err_handler_(msg); }};
|
||||
std::atomic<time_t> last_err_time_{0};
|
||||
std::atomic<size_t> msg_counter_{1};
|
||||
};
|
||||
void (*custom_err_handler_)(const std::string &msg) {nullptr};
|
||||
};
|
||||
} // namespace spdlog
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
|
@ -103,9 +103,9 @@ inline void flush_every(std::chrono::seconds interval)
|
||||
}
|
||||
|
||||
// Set global error handler
|
||||
inline void set_error_handler(log_err_handler handler)
|
||||
inline void set_error_handler(void (*handler)(const std::string &msg))
|
||||
{
|
||||
details::registry::instance().set_error_handler(std::move(handler));
|
||||
details::registry::instance().set_error_handler(handler);
|
||||
}
|
||||
|
||||
// Register the given logger with the given name
|
||||
|
@ -107,13 +107,6 @@
|
||||
// #define SPDLOG_PREVENT_CHILD_FD
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to enable message counting feature.
|
||||
// Use the %i in the logger pattern to display log message sequence id.
|
||||
//
|
||||
// #define SPDLOG_ENABLE_MESSAGE_COUNTER
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Uncomment to customize level names (e.g. "MT TRACE")
|
||||
//
|
||||
|
@ -113,14 +113,9 @@ SPDLOG_INLINE std::vector<spdlog::sink_ptr> &spdlog::logger::sinks()
|
||||
}
|
||||
|
||||
// error handler
|
||||
SPDLOG_INLINE void spdlog::logger::set_error_handler(spdlog::log_err_handler err_handler)
|
||||
SPDLOG_INLINE void spdlog::logger::set_error_handler(void (*handler)(const std::string &msg))
|
||||
{
|
||||
err_handler_ = std::move(err_handler);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE spdlog::log_err_handler spdlog::logger::error_handler() const
|
||||
{
|
||||
return err_handler_;
|
||||
custom_err_handler_ = handler;
|
||||
}
|
||||
|
||||
// create new logger with same sinks and configuration.
|
||||
@ -129,16 +124,13 @@ SPDLOG_INLINE std::shared_ptr<spdlog::logger> spdlog::logger::clone(std::string
|
||||
auto cloned = std::make_shared<spdlog::logger>(std::move(logger_name), sinks_.begin(), sinks_.end());
|
||||
cloned->set_level(this->level());
|
||||
cloned->flush_on(this->flush_level());
|
||||
cloned->set_error_handler(this->error_handler());
|
||||
cloned->set_error_handler(this->custom_err_handler_);
|
||||
return cloned;
|
||||
}
|
||||
|
||||
// protected methods
|
||||
SPDLOG_INLINE void spdlog::logger::sink_it_(spdlog::details::log_msg &msg)
|
||||
{
|
||||
#if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)
|
||||
incr_msg_counter_(msg);
|
||||
#endif
|
||||
for (auto &sink : sinks_)
|
||||
{
|
||||
if (sink->should_log(msg.level))
|
||||
@ -167,21 +159,17 @@ SPDLOG_INLINE bool spdlog::logger::should_flush_(const spdlog::details::log_msg
|
||||
return (msg.level >= flush_level) && (msg.level != level::off);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void spdlog::logger::default_err_handler_(const std::string &msg)
|
||||
{
|
||||
auto now = time(nullptr);
|
||||
if (now - last_err_time_ < 60)
|
||||
void spdlog::logger::err_handler_(const std::string &msg)
|
||||
{
|
||||
if (custom_err_handler_)
|
||||
{
|
||||
custom_err_handler_(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
auto tm_time = spdlog::details::os::localtime();
|
||||
char date_buf[64];
|
||||
std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time);
|
||||
fmt::print(stderr, "[*** LOG ERROR ***] [{}] [{}] {}\n", date_buf, name(), msg);
|
||||
}
|
||||
last_err_time_ = now;
|
||||
auto tm_time = details::os::localtime(now);
|
||||
char date_buf[100];
|
||||
std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time);
|
||||
fmt::print(stderr, "[*** LOG ERROR ***] [{}] [{}] {}\n", date_buf, name(), msg);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void spdlog::logger::incr_msg_counter_(spdlog::details::log_msg &msg)
|
||||
{
|
||||
msg.msg_id = msg_counter_.fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
}
|
@ -344,14 +344,12 @@ SPDLOG_INLINE void sleep_for_millis(int milliseconds) SPDLOG_NOEXCEPT
|
||||
|
||||
// wchar support for windows file names (SPDLOG_WCHAR_FILENAMES must be defined)
|
||||
#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
|
||||
#define SPDLOG_FILENAME_T(s) L##s
|
||||
SPDLOG_INLINE std::string filename_to_str(const filename_t &filename)
|
||||
{
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> c;
|
||||
return c.to_bytes(filename);
|
||||
}
|
||||
#else
|
||||
#define SPDLOG_FILENAME_T(s) s
|
||||
SPDLOG_INLINE std::string filename_to_str(const filename_t &filename)
|
||||
{
|
||||
return filename;
|
||||
|
1266
src/pattern_formatter.cpp
Normal file
1266
src/pattern_formatter.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,6 @@
|
||||
#include <string>
|
||||
|
||||
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG
|
||||
#define SPDLOG_ENABLE_MESSAGE_COUNTER
|
||||
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "spdlog/async.h"
|
||||
|
@ -41,13 +41,18 @@ TEST_CASE("default_error_handler", "[errors]]")
|
||||
struct custom_ex
|
||||
{
|
||||
};
|
||||
|
||||
static void custom_handler(const std::string &msg)
|
||||
{
|
||||
throw custom_ex();
|
||||
}
|
||||
TEST_CASE("custom_error_handler", "[errors]]")
|
||||
{
|
||||
prepare_logdir();
|
||||
std::string filename = "logs/simple_log.txt";
|
||||
auto logger = spdlog::create<spdlog::sinks::basic_file_sink_mt>("logger", filename, true);
|
||||
logger->flush_on(spdlog::level::info);
|
||||
logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
|
||||
logger->set_error_handler(custom_handler);
|
||||
logger->info("Good message #1");
|
||||
|
||||
REQUIRE_THROWS_AS(logger->info("Bad format msg {} {}", "xxx"), custom_ex);
|
||||
@ -59,7 +64,7 @@ TEST_CASE("default_error_handler2", "[errors]]")
|
||||
{
|
||||
spdlog::drop_all();
|
||||
auto logger = spdlog::create<failing_sink>("failed_logger");
|
||||
logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
|
||||
logger->set_error_handler(custom_handler);
|
||||
REQUIRE_THROWS_AS(logger->info("Some message"), custom_ex);
|
||||
}
|
||||
|
||||
@ -67,26 +72,26 @@ TEST_CASE("flush_error_handler", "[errors]]")
|
||||
{
|
||||
spdlog::drop_all();
|
||||
auto logger = spdlog::create<failing_sink>("failed_logger");
|
||||
logger->set_error_handler([=](const std::string &) { throw custom_ex(); });
|
||||
logger->set_error_handler(custom_handler);
|
||||
REQUIRE_THROWS_AS(logger->flush(), custom_ex);
|
||||
}
|
||||
|
||||
TEST_CASE("async_error_handler", "[errors]]")
|
||||
{
|
||||
prepare_logdir();
|
||||
std::string err_msg("log failed with some msg");
|
||||
|
||||
|
||||
std::string filename = "logs/simple_async_log.txt";
|
||||
{
|
||||
spdlog::init_thread_pool(128, 1);
|
||||
auto logger = spdlog::create_async<spdlog::sinks::basic_file_sink_mt>("logger", filename, true);
|
||||
logger->set_error_handler([=](const std::string &) {
|
||||
logger->set_error_handler([](const std::string &) {
|
||||
std::ofstream ofs("logs/custom_err.txt");
|
||||
if (!ofs)
|
||||
{
|
||||
throw std::runtime_error("Failed open logs/custom_err.txt");
|
||||
}
|
||||
ofs << err_msg;
|
||||
ofs << "log failed with some msg";
|
||||
});
|
||||
logger->info("Good message #1");
|
||||
logger->info("Bad format msg {} {}", "xxx");
|
||||
@ -95,27 +100,26 @@ TEST_CASE("async_error_handler", "[errors]]")
|
||||
}
|
||||
spdlog::init_thread_pool(128, 1);
|
||||
REQUIRE(count_lines(filename) == 2);
|
||||
REQUIRE(file_contents("logs/custom_err.txt") == err_msg);
|
||||
REQUIRE(file_contents("logs/custom_err.txt") == "log failed with some msg");
|
||||
}
|
||||
|
||||
// Make sure async error handler is executed
|
||||
TEST_CASE("async_error_handler2", "[errors]]")
|
||||
{
|
||||
prepare_logdir();
|
||||
std::string err_msg("This is async handler error message");
|
||||
prepare_logdir();
|
||||
{
|
||||
spdlog::init_thread_pool(128, 1);
|
||||
auto logger = spdlog::create_async<failing_sink>("failed_logger");
|
||||
logger->set_error_handler([=](const std::string &) {
|
||||
logger->set_error_handler([](const std::string &) {
|
||||
std::ofstream ofs("logs/custom_err2.txt");
|
||||
if (!ofs)
|
||||
throw std::runtime_error("Failed open logs/custom_err2.txt");
|
||||
ofs << err_msg;
|
||||
ofs << "handler error message";
|
||||
});
|
||||
logger->info("Hello failure");
|
||||
spdlog::drop("failed_logger"); // force logger to drain the queue and shutdown
|
||||
}
|
||||
|
||||
spdlog::init_thread_pool(128, 1);
|
||||
REQUIRE(file_contents("logs/custom_err2.txt") == err_msg);
|
||||
REQUIRE(file_contents("logs/custom_err2.txt") == "handler error message");
|
||||
}
|
||||
|
@ -107,8 +107,7 @@ TEST_CASE("clone-logger", "[clone]")
|
||||
cloned->info("Some message 2");
|
||||
|
||||
auto test_sink = std::static_pointer_cast<sinks::test_sink_mt>(cloned->sinks()[0]);
|
||||
REQUIRE(test_sink->msg_counter() == 2);
|
||||
|
||||
|
||||
spdlog::drop_all();
|
||||
}
|
||||
|
||||
@ -129,8 +128,7 @@ TEST_CASE("clone async", "[clone]")
|
||||
|
||||
spdlog::details::os::sleep_for_millis(10);
|
||||
|
||||
auto test_sink = std::static_pointer_cast<sinks::test_sink_mt>(cloned->sinks()[0]);
|
||||
REQUIRE(test_sink->msg_counter() == 2);
|
||||
auto test_sink = std::static_pointer_cast<sinks::test_sink_mt>(cloned->sinks()[0]);
|
||||
|
||||
spdlog::drop_all();
|
||||
}
|
||||
@ -176,22 +174,6 @@ TEST_CASE("to_hex_no_delimiter", "[to_hex]")
|
||||
REQUIRE(ends_with(output, "0000: 090A0B0CFFFF" + std::string(spdlog::details::os::default_eol)));
|
||||
}
|
||||
|
||||
TEST_CASE("message_counter", "[message_counter]")
|
||||
{
|
||||
std::ostringstream oss;
|
||||
auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss);
|
||||
spdlog::logger oss_logger("oss", oss_sink);
|
||||
oss_logger.set_pattern("%i %v");
|
||||
|
||||
oss_logger.info("Hello");
|
||||
REQUIRE(oss.str() == "000001 Hello" + std::string(spdlog::details::os::default_eol));
|
||||
|
||||
oss.str("");
|
||||
oss_logger.info("Hello again");
|
||||
|
||||
REQUIRE(oss.str() == "000002 Hello again" + std::string(spdlog::details::os::default_eol));
|
||||
}
|
||||
|
||||
TEST_CASE("default logger API", "[default logger]")
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
Loading…
Reference in New Issue
Block a user