Commit f9750ddd authored by fegomes's avatar fegomes

Merge branch 'master' into to_level

parents f4ffddc9 e8a39c89
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# #
cmake_minimum_required(VERSION 3.1) cmake_minimum_required(VERSION 3.1)
project(spdlog VERSION 0.16.3) project(spdlog VERSION 0.16.3 LANGUAGES CXX)
include(CTest) include(CTest)
include(CMakeDependentOption) include(CMakeDependentOption)
include(GNUInstallDirs) include(GNUInstallDirs)
...@@ -73,7 +73,6 @@ configure_file("cmake/spdlog.pc.in" "${pkg_config}" @ONLY) ...@@ -73,7 +73,6 @@ configure_file("cmake/spdlog.pc.in" "${pkg_config}" @ONLY)
install( install(
TARGETS spdlog TARGETS spdlog
EXPORT "${targets_export_name}" EXPORT "${targets_export_name}"
INCLUDES DESTINATION "${include_install_dir}"
) )
# install headers # install headers
......
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
# * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ # * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
# *************************************************************************/ # *************************************************************************/
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.1)
project(SpdlogExamples) project(SpdlogExamples CXX)
if(TARGET spdlog) if(TARGET spdlog)
# Part of the main project # Part of the main project
...@@ -32,16 +32,16 @@ else() ...@@ -32,16 +32,16 @@ else()
find_package(spdlog CONFIG REQUIRED) find_package(spdlog CONFIG REQUIRED)
endif() endif()
find_package(Threads) find_package(Threads REQUIRED)
add_executable(example example.cpp) add_executable(example example.cpp)
target_link_libraries(example spdlog::spdlog ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries(example spdlog::spdlog Threads::Threads)
add_executable(benchmark bench.cpp) add_executable(benchmark bench.cpp)
target_link_libraries(benchmark spdlog::spdlog ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries(benchmark spdlog::spdlog Threads::Threads)
add_executable(multisink multisink.cpp) add_executable(multisink multisink.cpp)
target_link_libraries(multisink spdlog::spdlog ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries(multisink spdlog::spdlog Threads::Threads)
enable_testing() enable_testing()
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/logs") file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/logs")
......
...@@ -31,11 +31,11 @@ namespace details ...@@ -31,11 +31,11 @@ namespace details
class async_log_helper; class async_log_helper;
} }
class async_logger SPDLOG_FINAL :public logger class async_logger SPDLOG_FINAL : public logger
{ {
public: public:
template<class It> template<class It>
async_logger(const std::string& name, async_logger(const std::string& logger_name,
const It& begin, const It& begin,
const It& end, const It& end,
size_t queue_size, size_t queue_size,
...@@ -65,8 +65,8 @@ public: ...@@ -65,8 +65,8 @@ public:
void flush() override; void flush() override;
// Error handler // Error handler
virtual void set_error_handler(log_err_handler) override; void set_error_handler(log_err_handler) override;
virtual log_err_handler error_handler() override; log_err_handler error_handler() override;
protected: protected:
void _sink_it(details::log_msg& msg) override; void _sink_it(details::log_msg& msg) override;
...@@ -78,5 +78,4 @@ private: ...@@ -78,5 +78,4 @@ private:
}; };
} }
#include "details/async_logger_impl.h" #include "details/async_logger_impl.h"
...@@ -5,6 +5,10 @@ ...@@ -5,6 +5,10 @@
#pragma once #pragma once
#define SPDLOG_VERSION "0.16.3"
#include "tweakme.h"
#include <string> #include <string>
#include <initializer_list> #include <initializer_list>
#include <chrono> #include <chrono>
...@@ -74,7 +78,7 @@ using log_err_handler = std::function<void(const std::string &err_msg)>; ...@@ -74,7 +78,7 @@ using log_err_handler = std::function<void(const std::string &err_msg)>;
//Log level enum //Log level enum
namespace level namespace level
{ {
typedef enum enum level_enum
{ {
trace = 0, trace = 0,
debug = 1, debug = 1,
...@@ -83,7 +87,7 @@ typedef enum ...@@ -83,7 +87,7 @@ typedef enum
err = 4, err = 4,
critical = 5, critical = 5,
off = 6 off = 6
} level_enum; };
#if !defined(SPDLOG_LEVEL_NAMES) #if !defined(SPDLOG_LEVEL_NAMES)
#define SPDLOG_LEVEL_NAMES { "trace", "debug", "info", "warning", "error", "critical", "off" } #define SPDLOG_LEVEL_NAMES { "trace", "debug", "info", "warning", "error", "critical", "off" }
...@@ -115,7 +119,6 @@ inline spdlog::level::level_enum to_level_enum(const char* name) ...@@ -115,7 +119,6 @@ inline spdlog::level::level_enum to_level_enum(const char* name)
using level_hasher = std::hash<int>; using level_hasher = std::hash<int>;
} //level } //level
// //
// Async overflow policy - block by default. // Async overflow policy - block by default.
// //
...@@ -145,22 +148,24 @@ namespace os ...@@ -145,22 +148,24 @@ namespace os
std::string errno_str(int err_num); std::string errno_str(int err_num);
} }
} }
class spdlog_ex: public std::exception class spdlog_ex : public std::exception
{ {
public: public:
spdlog_ex(const std::string& msg):_msg(msg) explicit spdlog_ex(std::string msg) : _msg(std::move(msg))
{} {}
spdlog_ex(const std::string& msg, int last_errno) spdlog_ex(const std::string& msg, int last_errno)
{ {
_msg = msg + ": " + details::os::errno_str(last_errno); _msg = msg + ": " + details::os::errno_str(last_errno);
} }
const char* what() const SPDLOG_NOEXCEPT override const char* what() const SPDLOG_NOEXCEPT override
{ {
return _msg.c_str(); return _msg.c_str();
} }
private: private:
std::string _msg; std::string _msg;
}; };
// //
...@@ -172,5 +177,4 @@ using filename_t = std::wstring; ...@@ -172,5 +177,4 @@ using filename_t = std::wstring;
using filename_t = std::string; using filename_t = std::string;
#endif #endif
} //spdlog } //spdlog
...@@ -43,6 +43,7 @@ class async_log_helper ...@@ -43,6 +43,7 @@ class async_log_helper
flush, flush,
terminate terminate
}; };
struct async_msg struct async_msg
{ {
std::string logger_name; std::string logger_name;
...@@ -56,8 +57,14 @@ class async_log_helper ...@@ -56,8 +57,14 @@ class async_log_helper
async_msg() = default; async_msg() = default;
~async_msg() = default; ~async_msg() = default;
explicit async_msg(async_msg_type m_type) :
level(level::info),
thread_id(0),
msg_type(m_type),
msg_id(0)
{}
async_msg(async_msg&& other) SPDLOG_NOEXCEPT: async_msg(async_msg&& other) SPDLOG_NOEXCEPT :
logger_name(std::move(other.logger_name)), logger_name(std::move(other.logger_name)),
level(std::move(other.level)), level(std::move(other.level)),
time(std::move(other.time)), time(std::move(other.time)),
...@@ -67,13 +74,6 @@ async_msg(async_msg&& other) SPDLOG_NOEXCEPT: ...@@ -67,13 +74,6 @@ async_msg(async_msg&& other) SPDLOG_NOEXCEPT:
msg_id(other.msg_id) msg_id(other.msg_id)
{} {}
async_msg(async_msg_type m_type):
level(level::info),
thread_id(0),
msg_type(m_type),
msg_id(0)
{}
async_msg& operator=(async_msg&& other) SPDLOG_NOEXCEPT async_msg& operator=(async_msg&& other) SPDLOG_NOEXCEPT
{ {
logger_name = std::move(other.logger_name); logger_name = std::move(other.logger_name);
...@@ -91,7 +91,7 @@ async_msg(async_msg&& other) SPDLOG_NOEXCEPT: ...@@ -91,7 +91,7 @@ async_msg(async_msg&& other) SPDLOG_NOEXCEPT:
async_msg& operator=(const async_msg& other) = delete; async_msg& operator=(const async_msg& other) = delete;
// construct from log_msg // construct from log_msg
async_msg(const details::log_msg& m): explicit async_msg(const details::log_msg& m):
level(m.level), level(m.level),
time(m.time), time(m.time),
thread_id(m.thread_id), thread_id(m.thread_id),
...@@ -104,7 +104,6 @@ async_msg(async_msg&& other) SPDLOG_NOEXCEPT: ...@@ -104,7 +104,6 @@ async_msg(async_msg&& other) SPDLOG_NOEXCEPT:
#endif #endif
} }
// copy into log_msg // copy into log_msg
void fill_log_msg(log_msg &msg) void fill_log_msg(log_msg &msg)
{ {
...@@ -118,28 +117,29 @@ async_msg(async_msg&& other) SPDLOG_NOEXCEPT: ...@@ -118,28 +117,29 @@ async_msg(async_msg&& other) SPDLOG_NOEXCEPT:
}; };
public: public:
using item_type = async_msg; using item_type = async_msg;
using q_type = details::mpmc_bounded_queue<item_type>; using q_type = details::mpmc_bounded_queue<item_type>;
using clock = std::chrono::steady_clock; using clock = std::chrono::steady_clock;
async_log_helper(formatter_ptr formatter, async_log_helper(formatter_ptr formatter,
const std::vector<sink_ptr>& sinks, std::vector<sink_ptr> sinks,
size_t queue_size, size_t queue_size,
const log_err_handler err_handler, const log_err_handler err_handler,
const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, const async_overflow_policy overflow_policy = async_overflow_policy::block_retry,
const std::function<void()>& worker_warmup_cb = nullptr, std::function<void()> worker_warmup_cb = nullptr,
const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero(), const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero(),
const std::function<void()>& worker_teardown_cb = nullptr); std::function<void()> worker_teardown_cb = nullptr);
void log(const details::log_msg& msg); void log(const details::log_msg& msg);
// stop logging and join the back thread // stop logging and join the back thread
~async_log_helper(); ~async_log_helper();
void set_formatter(formatter_ptr); async_log_helper(const async_log_helper&) = delete;
async_log_helper& operator=(const async_log_helper&) = delete;
void set_formatter(formatter_ptr msg_formatter);
void flush(bool wait_for_q); void flush(bool wait_for_q);
...@@ -158,7 +158,6 @@ private: ...@@ -158,7 +158,6 @@ private:
bool _terminate_requested; bool _terminate_requested;
// overflow policy // overflow policy
const async_overflow_policy _overflow_policy; const async_overflow_policy _overflow_policy;
...@@ -200,25 +199,26 @@ private: ...@@ -200,25 +199,26 @@ private:
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
inline spdlog::details::async_log_helper::async_log_helper( inline spdlog::details::async_log_helper::async_log_helper(
formatter_ptr formatter, formatter_ptr formatter,
const std::vector<sink_ptr>& sinks, std::vector<sink_ptr> sinks,
size_t queue_size, size_t queue_size,
log_err_handler err_handler, log_err_handler err_handler,
const async_overflow_policy overflow_policy, const async_overflow_policy overflow_policy,
const std::function<void()>& worker_warmup_cb, std::function<void()> worker_warmup_cb,
const std::chrono::milliseconds& flush_interval_ms, const std::chrono::milliseconds& flush_interval_ms,
const std::function<void()>& worker_teardown_cb): std::function<void()> worker_teardown_cb):
_formatter(formatter), _formatter(std::move(formatter)),
_sinks(sinks), _sinks(std::move(sinks)),
_q(queue_size), _q(queue_size),
_err_handler(err_handler), _err_handler(std::move(err_handler)),
_flush_requested(false), _flush_requested(false),
_terminate_requested(false), _terminate_requested(false),
_overflow_policy(overflow_policy), _overflow_policy(overflow_policy),
_worker_warmup_cb(worker_warmup_cb), _worker_warmup_cb(std::move(worker_warmup_cb)),
_flush_interval_ms(flush_interval_ms), _flush_interval_ms(flush_interval_ms),
_worker_teardown_cb(worker_teardown_cb), _worker_teardown_cb(std::move(worker_teardown_cb))
_worker_thread(&async_log_helper::worker_loop, this) {
{} _worker_thread = std::thread(&async_log_helper::worker_loop, this);
}
// Send to the worker thread termination message(level=off) // Send to the worker thread termination message(level=off)
// and wait for it to finish gracefully // and wait for it to finish gracefully
...@@ -327,13 +327,10 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_ ...@@ -327,13 +327,10 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_
// Handle empty queue.. // Handle empty queue..
// This is the only place where the queue can terminate or flush to avoid losing messages already in the queue // This is the only place where the queue can terminate or flush to avoid losing messages already in the queue
else
{
auto now = details::os::now(); auto now = details::os::now();
handle_flush_interval(now, last_flush); handle_flush_interval(now, last_flush);
sleep_or_yield(now, last_pop); sleep_or_yield(now, last_pop);
return !_terminate_requested; return !_terminate_requested;
}
} }
// flush all sinks if _flush_interval_ms has expired // flush all sinks if _flush_interval_ms has expired
...@@ -351,10 +348,9 @@ inline void spdlog::details::async_log_helper::handle_flush_interval(log_clock:: ...@@ -351,10 +348,9 @@ inline void spdlog::details::async_log_helper::handle_flush_interval(log_clock::
inline void spdlog::details::async_log_helper::set_formatter(formatter_ptr msg_formatter) inline void spdlog::details::async_log_helper::set_formatter(formatter_ptr msg_formatter)
{ {
_formatter = msg_formatter; _formatter = std::move(msg_formatter);
} }
// spin, yield or sleep. use the time passed since last message as a hint // spin, yield or sleep. use the time passed since last message as a hint
inline void spdlog::details::async_log_helper::sleep_or_yield(const spdlog::log_clock::time_point& now, const spdlog::log_clock::time_point& last_op_time) inline void spdlog::details::async_log_helper::sleep_or_yield(const spdlog::log_clock::time_point& now, const spdlog::log_clock::time_point& last_op_time)
{ {
...@@ -391,8 +387,5 @@ inline void spdlog::details::async_log_helper::wait_empty_q() ...@@ -391,8 +387,5 @@ inline void spdlog::details::async_log_helper::wait_empty_q()
inline void spdlog::details::async_log_helper::set_error_handler(spdlog::log_err_handler err_handler) inline void spdlog::details::async_log_helper::set_error_handler(spdlog::log_err_handler err_handler)
{ {
_err_handler = err_handler; _err_handler = std::move(err_handler);
} }
...@@ -48,7 +48,7 @@ inline spdlog::async_logger::async_logger(const std::string& logger_name, ...@@ -48,7 +48,7 @@ inline spdlog::async_logger::async_logger(const std::string& logger_name,
const std::function<void()>& worker_teardown_cb) : const std::function<void()>& worker_teardown_cb) :
async_logger(logger_name, async_logger(logger_name,
{ {
single_sink std::move(single_sink)
}, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb) {} }, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb) {}
......
...@@ -31,9 +31,7 @@ public: ...@@ -31,9 +31,7 @@ public:
const int open_tries = 5; const int open_tries = 5;
const int open_interval = 10; const int open_interval = 10;
explicit file_helper() : explicit file_helper() = default;
_fd(nullptr)
{}
file_helper(const file_helper&) = delete; file_helper(const file_helper&) = delete;
file_helper& operator=(const file_helper&) = delete; file_helper& operator=(const file_helper&) = delete;
...@@ -46,7 +44,6 @@ public: ...@@ -46,7 +44,6 @@ public:
void open(const filename_t& fname, bool truncate = false) void open(const filename_t& fname, bool truncate = false)
{ {
close(); close();
auto *mode = truncate ? SPDLOG_FILENAME_T("wb") : SPDLOG_FILENAME_T("ab"); auto *mode = truncate ? SPDLOG_FILENAME_T("wb") : SPDLOG_FILENAME_T("ab");
_filename = fname; _filename = fname;
...@@ -76,7 +73,7 @@ public: ...@@ -76,7 +73,7 @@ public:
void close() void close()
{ {
if (_fd) if (_fd != nullptr)
{ {
std::fclose(_fd); std::fclose(_fd);
_fd = nullptr; _fd = nullptr;
...@@ -93,8 +90,10 @@ public: ...@@ -93,8 +90,10 @@ public:
size_t size() const size_t size() const
{ {
if (!_fd) if (_fd == nullptr)
{
throw spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(_filename)); throw spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(_filename));
}
return os::filesize(_fd); return os::filesize(_fd);
} }
...@@ -137,8 +136,9 @@ public: ...@@ -137,8 +136,9 @@ public:
// finally - return a valid base and extension tuple // finally - return a valid base and extension tuple
return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index)); return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index));
} }
private: private:
FILE* _fd; FILE* _fd{ nullptr };
filename_t _filename; filename_t _filename;
}; };
} }
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
#include "../common.h" #include "../common.h"
#include "../details/os.h" #include "../details/os.h"
#include <string> #include <string>
#include <utility> #include <utility>
...@@ -21,8 +20,7 @@ struct log_msg ...@@ -21,8 +20,7 @@ struct log_msg
log_msg() = default; log_msg() = default;
log_msg(const std::string *loggers_name, level::level_enum lvl) : log_msg(const std::string *loggers_name, level::level_enum lvl) :
logger_name(loggers_name), logger_name(loggers_name),
level(lvl), level(lvl)
msg_id(0)
{ {
#ifndef SPDLOG_NO_DATETIME #ifndef SPDLOG_NO_DATETIME
time = os::now(); time = os::now();
...@@ -38,13 +36,13 @@ struct log_msg ...@@ -38,13 +36,13 @@ struct log_msg
log_msg(log_msg&& other) = delete; log_msg(log_msg&& other) = delete;
const std::string *logger_name; const std::string *logger_name{ nullptr };
level::level_enum level; level::level_enum level;
log_clock::time_point time; log_clock::time_point time;
size_t thread_id; size_t thread_id;
fmt::MemoryWriter raw; fmt::MemoryWriter raw;
fmt::MemoryWriter formatted; fmt::MemoryWriter formatted;
size_t msg_id; size_t msg_id{ 0 };
}; };
} }
} }
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
// create logger with given name, sinks and the default pattern formatter // create logger with given name, sinks and the default pattern formatter
// all other ctors will call this one // all other ctors will call this one
template<class It> template<class It>
inline spdlog::logger::logger(const std::string& logger_name, const It& begin, const It& end): inline spdlog::logger::logger(std::string logger_name, const It& begin, const It& end):
_name(logger_name), _name(std::move(logger_name)),
_sinks(begin, end), _sinks(begin, end),
_formatter(std::make_shared<pattern_formatter>("%+")), _formatter(std::make_shared<pattern_formatter>("%+")),
_level(level::info), _level(level::info),
...@@ -39,7 +39,7 @@ inline spdlog::logger::logger(const std::string& logger_name, sinks_init_list si ...@@ -39,7 +39,7 @@ inline spdlog::logger::logger(const std::string& logger_name, sinks_init_list si
inline spdlog::logger::logger(const std::string& logger_name, spdlog::sink_ptr single_sink): inline spdlog::logger::logger(const std::string& logger_name, spdlog::sink_ptr single_sink):
logger(logger_name, logger(logger_name,
{ {
single_sink std::move(single_sink)
}) })
{} {}
...@@ -49,7 +49,7 @@ inline spdlog::logger::~logger() = default; ...@@ -49,7 +49,7 @@ inline spdlog::logger::~logger() = default;
inline void spdlog::logger::set_formatter(spdlog::formatter_ptr msg_formatter) inline void spdlog::logger::set_formatter(spdlog::formatter_ptr msg_formatter)
{ {
_set_formatter(msg_formatter); _set_formatter(std::move(msg_formatter));
} }
inline void spdlog::logger::set_pattern(const std::string& pattern, pattern_time_type pattern_time) inline void spdlog::logger::set_pattern(const std::string& pattern, pattern_time_type pattern_time)
...@@ -281,7 +281,7 @@ inline void spdlog::logger::set_level(spdlog::level::level_enum log_level) ...@@ -281,7 +281,7 @@ inline void spdlog::logger::set_level(spdlog::level::level_enum log_level)
inline void spdlog::logger::set_error_handler(spdlog::log_err_handler err_handler) inline void spdlog::logger::set_error_handler(spdlog::log_err_handler err_handler)
{ {
_err_handler = err_handler; _err_handler = std::move(err_handler);
} }
inline spdlog::log_err_handler spdlog::logger::error_handler() inline spdlog::log_err_handler spdlog::logger::error_handler()
...@@ -289,7 +289,6 @@ inline spdlog::log_err_handler spdlog::logger::error_handler() ...@@ -289,7 +289,6 @@ inline spdlog::log_err_handler spdlog::logger::error_handler()
return _err_handler; return _err_handler;
} }
inline void spdlog::logger::flush_on(level::level_enum log_level) inline void spdlog::logger::flush_on(level::level_enum log_level)
{ {
_flush_level.store(log_level); _flush_level.store(log_level);
...@@ -330,9 +329,10 @@ inline void spdlog::logger::_set_pattern(const std::string& pattern, pattern_tim ...@@ -330,9 +329,10 @@ inline void spdlog::logger::_set_pattern(const std::string& pattern, pattern_tim
{ {
_formatter = std::make_shared<pattern_formatter>(pattern, pattern_time); _formatter = std::make_shared<pattern_formatter>(pattern, pattern_time);
} }
inline void spdlog::logger::_set_formatter(formatter_ptr msg_formatter) inline void spdlog::logger::_set_formatter(formatter_ptr msg_formatter)
{ {
_formatter = msg_formatter; _formatter = std::move(msg_formatter);
} }
inline void spdlog::logger::flush() inline void spdlog::logger::flush()
...@@ -350,7 +350,7 @@ inline void spdlog::logger::_default_err_handler(const std::string &msg) ...@@ -350,7 +350,7 @@ inline void spdlog::logger::_default_err_handler(const std::string &msg)
char date_buf[100]; char date_buf[100];
std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time); std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time);
details::log_msg err_msg; details::log_msg err_msg;
err_msg.formatted.write("[*** LOG ERROR ***] [{}] [{}] [{}]{}", name(), msg, date_buf, details::os::eol); err_msg.formatted.write("[*** LOG ERROR ***] [{}] [{}] [{}]{}", name(), msg, date_buf, details::os::default_eol);
sinks::stderr_sink_mt::instance()->log(err_msg); sinks::stderr_sink_mt::instance()->log(err_msg);
_last_err_time = now; _last_err_time = now;
} }
......
...@@ -53,13 +53,13 @@ namespace spdlog ...@@ -53,13 +53,13 @@ namespace spdlog
namespace details namespace details
{ {
template<typename T> template <typename T>
class mpmc_bounded_queue class mpmc_bounded_queue
{ {
public: public:
using item_type = T; using item_type = T;
mpmc_bounded_queue(size_t buffer_size)
explicit mpmc_bounded_queue(size_t buffer_size)
:max_size_(buffer_size), :max_size_(buffer_size),
buffer_(new cell_t[buffer_size]), buffer_(new cell_t[buffer_size]),
buffer_mask_(buffer_size - 1) buffer_mask_(buffer_size - 1)
...@@ -79,6 +79,8 @@ public: ...@@ -79,6 +79,8 @@ public:
delete[] buffer_; delete[] buffer_;
} }
mpmc_bounded_queue(mpmc_bounded_queue const&) = delete;
void operator=(mpmc_bounded_queue const&) = delete;
bool enqueue(T&& data) bool enqueue(T&& data)
{ {
...@@ -157,7 +159,7 @@ private: ...@@ -157,7 +159,7 @@ private:
size_t const max_size_; size_t const max_size_;
static size_t const cacheline_size = 64; static size_t const cacheline_size = 64;
typedef char cacheline_pad_t[cacheline_size]; using cacheline_pad_t = char[cacheline_size];
cacheline_pad_t pad0_; cacheline_pad_t pad0_;
cell_t* const buffer_; cell_t* const buffer_;
...@@ -167,9 +169,6 @@ private: ...@@ -167,9 +169,6 @@ private:
cacheline_pad_t pad2_; cacheline_pad_t pad2_;
std::atomic<size_t> dequeue_pos_; std::atomic<size_t> dequeue_pos_;
cacheline_pad_t pad3_; cacheline_pad_t pad3_;
mpmc_bounded_queue(mpmc_bounded_queue const&) = delete;
void operator= (mpmc_bounded_queue const&) = delete;
}; };
} // ns details } // ns details
......
...@@ -27,7 +27,7 @@ struct null_atomic_int ...@@ -27,7 +27,7 @@ struct null_atomic_int
int value; int value;
null_atomic_int() = default; null_atomic_int() = default;
null_atomic_int(int val):value(val) explicit null_atomic_int(int val) : value(val)
{} {}
int load(std::memory_order) const int load(std::memory_order) const
......
...@@ -96,7 +96,6 @@ inline std::tm localtime() ...@@ -96,7 +96,6 @@ inline std::tm localtime()
return localtime(now_t); return localtime(now_t);
} }
inline std::tm gmtime(const std::time_t &time_tt) inline std::tm gmtime(const std::time_t &time_tt)
{ {
...@@ -140,8 +139,7 @@ inline bool operator!=(const std::tm& tm1, const std::tm& tm2) ...@@ -140,8 +139,7 @@ inline bool operator!=(const std::tm& tm1, const std::tm& tm2)
#endif #endif
#endif #endif
SPDLOG_CONSTEXPR static const char* eol = SPDLOG_EOL; SPDLOG_CONSTEXPR static const char* default_eol = SPDLOG_EOL;
SPDLOG_CONSTEXPR static int eol_size = sizeof(SPDLOG_EOL) - 1;
...@@ -155,10 +153,13 @@ SPDLOG_CONSTEXPR static const char folder_sep = '/'; ...@@ -155,10 +153,13 @@ SPDLOG_CONSTEXPR static const char folder_sep = '/';
inline void prevent_child_fd(FILE *f) inline void prevent_child_fd(FILE *f)
{ {
#ifdef _WIN32 #ifdef _WIN32
#if !defined(__cplusplus_winrt)
auto file_handle = (HANDLE)_get_osfhandle(_fileno(f)); auto file_handle = (HANDLE)_get_osfhandle(_fileno(f));
if (!::SetHandleInformation(file_handle, HANDLE_FLAG_INHERIT, 0)) if (!::SetHandleInformation(file_handle, HANDLE_FLAG_INHERIT, 0))
throw spdlog_ex("SetHandleInformation failed", errno); throw spdlog_ex("SetHandleInformation failed", errno);
#endif
#else #else
auto fd = fileno(f); auto fd = fileno(f);
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
...@@ -168,7 +169,7 @@ inline void prevent_child_fd(FILE *f) ...@@ -168,7 +169,7 @@ inline void prevent_child_fd(FILE *f)
//fopen_s on non windows for writing //fopen_s on non windows for writing
inline int fopen_s(FILE** fp, const filename_t& filename, const filename_t& mode) inline bool fopen_s(FILE** fp, const filename_t& filename, const filename_t& mode)
{ {
#ifdef _WIN32 #ifdef _WIN32
#ifdef SPDLOG_WCHAR_FILENAMES #ifdef SPDLOG_WCHAR_FILENAMES
...@@ -248,7 +249,7 @@ inline size_t filesize(FILE *f) ...@@ -248,7 +249,7 @@ inline size_t filesize(FILE *f)
int fd = fileno(f); int fd = fileno(f);
//64 bits(but not in osx or cygwin, where fstat64 is deprecated) //64 bits(but not in osx or cygwin, where fstat64 is deprecated)
#if !defined(__FreeBSD__) && !defined(__APPLE__) && (defined(__x86_64__) || defined(__ppc64__)) && !defined(__CYGWIN__) #if !defined(__FreeBSD__) && !defined(__APPLE__) && (defined(__x86_64__) || defined(__ppc64__)) && !defined(__CYGWIN__)
struct stat64 st; struct stat64 st ;
if (fstat64(fd, &st) == 0) if (fstat64(fd, &st) == 0)
return static_cast<size_t>(st.st_size); return static_cast<size_t>(st.st_size);
#else // unix 32 bits or cygwin #else // unix 32 bits or cygwin
...@@ -316,9 +317,9 @@ inline int utc_minutes_offset(const std::tm& tm = details::os::localtime()) ...@@ -316,9 +317,9 @@ inline int utc_minutes_offset(const std::tm& tm = details::os::localtime())
} }
}; };
long int offset_seconds = helper::calculate_gmt_offset(tm); auto offset_seconds = helper::calculate_gmt_offset(tm);
#else #else
long int offset_seconds = tm.tm_gmtoff; auto offset_seconds = tm.tm_gmtoff;
#endif #endif
return static_cast<int>(offset_seconds / 60); return static_cast<int>(offset_seconds / 60);
...@@ -352,7 +353,7 @@ inline size_t _thread_id() ...@@ -352,7 +353,7 @@ inline size_t _thread_id()
//Return current thread id as size_t (from thread local storage) //Return current thread id as size_t (from thread local storage)
inline size_t thread_id() inline size_t thread_id()
{ {
#if defined(SPDLOG_DISABLE_TID_CACHING) || (defined(_MSC_VER) && (_MSC_VER < 1900)) || (defined(__clang__) && !__has_feature(cxx_thread_local)) #if defined(SPDLOG_DISABLE_TID_CACHING) || (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__cplusplus_winrt ) || (defined(__clang__) && !__has_feature(cxx_thread_local))
return _thread_id(); return _thread_id();
#else // cache thread id in tls #else // cache thread id in tls
static thread_local const size_t tid = _thread_id(); static thread_local const size_t tid = _thread_id();
...@@ -368,7 +369,7 @@ inline size_t thread_id() ...@@ -368,7 +369,7 @@ inline size_t thread_id()
inline void sleep_for_millis(int milliseconds) inline void sleep_for_millis(int milliseconds)
{ {
#if defined(_WIN32) #if defined(_WIN32)
Sleep(milliseconds); ::Sleep(milliseconds);
#else #else
std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds)); std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
#endif #endif
...@@ -401,10 +402,7 @@ inline std::string errno_to_string(char buf[256], int res) ...@@ -401,10 +402,7 @@ inline std::string errno_to_string(char buf[256], int res)
{ {
return std::string(buf); return std::string(buf);
} }
else
{
return "Unknown error"; return "Unknown error";
}
} }
// Return errno string (thread safe) // Return errno string (thread safe)
...@@ -437,7 +435,7 @@ inline int pid() ...@@ -437,7 +435,7 @@ inline int pid()
{ {
#ifdef _WIN32 #ifdef _WIN32
return ::_getpid(); return static_cast<int>(::GetCurrentProcessId());
#else #else
return static_cast<int>(::getpid()); return static_cast<int>(::getpid());
#endif #endif
...@@ -480,9 +478,9 @@ inline bool in_terminal(FILE* file) ...@@ -480,9 +478,9 @@ inline bool in_terminal(FILE* file)
{ {
#ifdef _WIN32 #ifdef _WIN32
return _isatty(_fileno(file)) ? true : false; return _isatty(_fileno(file)) != 0;
#else #else
return isatty(fileno(file)) ? true : false; return isatty(fileno(file)) != 0;
#endif #endif
} }
} //os } //os
......
...@@ -26,9 +26,12 @@ namespace spdlog ...@@ -26,9 +26,12 @@ namespace spdlog
{ {
namespace details namespace details
{ {
template <class Mutex> class registry_t template <class Mutex>
class registry_t
{ {
public: public:
registry_t<Mutex>(const registry_t<Mutex>&) = delete;
registry_t<Mutex>& operator=(const registry_t<Mutex>&) = delete;
void register_logger(std::shared_ptr<logger> logger) void register_logger(std::shared_ptr<logger> logger)
{ {
...@@ -38,7 +41,6 @@ public: ...@@ -38,7 +41,6 @@ public:
_loggers[logger_name] = logger; _loggers[logger_name] = logger;
} }
std::shared_ptr<logger> get(const std::string& logger_name) std::shared_ptr<logger> get(const std::string& logger_name)
{ {
std::lock_guard<Mutex> lock(_mutex); std::lock_guard<Mutex> lock(_mutex);
...@@ -111,6 +113,7 @@ public: ...@@ -111,6 +113,7 @@ public:
std::lock_guard<Mutex> lock(_mutex); std::lock_guard<Mutex> lock(_mutex);
_loggers.clear(); _loggers.clear();
} }
std::shared_ptr<logger> create(const std::string& logger_name, sinks_init_list sinks) std::shared_ptr<logger> create(const std::string& logger_name, sinks_init_list sinks)
{ {
return create(logger_name, sinks.begin(), sinks.end()); return create(logger_name, sinks.begin(), sinks.end());
...@@ -194,15 +197,14 @@ public: ...@@ -194,15 +197,14 @@ public:
} }
private: private:
registry_t<Mutex>() {} registry_t<Mutex>() = default;
registry_t<Mutex>(const registry_t<Mutex>&) = delete;
registry_t<Mutex>& operator=(const registry_t<Mutex>&) = delete;
void throw_if_exists(const std::string &logger_name) void throw_if_exists(const std::string &logger_name)
{ {
if (_loggers.find(logger_name) != _loggers.end()) if (_loggers.find(logger_name) != _loggers.end())
throw spdlog_ex("logger with name '" + logger_name + "' already exists"); throw spdlog_ex("logger with name '" + logger_name + "' already exists");
} }
Mutex _mutex; Mutex _mutex;
std::unordered_map <std::string, std::shared_ptr<logger>> _loggers; std::unordered_map <std::string, std::shared_ptr<logger>> _loggers;
formatter_ptr _formatter; formatter_ptr _formatter;
...@@ -212,14 +214,16 @@ private: ...@@ -212,14 +214,16 @@ private:
bool _async_mode = false; bool _async_mode = false;
size_t _async_q_size = 0; size_t _async_q_size = 0;
async_overflow_policy _overflow_policy = async_overflow_policy::block_retry; async_overflow_policy _overflow_policy = async_overflow_policy::block_retry;
std::function<void()> _worker_warmup_cb = nullptr; std::function<void()> _worker_warmup_cb;
std::chrono::milliseconds _flush_interval_ms; std::chrono::milliseconds _flush_interval_ms;
std::function<void()> _worker_teardown_cb = nullptr; std::function<void()> _worker_teardown_cb;
}; };
#ifdef SPDLOG_NO_REGISTRY_MUTEX #ifdef SPDLOG_NO_REGISTRY_MUTEX
typedef registry_t<spdlog::details::null_mutex> registry; using registry = registry_t<spdlog::details::null_mutex>;
#else #else
typedef registry_t<std::mutex> registry; using registry = registry_t<std::mutex>;
#endif #endif
} }
} }
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include "../sinks/syslog_sink.h" #include "../sinks/syslog_sink.h"
#endif #endif
#ifdef _WIN32 #if defined _WIN32 && !defined(__cplusplus_winrt)
#include "../sinks/wincolor_sink.h" #include "../sinks/wincolor_sink.h"
#else #else
#include "../sinks/ansicolor_sink.h" #include "../sinks/ansicolor_sink.h"
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
inline void spdlog::register_logger(std::shared_ptr<logger> logger) inline void spdlog::register_logger(std::shared_ptr<logger> logger)
{ {
return details::registry::instance().register_logger(logger); return details::registry::instance().register_logger(std::move(logger));
} }
inline std::shared_ptr<spdlog::logger> spdlog::get(const std::string& name) inline std::shared_ptr<spdlog::logger> spdlog::get(const std::string& name)
...@@ -107,7 +107,8 @@ inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st(const std::strin ...@@ -107,7 +107,8 @@ inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st(const std::strin
// //
// stdout/stderr color loggers // stdout/stderr color loggers
// //
#ifdef _WIN32 #if defined _WIN32 && !defined(__cplusplus_winrt)
inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt(const std::string& logger_name) inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt(const std::string& logger_name)
{ {
auto sink = std::make_shared<spdlog::sinks::wincolor_stdout_sink_mt>(); auto sink = std::make_shared<spdlog::sinks::wincolor_stdout_sink_mt>();
...@@ -182,13 +183,11 @@ inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_ ...@@ -182,13 +183,11 @@ inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_
} }
//Create logger with multiple sinks //Create logger with multiple sinks
inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, spdlog::sinks_init_list sinks) inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, spdlog::sinks_init_list sinks)
{ {
return details::registry::instance().create(logger_name, sinks); return details::registry::instance().create(logger_name, sinks);
} }
template <typename Sink, typename... Args> template <typename Sink, typename... Args>
inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, Args... args) inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, Args... args)
{ {
...@@ -196,7 +195,6 @@ inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_ ...@@ -196,7 +195,6 @@ inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_
return details::registry::instance().create(logger_name, { sink }); return details::registry::instance().create(logger_name, { sink });
} }
template<class It> template<class It>
inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end) inline std::shared_ptr<spdlog::logger> spdlog::create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end)
{ {
...@@ -223,7 +221,7 @@ inline std::shared_ptr<spdlog::logger> spdlog::create_async(const std::string& l ...@@ -223,7 +221,7 @@ inline std::shared_ptr<spdlog::logger> spdlog::create_async(const std::string& l
inline void spdlog::set_formatter(spdlog::formatter_ptr f) inline void spdlog::set_formatter(spdlog::formatter_ptr f)
{ {
details::registry::instance().formatter(f); details::registry::instance().formatter(std::move(f));
} }
inline void spdlog::set_pattern(const std::string& format_string) inline void spdlog::set_pattern(const std::string& format_string)
...@@ -243,10 +241,9 @@ inline void spdlog::flush_on(level::level_enum log_level) ...@@ -243,10 +241,9 @@ inline void spdlog::flush_on(level::level_enum log_level)
inline void spdlog::set_error_handler(log_err_handler handler) inline void spdlog::set_error_handler(log_err_handler handler)
{ {
return details::registry::instance().set_error_handler(handler); return details::registry::instance().set_error_handler(std::move(handler));
} }
inline void spdlog::set_async_mode(size_t queue_size, const async_overflow_policy overflow_policy, const std::function<void()>& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function<void()>& worker_teardown_cb) inline void spdlog::set_async_mode(size_t queue_size, const async_overflow_policy overflow_policy, const std::function<void()>& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms, const std::function<void()>& worker_teardown_cb)
{ {
details::registry::instance().set_async_mode(queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb); details::registry::instance().set_async_mode(queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms, worker_teardown_cb);
...@@ -259,7 +256,7 @@ inline void spdlog::set_sync_mode() ...@@ -259,7 +256,7 @@ inline void spdlog::set_sync_mode()
inline void spdlog::apply_all(std::function<void(std::shared_ptr<logger>)> fun) inline void spdlog::apply_all(std::function<void(std::shared_ptr<logger>)> fun)
{ {
details::registry::instance().apply_all(fun); details::registry::instance().apply_all(std::move(fun));
} }
inline void spdlog::drop_all() inline void spdlog::drop_all()
......
...@@ -72,9 +72,11 @@ ...@@ -72,9 +72,11 @@
// Dummy implementations of strerror_r and strerror_s called if corresponding // Dummy implementations of strerror_r and strerror_s called if corresponding
// system functions are not available. // system functions are not available.
FMT_MAYBE_UNUSED
static inline fmt::internal::Null<> strerror_r(int, char *, ...) { static inline fmt::internal::Null<> strerror_r(int, char *, ...) {
return fmt::internal::Null<>(); return fmt::internal::Null<>();
} }
FMT_MAYBE_UNUSED
static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) { static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) {
return fmt::internal::Null<>(); return fmt::internal::Null<>();
} }
...@@ -121,7 +123,7 @@ typedef void (*FormatFunc)(Writer &, int, StringRef); ...@@ -121,7 +123,7 @@ typedef void (*FormatFunc)(Writer &, int, StringRef);
// Buffer should be at least of size 1. // Buffer should be at least of size 1.
int safe_strerror( int safe_strerror(
int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT { int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer"); FMT_ASSERT(buffer != FMT_NULL && buffer_size != 0, "invalid buffer");
class StrError { class StrError {
private: private:
...@@ -159,6 +161,11 @@ int safe_strerror( ...@@ -159,6 +161,11 @@ int safe_strerror(
ERANGE : result; ERANGE : result;
} }
#ifdef __c2__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
// Fallback to strerror if strerror_r and strerror_s are not available. // Fallback to strerror if strerror_r and strerror_s are not available.
int fallback(internal::Null<>) { int fallback(internal::Null<>) {
errno = 0; errno = 0;
...@@ -166,13 +173,15 @@ int safe_strerror( ...@@ -166,13 +173,15 @@ int safe_strerror(
return errno; return errno;
} }
#ifdef __c2__
# pragma clang diagnostic pop
#endif
public: public:
StrError(int err_code, char *&buf, std::size_t buf_size) StrError(int err_code, char *&buf, std::size_t buf_size)
: error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {} : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
int run() { int run() {
// Suppress a warning about unused strerror_r.
strerror_r(0, FMT_NULL, "");
return handle(strerror_r(error_code_, buffer_, buffer_size_)); return handle(strerror_r(error_code_, buffer_, buffer_size_));
} }
}; };
...@@ -396,51 +405,6 @@ FMT_FUNC void format_system_error( ...@@ -396,51 +405,6 @@ FMT_FUNC void format_system_error(
fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32. fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
} }
template <typename Char>
void internal::ArgMap<Char>::init(const ArgList &args) {
if (!map_.empty())
return;
typedef internal::NamedArg<Char> NamedArg;
const NamedArg *named_arg = FMT_NULL;
bool use_values =
args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE;
if (use_values) {
for (unsigned i = 0;/*nothing*/; ++i) {
internal::Arg::Type arg_type = args.type(i);
switch (arg_type) {
case internal::Arg::NONE:
return;
case internal::Arg::NAMED_ARG:
named_arg = static_cast<const NamedArg*>(args.values_[i].pointer);
map_.push_back(Pair(named_arg->name, *named_arg));
break;
default:
/*nothing*/;
}
}
return;
}
for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) {
internal::Arg::Type arg_type = args.type(i);
if (arg_type == internal::Arg::NAMED_ARG) {
named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
map_.push_back(Pair(named_arg->name, *named_arg));
}
}
for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
switch (args.args_[i].type) {
case internal::Arg::NONE:
return;
case internal::Arg::NAMED_ARG:
named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
map_.push_back(Pair(named_arg->name, *named_arg));
break;
default:
/*nothing*/;
}
}
}
template <typename Char> template <typename Char>
void internal::FixedBuffer<Char>::grow(std::size_t) { void internal::FixedBuffer<Char>::grow(std::size_t) {
FMT_THROW(std::runtime_error("buffer overflow")); FMT_THROW(std::runtime_error("buffer overflow"));
...@@ -502,8 +466,6 @@ template struct internal::BasicData<void>; ...@@ -502,8 +466,6 @@ template struct internal::BasicData<void>;
template void internal::FixedBuffer<char>::grow(std::size_t); template void internal::FixedBuffer<char>::grow(std::size_t);
template void internal::ArgMap<char>::init(const ArgList &args);
template FMT_API int internal::CharTraits<char>::format_float( template FMT_API int internal::CharTraits<char>::format_float(
char *buffer, std::size_t size, const char *format, char *buffer, std::size_t size, const char *format,
unsigned width, int precision, double value); unsigned width, int precision, double value);
...@@ -516,8 +478,6 @@ template FMT_API int internal::CharTraits<char>::format_float( ...@@ -516,8 +478,6 @@ template FMT_API int internal::CharTraits<char>::format_float(
template void internal::FixedBuffer<wchar_t>::grow(std::size_t); template void internal::FixedBuffer<wchar_t>::grow(std::size_t);
template void internal::ArgMap<wchar_t>::init(const ArgList &args);
template FMT_API int internal::CharTraits<wchar_t>::format_float( template FMT_API int internal::CharTraits<wchar_t>::format_float(
wchar_t *buffer, std::size_t size, const wchar_t *format, wchar_t *buffer, std::size_t size, const wchar_t *format,
unsigned width, int precision, double value); unsigned width, int precision, double value);
......
This diff is collapsed.
...@@ -58,13 +58,15 @@ Yes &convert(std::ostream &); ...@@ -58,13 +58,15 @@ Yes &convert(std::ostream &);
struct DummyStream : std::ostream struct DummyStream : std::ostream
{ {
DummyStream(); // Suppress a bogus warning in MSVC. DummyStream(); // Suppress a bogus warning in MSVC.
// Hide all operator<< overloads from std::ostream. // Hide all operator<< overloads from std::ostream.
void operator<<(Null<>); template <typename T>
typename EnableIf<sizeof(T) == 0>::type operator<<(const T &);
}; };
No &operator<<(std::ostream &, int); No &operator<<(std::ostream &, int);
template<typename T> template <typename T>
struct ConvertToIntImpl<T, true> struct ConvertToIntImpl<T, true>
{ {
// Convert to int only if T doesn't have an overloaded operator<<. // Convert to int only if T doesn't have an overloaded operator<<.
...@@ -87,6 +89,7 @@ void format_arg(BasicFormatter<Char, ArgFormatter_> &f, ...@@ -87,6 +89,7 @@ void format_arg(BasicFormatter<Char, ArgFormatter_> &f,
internal::FormatBuf<Char> format_buf(buffer); internal::FormatBuf<Char> format_buf(buffer);
std::basic_ostream<Char> output(&format_buf); std::basic_ostream<Char> output(&format_buf);
output.exceptions(std::ios_base::failbit | std::ios_base::badbit);
output << value; output << value;
BasicStringRef<Char> str(&buffer[0], buffer.size()); BasicStringRef<Char> str(&buffer[0], buffer.size());
......
...@@ -152,7 +152,7 @@ public: ...@@ -152,7 +152,7 @@ public:
visit_any_int(value); visit_any_int(value);
} }
void visit_char(char value) void visit_char(int value)
{ {
if (type_ != 's') if (type_ != 's')
visit_any_int(value); visit_any_int(value);
...@@ -170,7 +170,7 @@ public: ...@@ -170,7 +170,7 @@ public:
using internal::Arg; using internal::Arg;
typedef typename internal::Conditional< typedef typename internal::Conditional<
is_same<T, void>::value, U, T>::type TargetType; is_same<T, void>::value, U, T>::type TargetType;
if (sizeof(TargetType) <= sizeof(int)) if (const_check(sizeof(TargetType) <= sizeof(int)))
{ {
// Extra casts are used to silence warnings. // Extra casts are used to silence warnings.
if (is_signed) if (is_signed)
......
...@@ -21,19 +21,20 @@ class flag_formatter; ...@@ -21,19 +21,20 @@ class flag_formatter;
class formatter class formatter
{ {
public: public:
virtual ~formatter() {} virtual ~formatter() = default;
virtual void format(details::log_msg& msg) = 0; virtual void format(details::log_msg& msg) = 0;
}; };
class pattern_formatter SPDLOG_FINAL : public formatter class pattern_formatter SPDLOG_FINAL : public formatter
{ {
public: public:
explicit pattern_formatter(const std::string& pattern, pattern_time_type pattern_time = pattern_time_type::local); explicit pattern_formatter(const std::string& pattern, pattern_time_type pattern_time = pattern_time_type::local, std::string eol = spdlog::details::os::default_eol);
pattern_formatter(const pattern_formatter&) = delete; pattern_formatter(const pattern_formatter&) = delete;
pattern_formatter& operator=(const pattern_formatter&) = delete; pattern_formatter& operator=(const pattern_formatter&) = delete;
void format(details::log_msg& msg) override; void format(details::log_msg& msg) override;
private: private:
const std::string _eol;
const std::string _pattern; const std::string _pattern;
const pattern_time_type _pattern_time; const pattern_time_type _pattern_time;
std::vector<std::unique_ptr<details::flag_formatter>> _formatters; std::vector<std::unique_ptr<details::flag_formatter>> _formatters;
...@@ -44,4 +45,3 @@ private: ...@@ -44,4 +45,3 @@ private:
} }
#include "details/pattern_formatter_impl.h" #include "details/pattern_formatter_impl.h"
...@@ -25,16 +25,17 @@ namespace spdlog ...@@ -25,16 +25,17 @@ namespace spdlog
class logger class logger
{ {
public: public:
logger(const std::string& logger_name, sink_ptr single_sink); logger(const std::string& name, sink_ptr single_sink);
logger(const std::string& name, sinks_init_list); logger(const std::string& name, sinks_init_list sinks);
template<class It>
logger(const std::string& name, const It& begin, const It& end); template <class It>
logger(std::string name, const It& begin, const It& end);
virtual ~logger(); virtual ~logger();
logger(const logger&) = delete; logger(const logger&) = delete;
logger& operator=(const logger&) = delete; logger& operator=(const logger&) = delete;
template <typename... Args> void log(level::level_enum lvl, const char* fmt, const Args&... args); template <typename... Args> void log(level::level_enum lvl, const char* fmt, const Args&... args);
template <typename... Args> void log(level::level_enum lvl, const char* msg); template <typename... Args> void log(level::level_enum lvl, const char* msg);
template <typename Arg1, typename... Args> void trace(const char* fmt, const Arg1&, const Args&... args); template <typename Arg1, typename... Args> void trace(const char* fmt, const Arg1&, const Args&... args);
...@@ -44,7 +45,6 @@ public: ...@@ -44,7 +45,6 @@ public:
template <typename Arg1, typename... Args> void error(const char* fmt, const Arg1&, const Args&... args); template <typename Arg1, typename... Args> void error(const char* fmt, const Arg1&, const Args&... args);
template <typename Arg1, typename... Args> void critical(const char* fmt, const Arg1&, const Args&... args); template <typename Arg1, typename... Args> void critical(const char* fmt, const Arg1&, const Args&... args);
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
template <typename... Args> void log(level::level_enum lvl, const wchar_t* msg); template <typename... Args> void log(level::level_enum lvl, const wchar_t* msg);
template <typename... Args> void log(level::level_enum lvl, const wchar_t* fmt, const Args&... args); template <typename... Args> void log(level::level_enum lvl, const wchar_t* fmt, const Args&... args);
...@@ -57,19 +57,19 @@ public: ...@@ -57,19 +57,19 @@ public:
#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT #endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
template <typename T> void log(level::level_enum lvl, const T&); template <typename T> void log(level::level_enum lvl, const T&);
template <typename T> void trace(const T&); template <typename T> void trace(const T& msg);
template <typename T> void debug(const T&); template <typename T> void debug(const T& msg);
template <typename T> void info(const T&); template <typename T> void info(const T& msg);
template <typename T> void warn(const T&); template <typename T> void warn(const T& msg);
template <typename T> void error(const T&); template <typename T> void error(const T& msg);
template <typename T> void critical(const T&); template <typename T> void critical(const T& msg);
bool should_log(level::level_enum) const; bool should_log(level::level_enum msg_level) const;
void set_level(level::level_enum); void set_level(level::level_enum log_level);
level::level_enum level() const; level::level_enum level() const;
const std::string& name() const; const std::string& name() const;
void set_pattern(const std::string&, pattern_time_type = pattern_time_type::local); void set_pattern(const std::string& pattern, pattern_time_type pattern_time = pattern_time_type::local);
void set_formatter(formatter_ptr); void set_formatter(formatter_ptr msg_formatter);
// automatically call flush() if message level >= log_level // automatically call flush() if message level >= log_level
void flush_on(level::level_enum log_level); void flush_on(level::level_enum log_level);
...@@ -79,22 +79,22 @@ public: ...@@ -79,22 +79,22 @@ public:
const std::vector<sink_ptr>& sinks() const; const std::vector<sink_ptr>& sinks() const;
// error handler // error handler
virtual void set_error_handler(log_err_handler); virtual void set_error_handler(log_err_handler err_handler);
virtual log_err_handler error_handler(); virtual log_err_handler error_handler();
protected: protected:
virtual void _sink_it(details::log_msg&); virtual void _sink_it(details::log_msg& msg);
virtual void _set_pattern(const std::string&, pattern_time_type); virtual void _set_pattern(const std::string& pattern, pattern_time_type pattern_time);
virtual void _set_formatter(formatter_ptr); virtual void _set_formatter(formatter_ptr msg_formatter);
// default error handler: print the error to stderr with the max rate of 1 message/minute // default error handler: print the error to stderr with the max rate of 1 message/minute
virtual void _default_err_handler(const std::string &msg); virtual void _default_err_handler(const std::string &msg);
// return true if the given message level should trigger a flush // return true if the given message level should trigger a flush
bool _should_flush_on(const details::log_msg&); bool _should_flush_on(const details::log_msg& msg);
// increment the message count (only if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)) // increment the message count (only if defined(SPDLOG_ENABLE_MESSAGE_COUNTER))
void _incr_msg_counter(details::log_msg &msg); void _incr_msg_counter(details::log_msg& msg);
const std::string _name; const std::string _name;
std::vector<sink_ptr> _sinks; std::vector<sink_ptr> _sinks;
......
...@@ -23,10 +23,10 @@ namespace sinks ...@@ -23,10 +23,10 @@ namespace sinks
* If no color terminal detected, omit the escape codes. * If no color terminal detected, omit the escape codes.
*/ */
template <class Mutex> template <class Mutex>
class ansicolor_sink: public base_sink<Mutex> class ansicolor_sink : public base_sink<Mutex>
{ {
public: public:
ansicolor_sink(FILE* file): target_file_(file) explicit ansicolor_sink(FILE* file) : target_file_(file)
{ {
should_do_colors_ = details::os::in_terminal(file) && details::os::is_color_terminal(); should_do_colors_ = details::os::in_terminal(file) && details::os::is_color_terminal();
colors_[level::trace] = cyan; colors_[level::trace] = cyan;
...@@ -37,7 +37,8 @@ public: ...@@ -37,7 +37,8 @@ public:
colors_[level::critical] = bold + on_red; colors_[level::critical] = bold + on_red;
colors_[level::off] = reset; colors_[level::off] = reset;
} }
virtual ~ansicolor_sink()
~ansicolor_sink() override
{ {
_flush(); _flush();
} }
...@@ -79,7 +80,7 @@ public: ...@@ -79,7 +80,7 @@ public:
const std::string on_white = "\033[47m"; const std::string on_white = "\033[47m";
protected: protected:
virtual void _sink_it(const details::log_msg& msg) override void _sink_it(const details::log_msg& msg) override
{ {
// Wrap the originally formatted message in color codes. // Wrap the originally formatted message in color codes.
// If color is not supported in the terminal, log as is instead. // If color is not supported in the terminal, log as is instead.
...@@ -102,6 +103,7 @@ protected: ...@@ -102,6 +103,7 @@ protected:
{ {
fflush(target_file_); fflush(target_file_);
} }
FILE* target_file_; FILE* target_file_;
bool should_do_colors_; bool should_do_colors_;
std::unordered_map<level::level_enum, std::string, level::level_hasher> colors_; std::unordered_map<level::level_enum, std::string, level::level_hasher> colors_;
...@@ -116,6 +118,9 @@ public: ...@@ -116,6 +118,9 @@ public:
{} {}
}; };
using ansicolor_stdout_sink_mt = ansicolor_stdout_sink<std::mutex>;
using ansicolor_stdout_sink_st = ansicolor_stdout_sink<details::null_mutex>;
template<class Mutex> template<class Mutex>
class ansicolor_stderr_sink: public ansicolor_sink<Mutex> class ansicolor_stderr_sink: public ansicolor_sink<Mutex>
{ {
...@@ -124,11 +129,8 @@ public: ...@@ -124,11 +129,8 @@ public:
{} {}
}; };
typedef ansicolor_stdout_sink<std::mutex> ansicolor_stdout_sink_mt; using ansicolor_stderr_sink_mt = ansicolor_stderr_sink<std::mutex>;
typedef ansicolor_stdout_sink<details::null_mutex> ansicolor_stdout_sink_st; using ansicolor_stderr_sink_st = ansicolor_stderr_sink<details::null_mutex>;
typedef ansicolor_stderr_sink<std::mutex> ansicolor_stderr_sink_mt;
typedef ansicolor_stderr_sink<details::null_mutex> ansicolor_stderr_sink_st;
} // namespace sinks } // namespace sinks
} // namespace spdlog } // namespace spdlog
......
...@@ -22,11 +22,10 @@ namespace spdlog ...@@ -22,11 +22,10 @@ namespace spdlog
namespace sinks namespace sinks
{ {
template<class Mutex> template<class Mutex>
class base_sink:public sink class base_sink : public sink
{ {
public: public:
base_sink():_mutex() {} base_sink() = default;
virtual ~base_sink() = default;
base_sink(const base_sink&) = delete; base_sink(const base_sink&) = delete;
base_sink& operator=(const base_sink&) = delete; base_sink& operator=(const base_sink&) = delete;
...@@ -36,6 +35,7 @@ public: ...@@ -36,6 +35,7 @@ public:
std::lock_guard<Mutex> lock(_mutex); std::lock_guard<Mutex> lock(_mutex);
_sink_it(msg); _sink_it(msg);
} }
void flush() SPDLOG_FINAL override void flush() SPDLOG_FINAL override
{ {
std::lock_guard<Mutex> lock(_mutex); std::lock_guard<Mutex> lock(_mutex);
......
...@@ -22,13 +22,12 @@ namespace spdlog ...@@ -22,13 +22,12 @@ namespace spdlog
namespace sinks namespace sinks
{ {
template<class Mutex> template<class Mutex>
class dist_sink: public base_sink<Mutex> class dist_sink : public base_sink<Mutex>
{ {
public: public:
explicit dist_sink() :_sinks() {} explicit dist_sink() :_sinks() {}
dist_sink(const dist_sink&) = delete; dist_sink(const dist_sink&) = delete;
dist_sink& operator=(const dist_sink&) = delete; dist_sink& operator=(const dist_sink&) = delete;
virtual ~dist_sink() = default;
protected: protected:
std::vector<std::shared_ptr<sink>> _sinks; std::vector<std::shared_ptr<sink>> _sinks;
...@@ -51,8 +50,6 @@ protected: ...@@ -51,8 +50,6 @@ protected:
} }
public: public:
void add_sink(std::shared_ptr<sink> sink) void add_sink(std::shared_ptr<sink> sink)
{ {
std::lock_guard<Mutex> lock(base_sink<Mutex>::_mutex); std::lock_guard<Mutex> lock(base_sink<Mutex>::_mutex);
...@@ -66,7 +63,8 @@ public: ...@@ -66,7 +63,8 @@ public:
} }
}; };
typedef dist_sink<std::mutex> dist_sink_mt; using dist_sink_mt = dist_sink<std::mutex>;
typedef dist_sink<details::null_mutex> dist_sink_st; using dist_sink_st = dist_sink<details::null_mutex>;
} }
} }
...@@ -25,8 +25,8 @@ namespace sinks ...@@ -25,8 +25,8 @@ namespace sinks
/* /*
* Trivial file sink with single file as target * Trivial file sink with single file as target
*/ */
template<class Mutex> template <class Mutex>
class simple_file_sink SPDLOG_FINAL : public base_sink < Mutex > class simple_file_sink SPDLOG_FINAL : public base_sink<Mutex>
{ {
public: public:
explicit simple_file_sink(const filename_t &filename, bool truncate = false):_force_flush(false) explicit simple_file_sink(const filename_t &filename, bool truncate = false):_force_flush(false)
...@@ -46,32 +46,32 @@ protected: ...@@ -46,32 +46,32 @@ protected:
if(_force_flush) if(_force_flush)
_file_helper.flush(); _file_helper.flush();
} }
void _flush() override void _flush() override
{ {
_file_helper.flush(); _file_helper.flush();
} }
private: private:
details::file_helper _file_helper; details::file_helper _file_helper;
bool _force_flush; bool _force_flush;
}; };
typedef simple_file_sink<std::mutex> simple_file_sink_mt; using simple_file_sink_mt = simple_file_sink<std::mutex>;
typedef simple_file_sink<details::null_mutex> simple_file_sink_st; using simple_file_sink_st = simple_file_sink<details::null_mutex>;
/* /*
* Rotating file sink based on size * Rotating file sink based on size
*/ */
template<class Mutex> template <class Mutex>
class rotating_file_sink SPDLOG_FINAL : public base_sink < Mutex > class rotating_file_sink SPDLOG_FINAL : public base_sink<Mutex>
{ {
public: public:
rotating_file_sink(const filename_t &base_filename, rotating_file_sink(filename_t base_filename,
std::size_t max_size, std::size_t max_files) : std::size_t max_size, std::size_t max_files) :
_base_filename(base_filename), _base_filename(std::move(base_filename)),
_max_size(max_size), _max_size(max_size),
_max_files(max_files), _max_files(max_files)
_current_size(0),
_file_helper()
{ {
_file_helper.open(calc_filename(_base_filename, 0)); _file_helper.open(calc_filename(_base_filename, 0));
_current_size = _file_helper.size(); //expensive. called only once _current_size = _file_helper.size(); //expensive. called only once
...@@ -81,8 +81,8 @@ public: ...@@ -81,8 +81,8 @@ public:
// e.g. calc_filename("logs/mylog.txt, 3) => "logs/mylog.3.txt". // e.g. calc_filename("logs/mylog.txt, 3) => "logs/mylog.3.txt".
static filename_t calc_filename(const filename_t& filename, std::size_t index) static filename_t calc_filename(const filename_t& filename, std::size_t index)
{ {
std::conditional<std::is_same<filename_t::value_type, char>::value, fmt::MemoryWriter, fmt::WMemoryWriter>::type w; typename std::conditional<std::is_same<filename_t::value_type, char>::value, fmt::MemoryWriter, fmt::WMemoryWriter>::type w;
if (index) if (index != 0u)
{ {
filename_t basename, ext; filename_t basename, ext;
std::tie(basename, ext) = details::file_helper::split_by_extenstion(filename); std::tie(basename, ext) = details::file_helper::split_by_extenstion(filename);
...@@ -112,7 +112,6 @@ protected: ...@@ -112,7 +112,6 @@ protected:
_file_helper.flush(); _file_helper.flush();
} }
private: private:
// Rotate files: // Rotate files:
// log.txt -> log.1.txt // log.txt -> log.1.txt
...@@ -135,13 +134,14 @@ private: ...@@ -135,13 +134,14 @@ private:
throw spdlog_ex("rotating_file_sink: failed removing " + filename_to_str(target), errno); throw spdlog_ex("rotating_file_sink: failed removing " + filename_to_str(target), errno);
} }
} }
if (details::file_helper::file_exists(src) && details::os::rename(src, target)) if (details::file_helper::file_exists(src) && details::os::rename(src, target) != 0)
{ {
throw spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), errno); throw spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target), errno);
} }
} }
_file_helper.reopen(true); _file_helper.reopen(true);
} }
filename_t _base_filename; filename_t _base_filename;
std::size_t _max_size; std::size_t _max_size;
std::size_t _max_files; std::size_t _max_files;
...@@ -149,8 +149,8 @@ private: ...@@ -149,8 +149,8 @@ private:
details::file_helper _file_helper; details::file_helper _file_helper;
}; };
typedef rotating_file_sink<std::mutex> rotating_file_sink_mt; using rotating_file_sink_mt = rotating_file_sink<std::mutex>;
typedef rotating_file_sink<details::null_mutex>rotating_file_sink_st; using rotating_file_sink_st = rotating_file_sink<details::null_mutex>;
/* /*
* Default generator of daily log file names. * Default generator of daily log file names.
...@@ -195,9 +195,10 @@ class daily_file_sink SPDLOG_FINAL :public base_sink < Mutex > ...@@ -195,9 +195,10 @@ class daily_file_sink SPDLOG_FINAL :public base_sink < Mutex >
public: public:
//create daily file sink which rotates on given time //create daily file sink which rotates on given time
daily_file_sink( daily_file_sink(
const filename_t& base_filename, filename_t base_filename,
int rotation_hour, int rotation_hour,
int rotation_minute) : _base_filename(base_filename), int rotation_minute) :
_base_filename(std::move(base_filename)),
_rotation_h(rotation_hour), _rotation_h(rotation_hour),
_rotation_m(rotation_minute) _rotation_m(rotation_minute)
{ {
...@@ -235,9 +236,10 @@ private: ...@@ -235,9 +236,10 @@ private:
date.tm_sec = 0; date.tm_sec = 0;
auto rotation_time = std::chrono::system_clock::from_time_t(std::mktime(&date)); auto rotation_time = std::chrono::system_clock::from_time_t(std::mktime(&date));
if (rotation_time > now) if (rotation_time > now)
{
return rotation_time; return rotation_time;
else }
return std::chrono::system_clock::time_point(rotation_time + std::chrono::hours(24)); return{ rotation_time + std::chrono::hours(24) };
} }
filename_t _base_filename; filename_t _base_filename;
...@@ -247,7 +249,8 @@ private: ...@@ -247,7 +249,8 @@ private:
details::file_helper _file_helper; details::file_helper _file_helper;
}; };
typedef daily_file_sink<std::mutex> daily_file_sink_mt; using daily_file_sink_mt = daily_file_sink<std::mutex>;
typedef daily_file_sink<details::null_mutex> daily_file_sink_st; using daily_file_sink_st = daily_file_sink<details::null_mutex>;
} }
} }
...@@ -23,15 +23,13 @@ namespace sinks ...@@ -23,15 +23,13 @@ namespace sinks
* MSVC sink (logging using OutputDebugStringA) * MSVC sink (logging using OutputDebugStringA)
*/ */
template<class Mutex> template<class Mutex>
class msvc_sink : public base_sink < Mutex > class msvc_sink : public base_sink<Mutex>
{ {
public: public:
explicit msvc_sink() explicit msvc_sink()
{ {
} }
protected: protected:
void _sink_it(const details::log_msg& msg) override void _sink_it(const details::log_msg& msg) override
{ {
...@@ -42,8 +40,8 @@ protected: ...@@ -42,8 +40,8 @@ protected:
{} {}
}; };
typedef msvc_sink<std::mutex> msvc_sink_mt; using msvc_sink_mt = msvc_sink<std::mutex>;
typedef msvc_sink<details::null_mutex> msvc_sink_st; using msvc_sink_st = msvc_sink<details::null_mutex>;
} }
} }
......
...@@ -16,7 +16,7 @@ namespace sinks ...@@ -16,7 +16,7 @@ namespace sinks
{ {
template <class Mutex> template <class Mutex>
class null_sink : public base_sink < Mutex > class null_sink : public base_sink<Mutex>
{ {
protected: protected:
void _sink_it(const details::log_msg&) override void _sink_it(const details::log_msg&) override
...@@ -26,8 +26,9 @@ protected: ...@@ -26,8 +26,9 @@ protected:
{} {}
}; };
typedef null_sink<details::null_mutex> null_sink_st;
typedef null_sink<details::null_mutex> null_sink_mt; using null_sink_mt = null_sink<details::null_mutex>;
using null_sink_st = null_sink<details::null_mutex>;
} }
} }
......
...@@ -16,13 +16,12 @@ namespace spdlog ...@@ -16,13 +16,12 @@ namespace spdlog
namespace sinks namespace sinks
{ {
template<class Mutex> template<class Mutex>
class ostream_sink: public base_sink<Mutex> class ostream_sink : public base_sink<Mutex>
{ {
public: public:
explicit ostream_sink(std::ostream& os, bool force_flush=false) :_ostream(os), _force_flush(force_flush) {} explicit ostream_sink(std::ostream& os, bool force_flush=false) :_ostream(os), _force_flush(force_flush) {}
ostream_sink(const ostream_sink&) = delete; ostream_sink(const ostream_sink&) = delete;
ostream_sink& operator=(const ostream_sink&) = delete; ostream_sink& operator=(const ostream_sink&) = delete;
virtual ~ostream_sink() = default;
protected: protected:
void _sink_it(const details::log_msg& msg) override void _sink_it(const details::log_msg& msg) override
...@@ -41,7 +40,8 @@ protected: ...@@ -41,7 +40,8 @@ protected:
bool _force_flush; bool _force_flush;
}; };
typedef ostream_sink<std::mutex> ostream_sink_mt; using ostream_sink_mt = ostream_sink<std::mutex>;
typedef ostream_sink<details::null_mutex> ostream_sink_st; using ostream_sink_st = ostream_sink<details::null_mutex>;
} }
} }
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
// Distributed under the MIT License (http://opensource.org/licenses/MIT) // Distributed under the MIT License (http://opensource.org/licenses/MIT)
// //
#pragma once #pragma once
#include "../details/log_msg.h" #include "../details/log_msg.h"
...@@ -15,12 +14,8 @@ namespace sinks ...@@ -15,12 +14,8 @@ namespace sinks
class sink class sink
{ {
public: public:
sink() virtual ~sink() = default;
{
_level = level::trace;
}
virtual ~sink() {}
virtual void log(const details::log_msg& msg) = 0; virtual void log(const details::log_msg& msg) = 0;
virtual void flush() = 0; virtual void flush() = 0;
...@@ -29,8 +24,7 @@ public: ...@@ -29,8 +24,7 @@ public:
level::level_enum level() const; level::level_enum level() const;
private: private:
level_t _level; level_t _level{ level::trace };
}; };
inline bool sink::should_log(level::level_enum msg_level) const inline bool sink::should_log(level::level_enum msg_level) const
...@@ -50,4 +44,3 @@ inline level::level_enum sink::level() const ...@@ -50,4 +44,3 @@ inline level::level_enum sink::level() const
} }
} }
...@@ -21,14 +21,16 @@ template <class Mutex> ...@@ -21,14 +21,16 @@ template <class Mutex>
class stdout_sink SPDLOG_FINAL : public base_sink<Mutex> class stdout_sink SPDLOG_FINAL : public base_sink<Mutex>
{ {
using MyType = stdout_sink<Mutex>; using MyType = stdout_sink<Mutex>;
public: public:
stdout_sink() explicit stdout_sink() = default;
{}
static std::shared_ptr<MyType> instance() static std::shared_ptr<MyType> instance()
{ {
static std::shared_ptr<MyType> instance = std::make_shared<MyType>(); static std::shared_ptr<MyType> instance = std::make_shared<MyType>();
return instance; return instance;
} }
protected: protected:
void _sink_it(const details::log_msg& msg) override void _sink_it(const details::log_msg& msg) override
{ {
...@@ -42,22 +44,23 @@ protected: ...@@ -42,22 +44,23 @@ protected:
} }
}; };
typedef stdout_sink<details::null_mutex> stdout_sink_st; using stdout_sink_mt = stdout_sink<std::mutex>;
typedef stdout_sink<std::mutex> stdout_sink_mt; using stdout_sink_st = stdout_sink<details::null_mutex>;
template <class Mutex> template <class Mutex>
class stderr_sink SPDLOG_FINAL : public base_sink<Mutex> class stderr_sink SPDLOG_FINAL : public base_sink<Mutex>
{ {
using MyType = stderr_sink<Mutex>; using MyType = stderr_sink<Mutex>;
public: public:
stderr_sink() explicit stderr_sink() = default;
{}
static std::shared_ptr<MyType> instance() static std::shared_ptr<MyType> instance()
{ {
static std::shared_ptr<MyType> instance = std::make_shared<MyType>(); static std::shared_ptr<MyType> instance = std::make_shared<MyType>();
return instance; return instance;
} }
protected: protected:
void _sink_it(const details::log_msg& msg) override void _sink_it(const details::log_msg& msg) override
{ {
...@@ -71,7 +74,8 @@ protected: ...@@ -71,7 +74,8 @@ protected:
} }
}; };
typedef stderr_sink<std::mutex> stderr_sink_mt; using stderr_sink_mt = stderr_sink<std::mutex>;
typedef stderr_sink<details::null_mutex> stderr_sink_st; using stderr_sink_st = stderr_sink<details::null_mutex>;
} }
} }
...@@ -33,18 +33,19 @@ public: ...@@ -33,18 +33,19 @@ public:
syslog_sink(const std::string& ident = "", int syslog_option=0, int syslog_facility=LOG_USER): syslog_sink(const std::string& ident = "", int syslog_option=0, int syslog_facility=LOG_USER):
_ident(ident) _ident(ident)
{ {
_priorities[static_cast<int>(level::trace)] = LOG_DEBUG; _priorities[static_cast<size_t>(level::trace)] = LOG_DEBUG;
_priorities[static_cast<int>(level::debug)] = LOG_DEBUG; _priorities[static_cast<size_t>(level::debug)] = LOG_DEBUG;
_priorities[static_cast<int>(level::info)] = LOG_INFO; _priorities[static_cast<size_t>(level::info)] = LOG_INFO;
_priorities[static_cast<int>(level::warn)] = LOG_WARNING; _priorities[static_cast<size_t>(level::warn)] = LOG_WARNING;
_priorities[static_cast<int>(level::err)] = LOG_ERR; _priorities[static_cast<size_t>(level::err)] = LOG_ERR;
_priorities[static_cast<int>(level::critical)] = LOG_CRIT; _priorities[static_cast<size_t>(level::critical)] = LOG_CRIT;
_priorities[static_cast<int>(level::off)] = LOG_INFO; _priorities[static_cast<size_t>(level::off)] = LOG_INFO;
//set ident to be program name if empty //set ident to be program name if empty
::openlog(_ident.empty()? nullptr:_ident.c_str(), syslog_option, syslog_facility); ::openlog(_ident.empty()? nullptr:_ident.c_str(), syslog_option, syslog_facility);
} }
~syslog_sink()
~syslog_sink() override
{ {
::closelog(); ::closelog();
} }
...@@ -72,7 +73,7 @@ private: ...@@ -72,7 +73,7 @@ private:
// //
int syslog_prio_from_level(const details::log_msg &msg) const int syslog_prio_from_level(const details::log_msg &msg) const
{ {
return _priorities[static_cast<int>(msg.level)]; return _priorities[static_cast<size_t>(msg.level)];
} }
}; };
} }
......
...@@ -21,8 +21,8 @@ namespace sinks ...@@ -21,8 +21,8 @@ namespace sinks
/* /*
* Windows color console sink. Uses WriteConsoleA to write to the console with colors * Windows color console sink. Uses WriteConsoleA to write to the console with colors
*/ */
template<class Mutex> template <class Mutex>
class wincolor_sink: public base_sink<Mutex> class wincolor_sink : public base_sink<Mutex>
{ {
public: public:
const WORD BOLD = FOREGROUND_INTENSITY; const WORD BOLD = FOREGROUND_INTENSITY;
...@@ -42,7 +42,7 @@ public: ...@@ -42,7 +42,7 @@ public:
colors_[level::off] = 0; colors_[level::off] = 0;
} }
virtual ~wincolor_sink() ~wincolor_sink() override
{ {
this->flush(); this->flush();
} }
...@@ -50,8 +50,15 @@ public: ...@@ -50,8 +50,15 @@ public:
wincolor_sink(const wincolor_sink& other) = delete; wincolor_sink(const wincolor_sink& other) = delete;
wincolor_sink& operator=(const wincolor_sink& other) = delete; wincolor_sink& operator=(const wincolor_sink& other) = delete;
// change the color for the given level
void set_color(level::level_enum level, WORD color)
{
std::lock_guard<Mutex> lock(base_sink<Mutex>::_mutex);
colors_[level] = color;
}
protected: protected:
virtual void _sink_it(const details::log_msg& msg) override void _sink_it(const details::log_msg& msg) override
{ {
auto color = colors_[msg.level]; auto color = colors_[msg.level];
auto orig_attribs = set_console_attribs(color); auto orig_attribs = set_console_attribs(color);
...@@ -59,18 +66,11 @@ protected: ...@@ -59,18 +66,11 @@ protected:
SetConsoleTextAttribute(out_handle_, orig_attribs); //reset to orig colors SetConsoleTextAttribute(out_handle_, orig_attribs); //reset to orig colors
} }
virtual void _flush() override void _flush() override
{ {
// windows console always flushed? // windows console always flushed?
} }
// change the color for the given level
void set_color(level::level_enum level, WORD color)
{
std::lock_guard<Mutex> lock(base_sink<Mutex>::_mutex);
colors_[level] = color;
}
private: private:
HANDLE out_handle_; HANDLE out_handle_;
std::unordered_map<level::level_enum, WORD, level::level_hasher> colors_; std::unordered_map<level::level_enum, WORD, level::level_hasher> colors_;
...@@ -92,30 +92,30 @@ private: ...@@ -92,30 +92,30 @@ private:
// //
// windows color console to stdout // windows color console to stdout
// //
template<class Mutex> template <class Mutex>
class wincolor_stdout_sink: public wincolor_sink<Mutex> class wincolor_stdout_sink : public wincolor_sink<Mutex>
{ {
public: public:
wincolor_stdout_sink() : wincolor_sink<Mutex>(GetStdHandle(STD_OUTPUT_HANDLE)) wincolor_stdout_sink() : wincolor_sink<Mutex>(GetStdHandle(STD_OUTPUT_HANDLE))
{} {}
}; };
typedef wincolor_stdout_sink<std::mutex> wincolor_stdout_sink_mt; using wincolor_stdout_sink_mt = wincolor_stdout_sink<std::mutex>;
typedef wincolor_stdout_sink<details::null_mutex> wincolor_stdout_sink_st; using wincolor_stdout_sink_st = wincolor_stdout_sink<details::null_mutex>;
// //
// windows color console to stderr // windows color console to stderr
// //
template<class Mutex> template <class Mutex>
class wincolor_stderr_sink: public wincolor_sink<Mutex> class wincolor_stderr_sink : public wincolor_sink<Mutex>
{ {
public: public:
wincolor_stderr_sink() : wincolor_sink<Mutex>(GetStdHandle(STD_ERROR_HANDLE)) wincolor_stderr_sink() : wincolor_sink<Mutex>(GetStdHandle(STD_ERROR_HANDLE))
{} {}
}; };
typedef wincolor_stderr_sink<std::mutex> wincolor_stderr_sink_mt; using wincolor_stderr_sink_mt = wincolor_stderr_sink<std::mutex>;
typedef wincolor_stderr_sink<details::null_mutex> wincolor_stderr_sink_st; using wincolor_stderr_sink_st = wincolor_stderr_sink<details::null_mutex>;
} }
} }
...@@ -17,11 +17,11 @@ namespace sinks ...@@ -17,11 +17,11 @@ namespace sinks
/* /*
* Windows debug sink (logging using OutputDebugStringA, synonym for msvc_sink) * Windows debug sink (logging using OutputDebugStringA, synonym for msvc_sink)
*/ */
template<class Mutex> template <class Mutex>
using windebug_sink = msvc_sink<Mutex>; using windebug_sink = msvc_sink<Mutex>;
typedef msvc_sink_mt windebug_sink_mt; using windebug_sink_mt = msvc_sink_mt;
typedef msvc_sink_st windebug_sink_st; using windebug_sink_st = msvc_sink_st;
} }
} }
......
...@@ -7,9 +7,7 @@ ...@@ -7,9 +7,7 @@
#pragma once #pragma once
#define SPDLOG_VERSION "0.16.3"
#include "tweakme.h"
#include "common.h" #include "common.h"
#include "logger.h" #include "logger.h"
...@@ -48,7 +46,7 @@ void flush_on(level::level_enum log_level); ...@@ -48,7 +46,7 @@ void flush_on(level::level_enum log_level);
// //
// Set global error handler // Set global error handler
// //
void set_error_handler(log_err_handler); void set_error_handler(log_err_handler handler);
// //
// Turn on async mode (off by default) and set the queue size for each async_logger. // Turn on async mode (off by default) and set the queue size for each async_logger.
...@@ -131,7 +129,7 @@ std::shared_ptr<logger> create(const std::string& logger_name, const It& sinks_b ...@@ -131,7 +129,7 @@ std::shared_ptr<logger> create(const std::string& logger_name, const It& sinks_b
// Example: // Example:
// spdlog::create<daily_file_sink_st>("mylog", "dailylog_filename"); // spdlog::create<daily_file_sink_st>("mylog", "dailylog_filename");
template <typename Sink, typename... Args> template <typename Sink, typename... Args>
std::shared_ptr<spdlog::logger> create(const std::string& logger_name, Args...); std::shared_ptr<spdlog::logger> create(const std::string& logger_name, Args... args);
// Create and register an async logger with a single sink // Create and register an async logger with a single sink
std::shared_ptr<logger> create_async(const std::string& logger_name, const sink_ptr& sink, size_t queue_size, const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, const std::function<void()>& worker_warmup_cb = nullptr, const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero(), const std::function<void()>& worker_teardown_cb = nullptr); std::shared_ptr<logger> create_async(const std::string& logger_name, const sink_ptr& sink, size_t queue_size, const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, const std::function<void()>& worker_warmup_cb = nullptr, const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero(), const std::function<void()>& worker_teardown_cb = nullptr);
......
project(spdlog-utests) project(spdlog-utests CXX)
enable_testing() enable_testing()
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
...@@ -7,7 +6,8 @@ set(SPDLOG_UTESTS_SOURCES ...@@ -7,7 +6,8 @@ set(SPDLOG_UTESTS_SOURCES
errors.cpp errors.cpp
file_helper.cpp file_helper.cpp
file_log.cpp file_log.cpp
format.cpp test_misc.cpp
test_pattern_formatter
includes.h includes.h
registry.cpp registry.cpp
test_macros.cpp test_macros.cpp
......
CXX ?= g++ CXX ?= g++
ifeq ($(STYLE),printf) ifeq ($(STYLE),printf)
$(info *** PRINTF STYLE ***) $(info *** PRINTF STYLE ***)
CXXFLAGS = -DSPDLOG_FMT_PRINTF -Wall -pedantic -std=c++11 -pthread -O2 -I../include CXXFLAGS = -DSPDLOG_FMT_PRINTF -Wall -pedantic -std=c++11 -pthread -O3 -I../include
else else
$(info *** FORMAT STYLE ***) $(info *** FORMAT STYLE ***)
CXXFLAGS = -Wall -pedantic -std=c++11 -pthread -O2 -I../include CXXFLAGS = -Wall -pedantic -std=c++11 -pthread -O3 -I../include
endif endif
LDPFALGS = -pthread LDPFALGS = -pthread
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
*/ */
#include "includes.h" #include "includes.h"
using namespace spdlog::details; using spdlog::details::log_msg;
using spdlog::details::file_helper;
static const std::string target_filename = "logs/file_helper_test.txt"; static const std::string target_filename = "logs/file_helper_test.txt";
...@@ -15,7 +16,6 @@ static void write_with_helper(file_helper &helper, size_t howmany) ...@@ -15,7 +16,6 @@ static void write_with_helper(file_helper &helper, size_t howmany)
helper.flush(); helper.flush();
} }
TEST_CASE("file_helper_filename", "[file_helper::filename()]]") TEST_CASE("file_helper_filename", "[file_helper::filename()]]")
{ {
prepare_logdir(); prepare_logdir();
...@@ -25,8 +25,6 @@ TEST_CASE("file_helper_filename", "[file_helper::filename()]]") ...@@ -25,8 +25,6 @@ TEST_CASE("file_helper_filename", "[file_helper::filename()]]")
REQUIRE(helper.filename() == target_filename); REQUIRE(helper.filename() == target_filename);
} }
TEST_CASE("file_helper_size", "[file_helper::size()]]") TEST_CASE("file_helper_size", "[file_helper::size()]]")
{ {
prepare_logdir(); prepare_logdir();
...@@ -40,7 +38,6 @@ TEST_CASE("file_helper_size", "[file_helper::size()]]") ...@@ -40,7 +38,6 @@ TEST_CASE("file_helper_size", "[file_helper::size()]]")
REQUIRE(get_filesize(target_filename) == expected_size); REQUIRE(get_filesize(target_filename) == expected_size);
} }
TEST_CASE("file_helper_exists", "[file_helper::file_exists()]]") TEST_CASE("file_helper_exists", "[file_helper::file_exists()]]")
{ {
prepare_logdir(); prepare_logdir();
...@@ -73,8 +70,6 @@ TEST_CASE("file_helper_reopen2", "[file_helper::reopen(false)]]") ...@@ -73,8 +70,6 @@ TEST_CASE("file_helper_reopen2", "[file_helper::reopen(false)]]")
REQUIRE(helper.size() == expected_size); REQUIRE(helper.size() == expected_size);
} }
static void test_split_ext(const char* fname, const char* expect_base, const char* expect_ext) static void test_split_ext(const char* fname, const char* expect_base, const char* expect_ext)
{ {
spdlog::filename_t filename(fname); spdlog::filename_t filename(fname);
...@@ -91,7 +86,6 @@ static void test_split_ext(const char* fname, const char* expect_base, const cha ...@@ -91,7 +86,6 @@ static void test_split_ext(const char* fname, const char* expect_base, const cha
REQUIRE(ext == expected_ext); REQUIRE(ext == expected_ext);
} }
TEST_CASE("file_helper_split_by_extenstion", "[file_helper::split_by_extenstion()]]") TEST_CASE("file_helper_split_by_extenstion", "[file_helper::split_by_extenstion()]]")
{ {
test_split_ext("mylog.txt", "mylog", ".txt"); test_split_ext("mylog.txt", "mylog", ".txt");
...@@ -113,6 +107,3 @@ TEST_CASE("file_helper_split_by_extenstion", "[file_helper::split_by_extenstion( ...@@ -113,6 +107,3 @@ TEST_CASE("file_helper_split_by_extenstion", "[file_helper::split_by_extenstion(
test_split_ext(".", ".", ""); test_split_ext(".", ".", "");
test_split_ext("..txt", ".", ".txt"); test_split_ext("..txt", ".", ".txt");
} }
#include "includes.h" #include "includes.h"
template<class T> template<class T>
...@@ -13,14 +12,9 @@ std::string log_info(const T& what, spdlog::level::level_enum logger_level = spd ...@@ -13,14 +12,9 @@ std::string log_info(const T& what, spdlog::level::level_enum logger_level = spd
oss_logger.set_pattern("%v"); oss_logger.set_pattern("%v");
oss_logger.info(what); oss_logger.info(what);
return oss.str().substr(0, oss.str().length() - spdlog::details::os::eol_size); return oss.str().substr(0, oss.str().length() - strlen(spdlog::details::os::default_eol));
} }
TEST_CASE("basic_logging ", "[basic_logging]") TEST_CASE("basic_logging ", "[basic_logging]")
{ {
//const char //const char
...@@ -39,7 +33,6 @@ TEST_CASE("basic_logging ", "[basic_logging]") ...@@ -39,7 +33,6 @@ TEST_CASE("basic_logging ", "[basic_logging]")
//REQUIRE(log_info(some_logged_class("some_val")) == "some_val"); //REQUIRE(log_info(some_logged_class("some_val")) == "some_val");
} }
TEST_CASE("log_levels", "[log_levels]") TEST_CASE("log_levels", "[log_levels]")
{ {
REQUIRE(log_info("Hello", spdlog::level::err) == ""); REQUIRE(log_info("Hello", spdlog::level::err) == "");
...@@ -54,3 +47,6 @@ TEST_CASE("log_levels", "[log_levels]") ...@@ -54,3 +47,6 @@ TEST_CASE("log_levels", "[log_levels]")
#include "includes.h"
// log to str and return it
static std::string log_to_str(const std::string& msg, const std::shared_ptr<spdlog::formatter>& formatter = nullptr)
{
std::ostringstream oss;
auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss);
spdlog::logger oss_logger("pattern_tester", oss_sink);
oss_logger.set_level(spdlog::level::info);
if (formatter) oss_logger.set_formatter(formatter);
oss_logger.info(msg);
return oss.str();
}
TEST_CASE("custom eol", "[pattern_formatter]")
{
std::string msg = "Hello custom eol test";
std::string eol = ";)";
auto formatter = std::make_shared<spdlog::pattern_formatter>("%v", spdlog::pattern_time_type::local, ";)");
REQUIRE(log_to_str(msg, formatter) == msg + eol);
}
TEST_CASE("empty format", "[pattern_formatter]")
{
auto formatter = std::make_shared<spdlog::pattern_formatter>("", spdlog::pattern_time_type::local, "");
REQUIRE(log_to_str("Some message", formatter) == "");
}
TEST_CASE("empty format2", "[pattern_formatter]")
{
auto formatter = std::make_shared<spdlog::pattern_formatter>("", spdlog::pattern_time_type::local, "\n");
REQUIRE(log_to_str("Some message", formatter) == "\n");
}
TEST_CASE("level", "[pattern_formatter]")
{
auto formatter = std::make_shared<spdlog::pattern_formatter>("[%l] %v", spdlog::pattern_time_type::local, "\n");
REQUIRE(log_to_str("Some message", formatter) == "[info] Some message\n");
}
TEST_CASE("short level", "[pattern_formatter]")
{
auto formatter = std::make_shared<spdlog::pattern_formatter>("[%L] %v", spdlog::pattern_time_type::local, "\n");
REQUIRE(log_to_str("Some message", formatter) == "[I] Some message\n");
}
TEST_CASE("name", "[pattern_formatter]")
{
auto formatter = std::make_shared<spdlog::pattern_formatter>("[%n] %v", spdlog::pattern_time_type::local, "\n");
REQUIRE(log_to_str("Some message", formatter) == "[pattern_tester] Some message\n");
}
TEST_CASE("date MM/DD/YY ", "[pattern_formatter]")
{
auto formatter = std::make_shared<spdlog::pattern_formatter>("%D %v", spdlog::pattern_time_type::local, "\n");
auto now_tm = spdlog::details::os::localtime();
std::stringstream oss;
oss << std::setfill('0') << std::setw(2) << now_tm.tm_mon + 1 << "/" << std::setw(2) << now_tm.tm_mday << "/" << std::setw(2) << (now_tm.tm_year + 1900) % 1000 << " Some message\n";
REQUIRE(log_to_str("Some message", formatter) == oss.str());
}
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{59A07559-5F38-4DD6-A7FA-DB4153690B42}</ProjectGuid> <ProjectGuid>{59A07559-5F38-4DD6-A7FA-DB4153690B42}</ProjectGuid>
<RootNamespace>tests</RootNamespace> <RootNamespace>tests</RootNamespace>
<WindowsTargetPlatformVersion>10.0.16299.0</WindowsTargetPlatformVersion>
</PropertyGroup> </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
...@@ -128,10 +129,11 @@ ...@@ -128,10 +129,11 @@
<ClCompile Include="errors.cpp" /> <ClCompile Include="errors.cpp" />
<ClCompile Include="file_helper.cpp" /> <ClCompile Include="file_helper.cpp" />
<ClCompile Include="file_log.cpp" /> <ClCompile Include="file_log.cpp" />
<ClCompile Include="format.cpp" /> <ClCompile Include="test_misc.cpp" />
<ClCompile Include="main.cpp" /> <ClCompile Include="main.cpp" />
<ClCompile Include="registry.cpp" /> <ClCompile Include="registry.cpp" />
<ClCompile Include="test_macros.cpp" /> <ClCompile Include="test_macros.cpp" />
<ClCompile Include="test_pattern_formatter.cpp" />
<ClCompile Include="utils.cpp" /> <ClCompile Include="utils.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
......
...@@ -18,9 +18,6 @@ ...@@ -18,9 +18,6 @@
<ClCompile Include="file_log.cpp"> <ClCompile Include="file_log.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="format.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="main.cpp"> <ClCompile Include="main.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
...@@ -39,6 +36,12 @@ ...@@ -39,6 +36,12 @@
<ClCompile Include="test_macros.cpp"> <ClCompile Include="test_macros.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="test_pattern_formatter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="test_misc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="includes.h"> <ClInclude Include="includes.h">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment