Merge pull request #3 from gabime/v1.x

update 20190522
pull/1084/head
CodingTrader 6 years ago committed by GitHub
commit c9c3373ba9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,7 +4,7 @@
# #
cmake_minimum_required(VERSION 3.1) cmake_minimum_required(VERSION 3.1)
project(spdlog VERSION 1.3.0 LANGUAGES CXX) project(spdlog VERSION 1.3.1 LANGUAGES CXX)
include(CMakeDependentOption) include(CMakeDependentOption)
include(GNUInstallDirs) include(GNUInstallDirs)
@ -30,7 +30,6 @@ if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCH
add_compile_options("-Wconversion") add_compile_options("-Wconversion")
add_compile_options("-pedantic") add_compile_options("-pedantic")
add_compile_options("-Wfatal-errors") add_compile_options("-Wfatal-errors")
endif() endif()
#--------------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------
@ -51,13 +50,11 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
endif() endif()
option(SPDLOG_BUILD_EXAMPLES "Build examples" ${SPDLOG_MASTER_PROJECT}) option(SPDLOG_BUILD_EXAMPLES "Build examples" ${SPDLOG_MASTER_PROJECT})
option(SPDLOG_BUILD_BENCH "Build benchmarks" ${SPDLOG_MASTER_PROJECT}) option(SPDLOG_BUILD_BENCH "Build benchmarks (Requires https://github.com/google/benchmark.git to be installed)" OFF)
option(SPDLOG_BUILD_TESTS "Build tests" ${SPDLOG_MASTER_PROJECT}) option(SPDLOG_BUILD_TESTS "Build tests" ${SPDLOG_MASTER_PROJECT})
option(SPDLOG_FMT_EXTERNAL "Use external fmt library instead of bundled" OFF) option(SPDLOG_FMT_EXTERNAL "Use external fmt library instead of bundled" OFF)
option(SPDLOG_FMT_HEADER_ONLY "Use header-only variant of external fmt library" ON)
if(SPDLOG_FMT_EXTERNAL) option(SPDLOG_INSTALL "Generate the install target." ${SPDLOG_MASTER_PROJECT})
find_package(fmt REQUIRED CONFIG)
endif()
target_include_directories( target_include_directories(
spdlog spdlog
@ -68,8 +65,17 @@ target_include_directories(
if(SPDLOG_FMT_EXTERNAL) if(SPDLOG_FMT_EXTERNAL)
target_compile_definitions(spdlog INTERFACE SPDLOG_FMT_EXTERNAL) target_compile_definitions(spdlog INTERFACE SPDLOG_FMT_EXTERNAL)
if(NOT TARGET fmt::fmt)
find_package(fmt REQUIRED CONFIG)
endif()
if(SPDLOG_FMT_HEADER_ONLY)
target_link_libraries(spdlog INTERFACE fmt::fmt-header-only)
else()
target_link_libraries(spdlog INTERFACE fmt::fmt) target_link_libraries(spdlog INTERFACE fmt::fmt)
endif() endif()
endif()
set(HEADER_BASE "${CMAKE_CURRENT_SOURCE_DIR}/include") set(HEADER_BASE "${CMAKE_CURRENT_SOURCE_DIR}/include")
@ -89,14 +95,15 @@ endif()
#--------------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------
# Install/export targets and files # Install/export targets and files
#--------------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------
if(SPDLOG_INSTALL)
# set files and directories # set files and directories
set(config_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") set(config_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
set(include_install_dir "${CMAKE_INSTALL_INCLUDEDIR}") set(include_install_dir "${CMAKE_INSTALL_INCLUDEDIR}")
set(pkgconfig_install_dir "${CMAKE_INSTALL_LIBDIR}/pkgconfig") set(pkgconfig_install_dir "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
set(version_config "${CMAKE_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake") set(version_config "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake")
set(project_config "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake") set(project_config "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake")
set(targets_config "${PROJECT_NAME}Targets.cmake") set(targets_config "${PROJECT_NAME}Targets.cmake")
set(pkg_config "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc") set(pkg_config "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc")
set(targets_export_name "${PROJECT_NAME}Targets") set(targets_export_name "${PROJECT_NAME}Targets")
set(namespace "${PROJECT_NAME}::") set(namespace "${PROJECT_NAME}::")
@ -153,5 +160,7 @@ export(
# register project in CMake user registry # register project in CMake user registry
export(PACKAGE ${PROJECT_NAME}) export(PACKAGE ${PROJECT_NAME})
endif()
file(GLOB_RECURSE spdlog_include_SRCS "${HEADER_BASE}/*.h") file(GLOB_RECURSE spdlog_include_SRCS "${HEADER_BASE}/*.h")
add_custom_target(spdlog_headers_for_ide SOURCES ${spdlog_include_SRCS}) add_custom_target(spdlog_headers_for_ide SOURCES ${spdlog_include_SRCS})

@ -11,7 +11,6 @@ Very fast, header only, C++ logging library. [![Build Status](https://travis-ci.
#### Or use your favorite package manager: #### Or use your favorite package manager:
* Ubuntu: `apt-get install libspdlog-dev`
* Homebrew: `brew install spdlog` * Homebrew: `brew install spdlog`
* FreeBSD: `cd /usr/ports/devel/spdlog/ && make install clean` * FreeBSD: `cd /usr/ports/devel/spdlog/ && make install clean`
* Fedora: `yum install spdlog` * Fedora: `yum install spdlog`
@ -80,6 +79,8 @@ async... Elapsed: 0.349851 2,858,358/sec
#### Basic usage #### Basic usage
```c++ ```c++
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
#include "spdlog/sinks/basic_file_sink.h"
int main() int main()
{ {
spdlog::info("Welcome to spdlog!"); spdlog::info("Welcome to spdlog!");
@ -102,6 +103,9 @@ int main()
SPDLOG_TRACE("Some trace message with param {}", {}); SPDLOG_TRACE("Some trace message with param {}", {});
SPDLOG_DEBUG("Some debug message"); SPDLOG_DEBUG("Some debug message");
// Set the default logger to file logger
auto file_logger = spdlog::basic_logger_mt("basic_logger", "logs/basic.txt");
spdlog::set_default_logger(file_logger);
} }
``` ```
#### create stdout/stderr logger object #### create stdout/stderr logger object
@ -310,7 +314,7 @@ void syslog_example()
void android_example() void android_example()
{ {
std::string tag = "spdlog-android"; std::string tag = "spdlog-android";
auto android_logger = spdlog::android_logger("android", tag); auto android_logger = spdlog::android_logger_mt("android", tag);
android_logger->critical("Use \"adb shell logcat\" to view this message."); android_logger->critical("Use \"adb shell logcat\" to view this message.");
} }
``` ```

@ -125,9 +125,12 @@ enum level_enum
"trace", "debug", "info", "warning", "error", "critical", "off" \ "trace", "debug", "info", "warning", "error", "critical", "off" \
} }
#endif #endif
static string_view_t level_string_views[] SPDLOG_LEVEL_NAMES; static string_view_t level_string_views[] SPDLOG_LEVEL_NAMES;
static const char *short_level_names[]{"T", "D", "I", "W", "E", "C", "O"};
#if !defined(SPDLOG_SHORT_LEVEL_NAMES)
#define SPDLOG_SHORT_LEVEL_NAMES {"T", "D", "I", "W", "E", "C", "O"}
#endif
static const char *short_level_names[] SPDLOG_SHORT_LEVEL_NAMES;
inline string_view_t &to_string_view(spdlog::level::level_enum l) SPDLOG_NOEXCEPT inline string_view_t &to_string_view(spdlog::level::level_enum l) SPDLOG_NOEXCEPT
{ {
@ -156,6 +159,16 @@ inline spdlog::level::level_enum from_str(const std::string &name) SPDLOG_NOEXCE
using level_hasher = std::hash<int>; using level_hasher = std::hash<int>;
} // namespace level } // namespace level
//
// Color mode used by sinks with color support.
//
enum class color_mode
{
always,
automatic,
never
};
// //
// Pattern time - specific time getting to use for pattern_formatter. // Pattern time - specific time getting to use for pattern_formatter.
// local time by default // local time by default
@ -210,10 +223,10 @@ struct source_loc
, funcname{""} , funcname{""}
{ {
} }
SPDLOG_CONSTEXPR source_loc(const char *filename, int line, const char *funcname) SPDLOG_CONSTEXPR source_loc(const char *filename_in, int line_in, const char *funcname_in)
: filename{filename} : filename{filename_in}
, line{static_cast<uint32_t>(line)} , line{static_cast<uint32_t>(line_in)}
, funcname{funcname} , funcname{funcname_in}
{ {
} }

@ -102,6 +102,12 @@ inline void spdlog::logger::log(level::level_enum lvl, const char *msg)
log(source_loc{}, lvl, msg); log(source_loc{}, lvl, msg);
} }
template<class T>
inline void spdlog::logger::log(level::level_enum lvl, const T &msg)
{
log(source_loc{}, lvl, msg);
}
template<class T, typename std::enable_if<std::is_convertible<T, spdlog::string_view_t>::value, T>::type *> template<class T, typename std::enable_if<std::is_convertible<T, spdlog::string_view_t>::value, T>::type *>
inline void spdlog::logger::log(source_loc source, level::level_enum lvl, const T &msg) inline void spdlog::logger::log(source_loc source, level::level_enum lvl, const T &msg)
{ {
@ -117,12 +123,6 @@ inline void spdlog::logger::log(source_loc source, level::level_enum lvl, const
SPDLOG_CATCH_AND_HANDLE SPDLOG_CATCH_AND_HANDLE
} }
template<class T, typename std::enable_if<std::is_convertible<T, spdlog::string_view_t>::value, T>::type *>
inline void spdlog::logger::log(level::level_enum lvl, const T &msg)
{
log(source_loc{}, lvl, msg);
}
template<class T, typename std::enable_if<!std::is_convertible<T, spdlog::string_view_t>::value, T>::type *> template<class T, typename std::enable_if<!std::is_convertible<T, spdlog::string_view_t>::value, T>::type *>
inline void spdlog::logger::log(source_loc source, level::level_enum lvl, const T &msg) inline void spdlog::logger::log(source_loc source, level::level_enum lvl, const T &msg)
{ {
@ -141,12 +141,6 @@ inline void spdlog::logger::log(source_loc source, level::level_enum lvl, const
SPDLOG_CATCH_AND_HANDLE SPDLOG_CATCH_AND_HANDLE
} }
template<class T, typename std::enable_if<!std::is_convertible<T, spdlog::string_view_t>::value, T>::type *>
inline void spdlog::logger::log(level::level_enum lvl, const T &msg)
{
log(source_loc{}, lvl, msg);
}
template<typename... Args> template<typename... Args>
inline void spdlog::logger::trace(const char *fmt, const Args &... args) inline void spdlog::logger::trace(const char *fmt, const Args &... args)
{ {

@ -196,7 +196,7 @@ inline bool file_exists(const filename_t &filename) SPDLOG_NOEXCEPT
return (attribs != INVALID_FILE_ATTRIBUTES && !(attribs & FILE_ATTRIBUTE_DIRECTORY)); return (attribs != INVALID_FILE_ATTRIBUTES && !(attribs & FILE_ATTRIBUTE_DIRECTORY));
#else // common linux/unix all have the stat system call #else // common linux/unix all have the stat system call
struct stat buffer; struct stat buffer;
return (stat(filename.c_str(), &buffer) == 0); return (::stat(filename.c_str(), &buffer) == 0);
#endif #endif
} }
@ -229,14 +229,14 @@ inline size_t filesize(FILE *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
struct stat st; struct stat st;
if (fstat(fd, &st) == 0) if (::fstat(fd, &st) == 0)
{ {
return static_cast<size_t>(st.st_size); return static_cast<size_t>(st.st_size);
} }

@ -352,7 +352,7 @@ class Y_formatter final : public flag_formatter
{ {
public: public:
explicit Y_formatter(padding_info padinfo) explicit Y_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override
{ {
@ -418,7 +418,7 @@ class I_formatter final : public flag_formatter
{ {
public: public:
explicit I_formatter(padding_info padinfo) explicit I_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override
{ {
@ -433,7 +433,7 @@ class M_formatter final : public flag_formatter
{ {
public: public:
explicit M_formatter(padding_info padinfo) explicit M_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override
{ {
@ -448,7 +448,7 @@ class S_formatter final : public flag_formatter
{ {
public: public:
explicit S_formatter(padding_info padinfo) explicit S_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override
{ {
@ -463,7 +463,7 @@ class e_formatter final : public flag_formatter
{ {
public: public:
explicit e_formatter(padding_info padinfo) explicit e_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override
{ {
@ -486,7 +486,7 @@ class f_formatter final : public flag_formatter
{ {
public: public:
explicit f_formatter(padding_info padinfo) explicit f_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override
{ {
@ -509,7 +509,7 @@ class F_formatter final : public flag_formatter
{ {
public: public:
explicit F_formatter(padding_info padinfo) explicit F_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override
{ {
@ -532,7 +532,7 @@ class E_formatter final : public flag_formatter
{ {
public: public:
explicit E_formatter(padding_info padinfo) explicit E_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override
{ {
@ -549,7 +549,7 @@ class p_formatter final : public flag_formatter
{ {
public: public:
explicit p_formatter(padding_info padinfo) explicit p_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override
{ {
@ -564,7 +564,7 @@ class r_formatter final : public flag_formatter
{ {
public: public:
explicit r_formatter(padding_info padinfo) explicit r_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override
{ {
@ -586,7 +586,7 @@ class R_formatter final : public flag_formatter
{ {
public: public:
explicit R_formatter(padding_info padinfo) explicit R_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override
{ {
@ -604,7 +604,7 @@ class T_formatter final : public flag_formatter
{ {
public: public:
explicit T_formatter(padding_info padinfo) explicit T_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override void format(const details::log_msg &, const std::tm &tm_time, fmt::memory_buffer &dest) override
{ {
@ -624,7 +624,7 @@ class z_formatter final : public flag_formatter
{ {
public: public:
explicit z_formatter(padding_info padinfo) explicit z_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
const std::chrono::seconds cache_refresh = std::chrono::seconds(5); const std::chrono::seconds cache_refresh = std::chrono::seconds(5);
@ -683,7 +683,7 @@ class t_formatter final : public flag_formatter
{ {
public: public:
explicit t_formatter(padding_info padinfo) explicit t_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override
{ {
@ -705,7 +705,7 @@ class pid_formatter final : public flag_formatter
{ {
public: public:
explicit pid_formatter(padding_info padinfo) explicit pid_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &, const std::tm &, fmt::memory_buffer &dest) override void format(const details::log_msg &, const std::tm &, fmt::memory_buffer &dest) override
{ {
@ -728,7 +728,7 @@ class i_formatter final : public flag_formatter
{ {
public: public:
explicit i_formatter(padding_info padinfo) explicit i_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override
{ {
@ -742,7 +742,7 @@ class v_formatter final : public flag_formatter
{ {
public: public:
explicit v_formatter(padding_info padinfo) explicit v_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override
{ {
@ -829,7 +829,7 @@ class source_location_formatter final : public flag_formatter
{ {
public: public:
explicit source_location_formatter(padding_info padinfo) explicit source_location_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override
{ {
@ -858,7 +858,7 @@ class source_filename_formatter final : public flag_formatter
{ {
public: public:
explicit source_filename_formatter(padding_info padinfo) explicit source_filename_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override
{ {
@ -875,7 +875,7 @@ class source_linenum_formatter final : public flag_formatter
{ {
public: public:
explicit source_linenum_formatter(padding_info padinfo) explicit source_linenum_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override
{ {
@ -900,7 +900,7 @@ class source_funcname_formatter final : public flag_formatter
{ {
public: public:
explicit source_funcname_formatter(padding_info padinfo) explicit source_funcname_formatter(padding_info padinfo)
: flag_formatter(padinfo){}; : flag_formatter(padinfo){}
void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override void format(const details::log_msg &msg, const std::tm &, fmt::memory_buffer &dest) override
{ {

@ -100,18 +100,13 @@ public:
#endif // _WIN32 #endif // _WIN32
#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT #endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
// T can be statically converted to string_view template<class T>
template<class T, typename std::enable_if<std::is_convertible<T, spdlog::string_view_t>::value, T>::type * = nullptr>
void log(level::level_enum lvl, const T &); void log(level::level_enum lvl, const T &);
// T can be statically converted to string_view // T can be statically converted to string_view
template<class T, typename std::enable_if<std::is_convertible<T, spdlog::string_view_t>::value, T>::type * = nullptr> template<class T, typename std::enable_if<std::is_convertible<T, spdlog::string_view_t>::value, T>::type * = nullptr>
void log(source_loc loc, level::level_enum lvl, const T &); void log(source_loc loc, level::level_enum lvl, const T &);
// T cannot be statically converted to string_view
template<class T, typename std::enable_if<!std::is_convertible<T, spdlog::string_view_t>::value, T>::type * = nullptr>
void log(level::level_enum lvl, const T &);
// T cannot be statically converted to string_view // T cannot be statically converted to string_view
template<class T, typename std::enable_if<!std::is_convertible<T, spdlog::string_view_t>::value, T>::type * = nullptr> template<class T, typename std::enable_if<!std::is_convertible<T, spdlog::string_view_t>::value, T>::type * = nullptr>
void log(source_loc loc, level::level_enum lvl, const T &); void log(source_loc loc, level::level_enum lvl, const T &);

@ -33,12 +33,12 @@ class ansicolor_sink final : public sink
{ {
public: public:
using mutex_t = typename ConsoleMutex::mutex_t; using mutex_t = typename ConsoleMutex::mutex_t;
ansicolor_sink() ansicolor_sink(color_mode mode = color_mode::automatic)
: target_file_(TargetStream::stream()) : target_file_(TargetStream::stream())
, mutex_(ConsoleMutex::mutex()) , mutex_(ConsoleMutex::mutex())
{ {
should_do_colors_ = details::os::in_terminal(target_file_) && details::os::is_color_terminal(); set_color_mode_(mode);
colors_[level::trace] = white; colors_[level::trace] = white;
colors_[level::debug] = cyan; colors_[level::debug] = cyan;
colors_[level::info] = green; colors_[level::info] = green;
@ -133,7 +133,35 @@ public:
formatter_ = std::move(sink_formatter); formatter_ = std::move(sink_formatter);
} }
bool should_color()
{
std::lock_guard<mutex_t> lock(mutex_);
return should_do_colors_;
}
void set_color_mode(color_mode mode)
{
std::lock_guard<mutex_t> lock(mutex_);
set_color_mode_(mode);
}
private: private:
void set_color_mode_(color_mode mode)
{
switch (mode)
{
case color_mode::always:
should_do_colors_ = true;
break;
case color_mode::automatic:
should_do_colors_ = details::os::in_terminal(target_file_) && details::os::is_color_terminal();
break;
case color_mode::never:
should_do_colors_ = false;
break;
}
}
void print_ccode_(const std::string &color_code) void print_ccode_(const std::string &color_code)
{ {
fwrite(color_code.data(), sizeof(char), color_code.size(), target_file_); fwrite(color_code.data(), sizeof(char), color_code.size(), target_file_);

@ -30,6 +30,11 @@ public:
file_helper_.open(filename, truncate); file_helper_.open(filename, truncate);
} }
const filename_t &filename() const
{
return file_helper_.filename();
}
protected: protected:
void sink_it_(const details::log_msg &msg) override void sink_it_(const details::log_msg &msg) override
{ {

@ -63,6 +63,11 @@ public:
rotation_tp_ = next_rotation_tp_(); rotation_tp_ = next_rotation_tp_();
} }
const filename_t &filename() const
{
return file_helper_.filename();
}
protected: protected:
void sink_it_(const details::log_msg &msg) override void sink_it_(const details::log_msg &msg) override
{ {

@ -31,13 +31,17 @@ template<typename Mutex>
class rotating_file_sink final : public base_sink<Mutex> class rotating_file_sink final : public base_sink<Mutex>
{ {
public: public:
rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files) rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open=false)
: base_filename_(std::move(base_filename)) : base_filename_(std::move(base_filename))
, max_size_(max_size) , max_size_(max_size)
, max_files_(max_files) , max_files_(max_files)
{ {
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
if (rotate_on_open && current_size_ > 0)
{
rotate_();
}
} }
// calc filename according to index and file extension if exists. // calc filename according to index and file extension if exists.
@ -58,6 +62,11 @@ public:
return fmt::to_string(w); return fmt::to_string(w);
} }
const filename_t &filename() const
{
return file_helper_.filename();
}
protected: protected:
void sink_it_(const details::log_msg &msg) override void sink_it_(const details::log_msg &msg) override
{ {
@ -141,15 +150,15 @@ using rotating_file_sink_st = rotating_file_sink<details::null_mutex>;
template<typename Factory = default_factory> template<typename Factory = default_factory>
inline std::shared_ptr<logger> rotating_logger_mt( inline std::shared_ptr<logger> rotating_logger_mt(
const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files) const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files, bool rotate_on_open=false)
{ {
return Factory::template create<sinks::rotating_file_sink_mt>(logger_name, filename, max_file_size, max_files); return Factory::template create<sinks::rotating_file_sink_mt>(logger_name, filename, max_file_size, max_files, rotate_on_open);
} }
template<typename Factory = default_factory> template<typename Factory = default_factory>
inline std::shared_ptr<logger> rotating_logger_st( inline std::shared_ptr<logger> rotating_logger_st(
const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files) const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files, bool rotate_on_open = false)
{ {
return Factory::template create<sinks::rotating_file_sink_st>(logger_name, filename, max_file_size, max_files); return Factory::template create<sinks::rotating_file_sink_st>(logger_name, filename, max_file_size, max_files, rotate_on_open);
} }
} // namespace spdlog } // namespace spdlog

@ -14,15 +14,10 @@ namespace sinks {
class sink class sink
{ {
public: public:
sink() sink() = default;
: level_(level::trace)
, formatter_(new pattern_formatter())
{
}
explicit sink(std::unique_ptr<spdlog::pattern_formatter> formatter) explicit sink(std::unique_ptr<spdlog::formatter> formatter)
: level_(level::trace) : formatter_{std::move(formatter)}
, formatter_(std::move(formatter))
{ {
} }
@ -49,10 +44,10 @@ public:
protected: protected:
// sink log level - default is all // sink log level - default is all
level_t level_; level_t level_{level::trace};
// sink formatter - default is full format // sink formatter - default is full format
std::unique_ptr<spdlog::formatter> formatter_; std::unique_ptr<spdlog::formatter> formatter_{details::make_unique<spdlog::pattern_formatter>()};
}; };
} // namespace sinks } // namespace sinks

@ -31,26 +31,26 @@ using stderr_color_sink_st = ansicolor_stderr_sink_st;
} // namespace sinks } // namespace sinks
template<typename Factory = default_factory> template<typename Factory = default_factory>
inline std::shared_ptr<logger> stdout_color_mt(const std::string &logger_name) inline std::shared_ptr<logger> stdout_color_mt(const std::string &logger_name, color_mode mode = color_mode::automatic)
{ {
return Factory::template create<sinks::stdout_color_sink_mt>(logger_name); return Factory::template create<sinks::stdout_color_sink_mt>(logger_name, mode);
} }
template<typename Factory = default_factory> template<typename Factory = default_factory>
inline std::shared_ptr<logger> stdout_color_st(const std::string &logger_name) inline std::shared_ptr<logger> stdout_color_st(const std::string &logger_name, color_mode mode = color_mode::automatic)
{ {
return Factory::template create<sinks::stdout_color_sink_st>(logger_name); return Factory::template create<sinks::stdout_color_sink_st>(logger_name, mode);
} }
template<typename Factory = default_factory> template<typename Factory = default_factory>
inline std::shared_ptr<logger> stderr_color_mt(const std::string &logger_name) inline std::shared_ptr<logger> stderr_color_mt(const std::string &logger_name, color_mode mode = color_mode::automatic)
{ {
return Factory::template create<sinks::stderr_color_sink_mt>(logger_name); return Factory::template create<sinks::stderr_color_sink_mt>(logger_name, mode);
} }
template<typename Factory = default_factory> template<typename Factory = default_factory>
inline std::shared_ptr<logger> stderr_color_st(const std::string &logger_name) inline std::shared_ptr<logger> stderr_color_st(const std::string &logger_name, color_mode mode = color_mode::automatic)
{ {
return Factory::template create<sinks::stderr_color_sink_mt>(logger_name); return Factory::template create<sinks::stderr_color_sink_st>(logger_name, mode);
} }
} // namespace spdlog } // namespace spdlog

@ -0,0 +1,91 @@
//
// Copyright(c) 2019 ZVYAGIN.Alexander@gmail.com
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
#ifndef SPDLOG_H
#include "spdlog/spdlog.h"
#endif
#include "spdlog/sinks/base_sink.h"
#include <array>
#include <string>
#include <systemd/sd-journal.h>
namespace spdlog {
namespace sinks {
inline int syslog_level(level::level_enum l) {
switch(l) {
case level::off:
case level::trace:
case level::debug:
return LOG_DEBUG;
case level::info:
return LOG_INFO;
case level::warn:
return LOG_WARNING;
case level::err:
return LOG_ERR;
case level::critical:
return LOG_CRIT;
default:
throw std::invalid_argument("systemd_sink.h syslog_level()");
}
}
/**
* Sink that write to systemd using the `sd_journal_print()` library call.
*
* Locking is not needed, as `sd_journal_print()` itself is thread-safe.
*/
template<typename Mutex>
class systemd_sink : public base_sink<Mutex>
{
public:
//
explicit systemd_sink(void) {}
~systemd_sink() override {}
systemd_sink(const systemd_sink &) = delete;
systemd_sink &operator=(const systemd_sink &) = delete;
protected:
void sink_it_(const details::log_msg &msg) override
{
if( sd_journal_print(
syslog_level(msg.level),
"%.*s",
static_cast<int>(msg.payload.size()),
msg.payload.data()
)
)
throw spdlog_ex("Failed writing to systemd");
}
void flush_() override {}
};
using systemd_sink_mt = systemd_sink<std::mutex>;
using systemd_sink_st = systemd_sink<details::null_mutex>;
} // namespace sinks
// Create and register a syslog logger
template<typename Factory = default_factory>
inline std::shared_ptr<logger> systemd_logger_mt(
const std::string &logger_name)
{
return Factory::template create<sinks::systemd_sink_mt>(logger_name);
}
template<typename Factory = default_factory>
inline std::shared_ptr<logger> systemd_logger_st(
const std::string &logger_name)
{
return Factory::template create<sinks::systemd_sink_st>(logger_name);
}
} // namespace spdlog

@ -37,10 +37,11 @@ public:
const WORD WHITE = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; const WORD WHITE = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
const WORD YELLOW = FOREGROUND_RED | FOREGROUND_GREEN; const WORD YELLOW = FOREGROUND_RED | FOREGROUND_GREEN;
wincolor_sink() wincolor_sink(color_mode mode = color_mode::automatic)
: out_handle_(OutHandle::handle()) : out_handle_(OutHandle::handle())
, mutex_(ConsoleMutex::mutex()) , mutex_(ConsoleMutex::mutex())
{ {
set_color_mode_(mode);
colors_[level::trace] = WHITE; colors_[level::trace] = WHITE;
colors_[level::debug] = CYAN; colors_[level::debug] = CYAN;
colors_[level::info] = GREEN; colors_[level::info] = GREEN;
@ -70,7 +71,7 @@ public:
std::lock_guard<mutex_t> lock(mutex_); std::lock_guard<mutex_t> lock(mutex_);
fmt::memory_buffer formatted; fmt::memory_buffer formatted;
formatter_->format(msg, formatted); formatter_->format(msg, formatted);
if (msg.color_range_end > msg.color_range_start) if (should_do_colors_ && msg.color_range_end > msg.color_range_start)
{ {
// before color range // before color range
print_range_(formatted, 0, msg.color_range_start); print_range_(formatted, 0, msg.color_range_start);
@ -83,7 +84,7 @@ public:
// after color range // after color range
print_range_(formatted, msg.color_range_end, formatted.size()); print_range_(formatted, msg.color_range_end, formatted.size());
} }
else // print without colors if color range is invalid else // print without colors if color range is invalid (or color is disabled)
{ {
print_range_(formatted, 0, formatted.size()); print_range_(formatted, 0, formatted.size());
} }
@ -106,8 +107,29 @@ public:
formatter_ = std::move(sink_formatter); formatter_ = std::move(sink_formatter);
} }
void set_color_mode(color_mode mode)
{
std::lock_guard<mutex_t> lock(mutex_);
set_color_mode_(mode);
}
private: private:
using mutex_t = typename ConsoleMutex::mutex_t; using mutex_t = typename ConsoleMutex::mutex_t;
void set_color_mode_(color_mode mode)
{
switch (mode)
{
case color_mode::always:
case color_mode::automatic:
should_do_colors_ = true;
break;
case color_mode::never:
should_do_colors_ = false;
break;
}
}
// set color and return the orig console attributes (for resetting later) // set color and return the orig console attributes (for resetting later)
WORD set_console_attribs(WORD attribs) WORD set_console_attribs(WORD attribs)
{ {
@ -130,6 +152,7 @@ private:
HANDLE out_handle_; HANDLE out_handle_;
mutex_t &mutex_; mutex_t &mutex_;
bool should_do_colors_;
std::unordered_map<level::level_enum, WORD, level::level_hasher> colors_; std::unordered_map<level::level_enum, WORD, level::level_hasher> colors_;
}; };

@ -47,6 +47,21 @@ inline std::shared_ptr<spdlog::logger> create(std::string logger_name, SinkArgs
return default_factory::create<Sink>(std::move(logger_name), std::forward<SinkArgs>(sink_args)...); return default_factory::create<Sink>(std::move(logger_name), std::forward<SinkArgs>(sink_args)...);
} }
// Initialize and register a logger,
// formatter and flush level will be set according the global settings.
//
// NOTE:
// Use this function when creating loggers manually.
//
// Example:
// auto console_sink = std::make_shared<spdlog::sinks::stdout_sink_mt>();
// auto console_logger = std::make_shared<spdlog::logger>("console_logger", console_sink);
// spdlog::initialize_logger(console_logger);
inline void initialize_logger(std::shared_ptr<logger> logger)
{
details::registry::instance().initialize_logger(std::move(logger));
}
// Return an existing logger or nullptr if a logger with such name doesn't // Return an existing logger or nullptr if a logger with such name doesn't
// exist. // exist.
// example: spdlog::get("my_logger")->info("hello {}", "world"); // example: spdlog::get("my_logger")->info("hello {}", "world");
@ -312,8 +327,10 @@ inline void critical(const wchar_t *fmt, const Args &... args)
// //
#define SPDLOG_LOGGER_CALL(logger, level, ...) \ #define SPDLOG_LOGGER_CALL(logger, level, ...) \
do { \
if (logger->should_log(level)) \ if (logger->should_log(level)) \
logger->log(spdlog::source_loc{SPDLOG_FILE_BASENAME(__FILE__), __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__) logger->log(spdlog::source_loc{SPDLOG_FILE_BASENAME(__FILE__), __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__); \
} while (0)
#if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE
#define SPDLOG_LOGGER_TRACE(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::trace, __VA_ARGS__) #define SPDLOG_LOGGER_TRACE(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::trace, __VA_ARGS__)

@ -121,6 +121,13 @@
// "MY ERROR", "MY CRITICAL", "OFF" } // "MY ERROR", "MY CRITICAL", "OFF" }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// Uncomment to customize short level names (e.g. "MT")
// These can be longer than one character.
//
// #define SPDLOG_SHORT_LEVEL_NAMES { "T", "D", "I", "W", "E", "C", "O" }
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Uncomment to disable default logger creation. // Uncomment to disable default logger creation.
// This might save some (very) small initialization time if no default logger is needed. // This might save some (very) small initialization time if no default logger is needed.

@ -7,6 +7,6 @@
#define SPDLOG_VER_MAJOR 1 #define SPDLOG_VER_MAJOR 1
#define SPDLOG_VER_MINOR 3 #define SPDLOG_VER_MINOR 3
#define SPDLOG_VER_PATCH 0 #define SPDLOG_VER_PATCH 1
#define SPDLOG_VERSION (SPDLOG_VER_MAJOR * 10000 + SPDLOG_VER_MINOR * 100 + SPDLOG_VER_PATCH) #define SPDLOG_VERSION (SPDLOG_VER_MAJOR * 10000 + SPDLOG_VER_MINOR * 100 + SPDLOG_VER_PATCH)

@ -1,6 +1,6 @@
CXX ?= g++ CXX ?= g++
CXXFLAGS = -Wall -pedantic -std=c++11 -pthread -Wconversion -O3 -I../include -fmax-errors=1 CXXFLAGS = -Wall -pedantic -std=c++11 -pthread -Wconversion -O3 -I../include -fmax-errors=1
LDPFALGS = -pthread LDPFALGS = -pthread -lsystemd
CPP_FILES := $(wildcard *.cpp) CPP_FILES := $(wildcard *.cpp)
OBJ_FILES := $(addprefix ./,$(notdir $(CPP_FILES:.cpp=.o))) OBJ_FILES := $(addprefix ./,$(notdir $(CPP_FILES:.cpp=.o)))

@ -60,7 +60,20 @@ TEST_CASE("rotating_file_logger2", "[rotating_logger]]")
prepare_logdir(); prepare_logdir();
size_t max_size = 1024 * 10; size_t max_size = 1024 * 10;
std::string basename = "logs/rotating_log"; std::string basename = "logs/rotating_log";
auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 1);
{
// make an initial logger to create the first output file
auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 2, true);
for (int i = 0; i < 10; ++i)
{
logger->info("Test message {}", i);
}
// drop causes the logger destructor to be called, which is required so the
// next logger can rename the first output file.
spdlog::drop(logger->name());
}
auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 2, true);
for (int i = 0; i < 10; ++i) for (int i = 0; i < 10; ++i)
{ {
logger->info("Test message {}", i); logger->info("Test message {}", i);

@ -0,0 +1,13 @@
#include "includes.h"
#include <spdlog/sinks/systemd_sink.h>
TEST_CASE("systemd", "[all]")
{
auto systemd_sink = std::make_shared<spdlog::sinks::systemd_sink_st>();
systemd_sink->set_level(spdlog::level::level_enum::err);
spdlog::logger logger("spdlog_systemd_test", systemd_sink);
logger.debug("test debug");
logger.error("test error");
logger.info("test info");
}
Loading…
Cancel
Save