spdlog/include/spdlog/logger.h

380 lines
11 KiB
C
Raw Normal View History

2019-06-04 05:09:16 +08:00
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
2016-09-02 22:06:00 +08:00
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
2019-10-01 06:50:18 +08:00
// Thread safe logger (except for set_error_handler())
2016-09-02 22:06:00 +08:00
// Has name, log level, vector of std::shared sink pointers and formatter
// Upon each log write the logger:
2018-06-24 06:32:39 +08:00
// 1. Checks if its log level is enough to log the message and if yes:
// 2. Call the underlying sinks to do the job.
2018-07-22 04:48:07 +08:00
// 3. Each sink use its own private copy of a formatter to format the message
// and send to its destination.
2018-06-24 06:32:39 +08:00
//
2018-07-22 04:48:07 +08:00
// The use of private formatter per sink provides the opportunity to cache some
2019-04-05 21:44:17 +08:00
// formatted data, and support for different format per sink.
#include <spdlog/common.h>
#include <spdlog/details/log_msg.h>
#include <spdlog/details/backtracer.h>
2019-04-05 21:44:17 +08:00
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
#include <spdlog/details/os.h>
#endif
2018-03-09 21:26:33 +08:00
#include <vector>
#ifndef SPDLOG_NO_EXCEPTIONS
2019-07-18 19:26:36 +08:00
#define SPDLOG_LOGGER_CATCH() \
catch (const std::exception &ex) \
{ \
err_handler_(ex.what()); \
} \
catch (...) \
{ \
err_handler_("Unknown exception in logger"); \
}
#else
#define SPDLOG_LOGGER_CATCH()
#endif
2019-04-06 04:05:46 +08:00
namespace spdlog {
2019-08-27 00:59:16 +08:00
2020-03-10 03:02:16 +08:00
class SPDLOG_API logger
2016-09-02 22:06:00 +08:00
{
2019-04-06 04:05:46 +08:00
public:
// Empty logger
2019-06-04 05:09:16 +08:00
explicit logger(std::string name)
: name_(std::move(name))
, sinks_()
2019-06-04 03:49:21 +08:00
{}
// Logger with range on sinks
2019-04-27 07:34:50 +08:00
template<typename It>
logger(std::string name, It begin, It end)
: name_(std::move(name))
, sinks_(begin, end)
{}
2019-04-27 07:34:50 +08:00
// Logger with single sink
2019-04-27 07:34:50 +08:00
logger(std::string name, sink_ptr single_sink)
2019-08-29 04:53:00 +08:00
: logger(std::move(name), {std::move(single_sink)})
{}
// Logger with sinks init list
2019-04-27 07:34:50 +08:00
logger(std::string name, sinks_init_list sinks)
: logger(std::move(name), sinks.begin(), sinks.end())
{}
2019-04-27 07:34:50 +08:00
virtual ~logger() = default;
logger(const logger &other);
logger(logger &&other) SPDLOG_NOEXCEPT;
logger &operator=(logger other) SPDLOG_NOEXCEPT;
void swap(spdlog::logger &other) SPDLOG_NOEXCEPT;
2019-04-27 07:34:50 +08:00
template<typename... Args>
void log(source_loc loc, level::level_enum lvl, string_view_t fmt, const Args &... args)
2019-04-27 07:34:50 +08:00
{
2019-11-03 23:00:12 +08:00
bool log_enabled = should_log(lvl);
bool traceback_enabled = tracer_.enabled();
if (!log_enabled && !traceback_enabled)
{
return;
}
SPDLOG_TRY
2019-04-05 18:26:33 +08:00
{
memory_buf_t buf;
2019-04-27 07:34:50 +08:00
fmt::format_to(buf, fmt, args...);
details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
2019-11-03 23:00:12 +08:00
log_it_(log_msg, log_enabled, traceback_enabled);
2019-04-05 18:26:33 +08:00
}
SPDLOG_LOGGER_CATCH()
2019-04-27 07:34:50 +08:00
}
template<typename... Args>
2019-07-07 01:00:49 +08:00
void log(level::level_enum lvl, string_view_t fmt, const Args &... args)
2019-04-27 07:34:50 +08:00
{
log(source_loc{}, lvl, fmt, args...);
}
template<typename... Args>
2019-07-07 01:00:49 +08:00
void trace(string_view_t fmt, const Args &... args)
2019-04-27 07:34:50 +08:00
{
log(level::trace, fmt, args...);
}
template<typename... Args>
2019-07-07 01:00:49 +08:00
void debug(string_view_t fmt, const Args &... args)
2019-04-27 07:34:50 +08:00
{
log(level::debug, fmt, args...);
}
template<typename... Args>
2019-07-07 01:00:49 +08:00
void info(string_view_t fmt, const Args &... args)
2019-04-27 07:34:50 +08:00
{
log(level::info, fmt, args...);
}
template<typename... Args>
2019-07-07 01:00:49 +08:00
void warn(string_view_t fmt, const Args &... args)
2019-04-27 07:34:50 +08:00
{
log(level::warn, fmt, args...);
}
template<typename... Args>
2019-07-07 01:00:49 +08:00
void error(string_view_t fmt, const Args &... args)
2019-04-27 07:34:50 +08:00
{
log(level::err, fmt, args...);
}
template<typename... Args>
2019-07-07 01:00:49 +08:00
void critical(string_view_t fmt, const Args &... args)
2019-04-27 07:34:50 +08:00
{
log(level::critical, fmt, args...);
}
template<typename T>
void log(level::level_enum lvl, const T &msg)
{
log(source_loc{}, lvl, msg);
}
// T can be statically converted to string_view
template<class T, typename std::enable_if<std::is_convertible<const T &, spdlog::string_view_t>::value, T>::type * = nullptr>
2019-04-27 07:34:50 +08:00
void log(source_loc loc, level::level_enum lvl, const T &msg)
{
2020-02-10 23:13:41 +08:00
log(loc, lvl, string_view_t{msg});
}
void log(source_loc loc, level::level_enum lvl, string_view_t msg)
2019-04-27 07:34:50 +08:00
{
2019-11-03 23:00:12 +08:00
bool log_enabled = should_log(lvl);
bool traceback_enabled = tracer_.enabled();
if (!log_enabled && !traceback_enabled)
2019-08-27 00:59:16 +08:00
{
return;
2019-08-27 00:59:16 +08:00
}
2019-10-18 21:10:30 +08:00
details::log_msg log_msg(loc, name_, lvl, msg);
2019-11-03 23:00:12 +08:00
log_it_(log_msg, log_enabled, traceback_enabled);
}
void log(level::level_enum lvl, string_view_t msg)
{
log(source_loc{}, lvl, msg);
2019-04-27 07:34:50 +08:00
}
2019-07-25 01:46:59 +08:00
// T cannot be statically converted to string_view or wstring_view
template<class T, typename std::enable_if<!std::is_convertible<const T &, spdlog::string_view_t>::value &&
!is_convertible_to_wstring_view<const T &>::value,
T>::type * = nullptr>
2019-04-27 07:34:50 +08:00
void log(source_loc loc, level::level_enum lvl, const T &msg)
{
log(loc, lvl, "{}", msg);
2019-04-27 07:34:50 +08:00
}
template<typename T>
void trace(const T &msg)
{
log(level::trace, msg);
}
template<typename T>
void debug(const T &msg)
{
log(level::debug, msg);
}
template<typename T>
void info(const T &msg)
{
log(level::info, msg);
}
template<typename T>
void warn(const T &msg)
{
log(level::warn, msg);
}
template<typename T>
void error(const T &msg)
{
log(level::err, msg);
}
template<typename T>
void critical(const T &msg)
{
log(level::critical, msg);
}
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
#ifndef _WIN32
#error SPDLOG_WCHAR_TO_UTF8_SUPPORT only supported on windows
#else
2019-08-27 21:39:18 +08:00
template<typename... Args>
2019-08-28 01:22:07 +08:00
void log(source_loc loc, level::level_enum lvl, wstring_view_t fmt, const Args &... args)
2019-08-07 06:29:59 +08:00
{
2019-11-03 23:00:12 +08:00
bool log_enabled = should_log(lvl);
bool traceback_enabled = tracer_.enabled();
if (!log_enabled && !traceback_enabled)
2019-08-07 06:29:59 +08:00
{
return;
2019-08-07 06:29:59 +08:00
}
SPDLOG_TRY
{
2019-08-28 01:22:07 +08:00
// format to wmemory_buffer and convert to utf8
fmt::wmemory_buffer wbuf;
fmt::format_to(wbuf, fmt, args...);
2019-08-07 06:29:59 +08:00
memory_buf_t buf;
details::os::wstr_to_utf8buf(wstring_view_t(wbuf.data(), wbuf.size()), buf);
details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
2019-11-03 23:00:12 +08:00
log_it_(log_msg, log_enabled, traceback_enabled);
}
SPDLOG_LOGGER_CATCH()
}
2019-08-28 01:22:07 +08:00
2019-04-27 07:34:50 +08:00
template<typename... Args>
2019-07-07 01:00:49 +08:00
void log(level::level_enum lvl, wstring_view_t fmt, const Args &... args)
2019-04-27 07:34:50 +08:00
{
log(source_loc{}, lvl, fmt, args...);
}
template<typename... Args>
2019-07-07 01:00:49 +08:00
void trace(wstring_view_t fmt, const Args &... args)
2019-04-27 07:34:50 +08:00
{
log(level::trace, fmt, args...);
}
template<typename... Args>
2019-07-07 01:00:49 +08:00
void debug(wstring_view_t fmt, const Args &... args)
2019-04-27 07:34:50 +08:00
{
log(level::debug, fmt, args...);
}
template<typename... Args>
2019-07-07 01:00:49 +08:00
void info(wstring_view_t fmt, const Args &... args)
2019-04-27 07:34:50 +08:00
{
log(level::info, fmt, args...);
}
template<typename... Args>
2019-07-07 01:00:49 +08:00
void warn(wstring_view_t fmt, const Args &... args)
2019-04-27 07:34:50 +08:00
{
log(level::warn, fmt, args...);
}
template<typename... Args>
2019-07-07 01:00:49 +08:00
void error(wstring_view_t fmt, const Args &... args)
2019-04-27 07:34:50 +08:00
{
log(level::err, fmt, args...);
}
template<typename... Args>
2019-07-07 01:00:49 +08:00
void critical(wstring_view_t fmt, const Args &... args)
2019-04-27 07:34:50 +08:00
{
log(level::critical, fmt, args...);
}
// T can be statically converted to wstring_view
2019-07-25 01:46:59 +08:00
template<class T, typename std::enable_if<is_convertible_to_wstring_view<const T &>::value, T>::type * = nullptr>
void log(source_loc loc, level::level_enum lvl, const T &msg)
{
2019-11-03 23:00:12 +08:00
bool log_enabled = should_log(lvl);
bool traceback_enabled = tracer_.enabled();
if (!log_enabled && !traceback_enabled)
{
return;
}
SPDLOG_TRY
{
memory_buf_t buf;
details::os::wstr_to_utf8buf(msg, buf);
2019-07-25 01:46:59 +08:00
details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size()));
2019-11-03 23:00:12 +08:00
log_it_(log_msg, log_enabled, traceback_enabled);
}
SPDLOG_LOGGER_CATCH()
}
2018-10-04 07:20:47 +08:00
#endif // _WIN32
2019-04-27 07:34:50 +08:00
#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
2019-04-05 18:26:33 +08:00
2019-10-10 02:41:02 +08:00
// return true logging is enabled for the given level.
bool should_log(level::level_enum msg_level) const
{
return msg_level >= level_.load(std::memory_order_relaxed);
}
2019-04-05 18:26:33 +08:00
2019-10-10 02:41:02 +08:00
// return true if backtrace logging is enabled.
bool should_backtrace() const
{
return tracer_.enabled();
}
2019-10-10 02:41:02 +08:00
2019-04-27 07:34:50 +08:00
void set_level(level::level_enum log_level);
2018-07-23 05:13:52 +08:00
2019-04-27 07:34:50 +08:00
level::level_enum level() const;
2018-07-23 05:13:52 +08:00
2019-04-27 07:34:50 +08:00
const std::string &name() const;
2019-04-05 18:26:33 +08:00
2019-04-27 07:34:50 +08:00
// set formatting for the sinks in this logger.
// each sink will get a separate instance of the formatter object.
2019-04-27 07:34:50 +08:00
void set_formatter(std::unique_ptr<formatter> f);
2019-04-05 18:26:33 +08:00
2019-04-27 07:34:50 +08:00
void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local);
2016-09-02 22:06:00 +08:00
2019-08-27 00:59:16 +08:00
// backtrace support.
// efficiently store all debug/trace messages in a circular buffer until needed for debugging.
void enable_backtrace(size_t n_messages);
2019-08-25 22:24:17 +08:00
void disable_backtrace();
void dump_backtrace();
2019-08-23 07:28:52 +08:00
2019-04-27 07:34:50 +08:00
// flush functions
void flush();
void flush_on(level::level_enum log_level);
level::level_enum flush_level() const;
2019-04-05 18:26:33 +08:00
2019-04-27 07:34:50 +08:00
// sinks
const std::vector<sink_ptr> &sinks() const;
2018-07-23 05:13:52 +08:00
2019-04-27 07:34:50 +08:00
std::vector<sink_ptr> &sinks();
2019-04-05 18:26:33 +08:00
2019-04-27 07:34:50 +08:00
// error handler
void set_error_handler(err_handler);
2016-09-02 22:06:00 +08:00
2019-08-29 06:05:23 +08:00
// create new logger with same sinks and configuration.
virtual std::shared_ptr<logger> clone(std::string logger_name);
2019-04-27 07:34:50 +08:00
protected:
std::string name_;
std::vector<sink_ptr> sinks_;
spdlog::level_t level_{level::info};
spdlog::level_t flush_level_{level::off};
err_handler custom_err_handler_{nullptr};
details::backtracer tracer_;
2019-04-05 18:26:33 +08:00
2019-10-18 21:10:30 +08:00
// log the given message (if the given log level is high enough),
// and save backtrace (if backtrace is enabled).
2019-11-03 23:00:12 +08:00
void log_it_(const details::log_msg &log_msg, bool log_enabled, bool traceback_enabled);
virtual void sink_it_(const details::log_msg &msg);
2019-04-27 07:34:50 +08:00
virtual void flush_();
2019-08-27 00:59:16 +08:00
void dump_backtrace_();
2019-04-27 07:34:50 +08:00
bool should_flush_(const details::log_msg &msg);
// handle errors during logging.
// default handler prints the error to stderr at max rate of 1 message/sec.
2019-04-27 07:34:50 +08:00
void err_handler_(const std::string &msg);
2019-04-06 04:05:46 +08:00
};
2019-06-18 22:05:27 +08:00
void swap(logger &a, logger &b);
2018-03-09 21:26:33 +08:00
} // namespace spdlog
2016-09-02 22:06:00 +08:00
#ifdef SPDLOG_HEADER_ONLY
2019-05-11 18:52:46 +08:00
#include "logger-inl.h"
2019-04-27 23:44:48 +08:00
#endif