Compare commits
10 Commits
37b847692e
...
5ebfc92730
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5ebfc92730 | ||
![]() |
885b5473e2 | ||
![]() |
d276069a6e | ||
![]() |
eeb22c13bb | ||
![]() |
c3aed4b683 | ||
![]() |
27cb4c7670 | ||
![]() |
2d4acf8cc3 | ||
![]() |
3b4fd93bd0 | ||
![]() |
2122eb2194 | ||
![]() |
22b0f4fc06 |
@ -34,7 +34,7 @@ elseif(NOT CMAKE_CXX_STANDARD)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# make sure __cplusplus is defined when using msvc and enable parallel build
|
# make sure __cplusplus is defined when using msvc and enable parallel build
|
||||||
if(MSVC)
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
string(APPEND CMAKE_CXX_FLAGS " /Zc:__cplusplus /MP")
|
string(APPEND CMAKE_CXX_FLAGS " /Zc:__cplusplus /MP")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -108,9 +108,11 @@ endif()
|
|||||||
if(WIN32)
|
if(WIN32)
|
||||||
option(SPDLOG_WCHAR_SUPPORT "Support wchar api" OFF)
|
option(SPDLOG_WCHAR_SUPPORT "Support wchar api" OFF)
|
||||||
option(SPDLOG_WCHAR_FILENAMES "Support wchar filenames" OFF)
|
option(SPDLOG_WCHAR_FILENAMES "Support wchar filenames" OFF)
|
||||||
|
option(SPDLOG_WCHAR_CONSOLE "Support wchar output to console" OFF)
|
||||||
else()
|
else()
|
||||||
set(SPDLOG_WCHAR_SUPPORT OFF CACHE BOOL "non supported option" FORCE)
|
set(SPDLOG_WCHAR_SUPPORT OFF CACHE BOOL "non supported option" FORCE)
|
||||||
set(SPDLOG_WCHAR_FILENAMES OFF CACHE BOOL "non supported option" FORCE)
|
set(SPDLOG_WCHAR_FILENAMES OFF CACHE BOOL "non supported option" FORCE)
|
||||||
|
set(SPDLOG_WCHAR_CONSOLE OFF CACHE BOOL "non supported option" FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||||
@ -159,7 +161,7 @@ if(SPDLOG_BUILD_SHARED OR BUILD_SHARED_LIBS)
|
|||||||
endif()
|
endif()
|
||||||
add_library(spdlog SHARED ${SPDLOG_SRCS} ${SPDLOG_ALL_HEADERS})
|
add_library(spdlog SHARED ${SPDLOG_SRCS} ${SPDLOG_ALL_HEADERS})
|
||||||
target_compile_definitions(spdlog PUBLIC SPDLOG_SHARED_LIB)
|
target_compile_definitions(spdlog PUBLIC SPDLOG_SHARED_LIB)
|
||||||
if(MSVC)
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||||
target_compile_options(spdlog PUBLIC $<$<AND:$<CXX_COMPILER_ID:MSVC>,$<NOT:$<COMPILE_LANGUAGE:CUDA>>>:/wd4251
|
target_compile_options(spdlog PUBLIC $<$<AND:$<CXX_COMPILER_ID:MSVC>,$<NOT:$<COMPILE_LANGUAGE:CUDA>>>:/wd4251
|
||||||
/wd4275>)
|
/wd4275>)
|
||||||
endif()
|
endif()
|
||||||
@ -237,9 +239,11 @@ endif()
|
|||||||
# Misc definitions according to tweak options
|
# Misc definitions according to tweak options
|
||||||
# ---------------------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------------------
|
||||||
set(SPDLOG_WCHAR_TO_UTF8_SUPPORT ${SPDLOG_WCHAR_SUPPORT})
|
set(SPDLOG_WCHAR_TO_UTF8_SUPPORT ${SPDLOG_WCHAR_SUPPORT})
|
||||||
|
set(SPDLOG_UTF8_TO_WCHAR_CONSOLE ${SPDLOG_WCHAR_CONSOLE})
|
||||||
foreach(
|
foreach(
|
||||||
SPDLOG_OPTION
|
SPDLOG_OPTION
|
||||||
SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
SPDLOG_WCHAR_TO_UTF8_SUPPORT
|
||||||
|
SPDLOG_UTF8_TO_WCHAR_CONSOLE
|
||||||
SPDLOG_WCHAR_FILENAMES
|
SPDLOG_WCHAR_FILENAMES
|
||||||
SPDLOG_NO_EXCEPTIONS
|
SPDLOG_NO_EXCEPTIONS
|
||||||
SPDLOG_CLOCK_COARSE
|
SPDLOG_CLOCK_COARSE
|
||||||
|
15
README.md
15
README.md
@ -437,7 +437,22 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
|||||||
logger->info("Some info message");
|
logger->info("Some info message");
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Mapped Diagnostic Context
|
||||||
|
```c++
|
||||||
|
// Mapped Diagnostic Context (MDC) is a map that stores key-value pairs (string values) in thread local storage.
|
||||||
|
// Each thread maintains its own MDC, which loggers use to append diagnostic information to log outputs.
|
||||||
|
// Note: it is not supported in asynchronous mode due to its reliance on thread-local storage.
|
||||||
|
#include "spdlog/mdc.h"
|
||||||
|
void mdc_example()
|
||||||
|
{
|
||||||
|
spdlog::mdc::put("key1", "value1");
|
||||||
|
spdlog::mdc::put("key2", "value2");
|
||||||
|
// if not using the default format, use the %& formatter to print mdc data
|
||||||
|
// spdlog::set_pattern("[%H:%M:%S %z] [%^%L%$] [%&] %v");
|
||||||
|
}
|
||||||
|
```
|
||||||
---
|
---
|
||||||
## Benchmarks
|
## Benchmarks
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ void udp_example();
|
|||||||
void custom_flags_example();
|
void custom_flags_example();
|
||||||
void file_events_example();
|
void file_events_example();
|
||||||
void replace_default_logger_example();
|
void replace_default_logger_example();
|
||||||
|
void mdc_example();
|
||||||
|
|
||||||
#include "spdlog/spdlog.h"
|
#include "spdlog/spdlog.h"
|
||||||
#include "spdlog/cfg/env.h" // support for loading levels from the environment variable
|
#include "spdlog/cfg/env.h" // support for loading levels from the environment variable
|
||||||
@ -84,6 +85,7 @@ int main(int, char *[]) {
|
|||||||
custom_flags_example();
|
custom_flags_example();
|
||||||
file_events_example();
|
file_events_example();
|
||||||
replace_default_logger_example();
|
replace_default_logger_example();
|
||||||
|
mdc_example();
|
||||||
|
|
||||||
// Flush all *registered* loggers using a worker thread every 3 seconds.
|
// Flush all *registered* loggers using a worker thread every 3 seconds.
|
||||||
// note: registered loggers *must* be thread safe for this to work correctly!
|
// note: registered loggers *must* be thread safe for this to work correctly!
|
||||||
@ -270,7 +272,7 @@ struct my_type {
|
|||||||
#ifndef SPDLOG_USE_STD_FORMAT // when using fmtlib
|
#ifndef SPDLOG_USE_STD_FORMAT // when using fmtlib
|
||||||
template <>
|
template <>
|
||||||
struct fmt::formatter<my_type> : fmt::formatter<std::string> {
|
struct fmt::formatter<my_type> : fmt::formatter<std::string> {
|
||||||
auto format(my_type my, format_context &ctx) -> decltype(ctx.out()) {
|
auto format(my_type my, format_context &ctx) const -> decltype(ctx.out()) {
|
||||||
return fmt::format_to(ctx.out(), "[my_type i={}]", my.i);
|
return fmt::format_to(ctx.out(), "[my_type i={}]", my.i);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -376,3 +378,16 @@ void replace_default_logger_example() {
|
|||||||
|
|
||||||
spdlog::set_default_logger(old_logger);
|
spdlog::set_default_logger(old_logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mapped Diagnostic Context (MDC) is a map that stores key-value pairs (string values) in thread local storage.
|
||||||
|
// Each thread maintains its own MDC, which loggers use to append diagnostic information to log outputs.
|
||||||
|
// Note: it is not supported in asynchronous mode due to its reliance on thread-local storage.
|
||||||
|
#include "spdlog/mdc.h"
|
||||||
|
void mdc_example()
|
||||||
|
{
|
||||||
|
spdlog::mdc::put("key1", "value1");
|
||||||
|
spdlog::mdc::put("key2", "value2");
|
||||||
|
// if not using the default format, you can use the %& formatter to print mdc data as well
|
||||||
|
spdlog::set_pattern("[%H:%M:%S %z] [%^%L%$] [%&] %v");
|
||||||
|
spdlog::info("Some log message with context");
|
||||||
|
}
|
||||||
|
@ -98,7 +98,7 @@ SPDLOG_INLINE void file_helper::close() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE void file_helper::write(const memory_buf_t &buf) {
|
SPDLOG_INLINE void file_helper::write(const memory_buf_t &buf) {
|
||||||
if(fd_ == nullptr) return;
|
if (fd_ == nullptr) return;
|
||||||
size_t msg_size = buf.size();
|
size_t msg_size = buf.size();
|
||||||
auto data = buf.data();
|
auto data = buf.data();
|
||||||
if (std::fwrite(data, 1, msg_size, fd_) != msg_size) {
|
if (std::fwrite(data, 1, msg_size, fd_) != msg_size) {
|
||||||
|
@ -84,7 +84,6 @@ SPDLOG_INLINE std::shared_ptr<logger> registry::get(const std::string &logger_na
|
|||||||
return found == loggers_.end() ? nullptr : found->second;
|
return found == loggers_.end() ? nullptr : found->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SPDLOG_INLINE std::shared_ptr<logger> registry::default_logger() {
|
SPDLOG_INLINE std::shared_ptr<logger> registry::default_logger() {
|
||||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||||
return default_logger_;
|
return default_logger_;
|
||||||
|
@ -44,7 +44,8 @@ public:
|
|||||||
|
|
||||||
// set default logger and add it to the registry if not registered already.
|
// set default logger and add it to the registry if not registered already.
|
||||||
// default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
|
// default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
|
||||||
// Note: Make sure to unregister it when no longer needed or before calling again with a new logger.
|
// Note: Make sure to unregister it when no longer needed or before calling again with a new
|
||||||
|
// logger.
|
||||||
void set_default_logger(std::shared_ptr<logger> new_default_logger);
|
void set_default_logger(std::shared_ptr<logger> new_default_logger);
|
||||||
|
|
||||||
void set_tp(std::shared_ptr<thread_pool> tp);
|
void set_tp(std::shared_ptr<thread_pool> tp);
|
||||||
|
@ -67,9 +67,7 @@ struct async_msg : log_msg_buffer {
|
|||||||
worker_ptr{std::move(worker)},
|
worker_ptr{std::move(worker)},
|
||||||
flush_promise{} {}
|
flush_promise{} {}
|
||||||
|
|
||||||
async_msg(async_logger_ptr &&worker,
|
async_msg(async_logger_ptr &&worker, async_msg_type the_type, std::promise<void> &&promise)
|
||||||
async_msg_type the_type,
|
|
||||||
std::promise<void> &&promise)
|
|
||||||
: log_msg_buffer{},
|
: log_msg_buffer{},
|
||||||
msg_type{the_type},
|
msg_type{the_type},
|
||||||
worker_ptr{std::move(worker)},
|
worker_ptr{std::move(worker)},
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||||
|
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -5,9 +8,16 @@
|
|||||||
|
|
||||||
#include <spdlog/common.h>
|
#include <spdlog/common.h>
|
||||||
|
|
||||||
|
// MDC is a simple map of key->string values stored in thread local storage whose content will be printed by the loggers.
|
||||||
|
// Note: Not supported in async mode (thread local storage - so the async thread pool have different copy).
|
||||||
|
//
|
||||||
|
// Usage example:
|
||||||
|
// spdlog::mdc::put("mdc_key_1", "mdc_value_1");
|
||||||
|
// spdlog::info("Hello, {}", "World!"); // => [2024-04-26 02:08:05.040] [info] [mdc_key_1:mdc_value_1] Hello, World!
|
||||||
|
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
class SPDLOG_API mdc {
|
class SPDLOG_API mdc {
|
||||||
public:
|
public:
|
||||||
using mdc_map_t = std::map<std::string, std::string>;
|
using mdc_map_t = std::map<std::string, std::string>;
|
||||||
|
|
||||||
static void put(const std::string &key, const std::string &value) {
|
static void put(const std::string &key, const std::string &value) {
|
||||||
@ -31,6 +41,6 @@ namespace spdlog {
|
|||||||
static thread_local mdc_map_t context;
|
static thread_local mdc_map_t context;
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
@ -802,7 +802,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void format_mdc(const mdc::mdc_map_t &mdc_map, memory_buf_t &dest){
|
void format_mdc(const mdc::mdc_map_t &mdc_map, memory_buf_t &dest) {
|
||||||
auto last_element = --mdc_map.end();
|
auto last_element = --mdc_map.end();
|
||||||
for (auto it = mdc_map.begin(); it != mdc_map.end(); ++it) {
|
for (auto it = mdc_map.begin(); it != mdc_map.end(); ++it) {
|
||||||
auto &pair = *it;
|
auto &pair = *it;
|
||||||
@ -825,8 +825,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Full info formatter
|
// Full info formatter
|
||||||
// pattern: [%Y-%m-%d %H:%M:%S.%e] [%n] [%l] [%s:%#] %v
|
// pattern: [%Y-%m-%d %H:%M:%S.%e] [%n] [%l] [%s:%#] %v
|
||||||
class full_formatter final : public flag_formatter {
|
class full_formatter final : public flag_formatter {
|
||||||
@ -921,8 +919,6 @@ private:
|
|||||||
mdc_formatter<null_scoped_padder> mdc_formatter_{padding_info{}};
|
mdc_formatter<null_scoped_padder> mdc_formatter_{padding_info{}};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace details
|
} // namespace details
|
||||||
|
|
||||||
SPDLOG_INLINE pattern_formatter::pattern_formatter(std::string pattern,
|
SPDLOG_INLINE pattern_formatter::pattern_formatter(std::string pattern,
|
||||||
|
@ -60,7 +60,7 @@ SPDLOG_INLINE filename_t rotating_file_sink<Mutex>::calc_filename(const filename
|
|||||||
|
|
||||||
filename_t basename, ext;
|
filename_t basename, ext;
|
||||||
std::tie(basename, ext) = details::file_helper::split_by_extension(filename);
|
std::tie(basename, ext) = details::file_helper::split_by_extension(filename);
|
||||||
return fmt_lib::format(SPDLOG_FILENAME_T("{}.{}{}"), basename, index, ext);
|
return fmt_lib::format(SPDLOG_FMT_STRING(SPDLOG_FILENAME_T("{}.{}{}")), basename, index, ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Mutex>
|
template <typename Mutex>
|
||||||
|
@ -64,13 +64,14 @@ protected:
|
|||||||
//
|
//
|
||||||
// Simply maps spdlog's log level to syslog priority level.
|
// Simply maps spdlog's log level to syslog priority level.
|
||||||
//
|
//
|
||||||
int syslog_prio_from_level(const details::log_msg &msg) const {
|
virtual int syslog_prio_from_level(const details::log_msg &msg) const {
|
||||||
return syslog_levels_.at(static_cast<levels_array::size_type>(msg.level));
|
return syslog_levels_.at(static_cast<levels_array::size_type>(msg.level));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
using levels_array = std::array<int, 7>;
|
using levels_array = std::array<int, 7>;
|
||||||
levels_array syslog_levels_;
|
levels_array syslog_levels_;
|
||||||
|
|
||||||
|
private:
|
||||||
// must store the ident because the man says openlog might use the pointer as
|
// must store the ident because the man says openlog might use the pointer as
|
||||||
// is and not a string copy
|
// is and not a string copy
|
||||||
const std::string ident_;
|
const std::string ident_;
|
||||||
|
@ -134,9 +134,18 @@ void SPDLOG_INLINE wincolor_sink<ConsoleMutex>::print_range_(const memory_buf_t
|
|||||||
size_t start,
|
size_t start,
|
||||||
size_t end) {
|
size_t end) {
|
||||||
if (end > start) {
|
if (end > start) {
|
||||||
|
#if defined(SPDLOG_UTF8_TO_WCHAR_CONSOLE)
|
||||||
|
wmemory_buf_t wformatted;
|
||||||
|
details::os::utf8_to_wstrbuf(string_view_t(formatted.data() + start, end - start),
|
||||||
|
wformatted);
|
||||||
|
auto size = static_cast<DWORD>(wformatted.size());
|
||||||
|
auto ignored = ::WriteConsoleW(static_cast<HANDLE>(out_handle_), wformatted.data(), size,
|
||||||
|
nullptr, nullptr);
|
||||||
|
#else
|
||||||
auto size = static_cast<DWORD>(end - start);
|
auto size = static_cast<DWORD>(end - start);
|
||||||
auto ignored = ::WriteConsoleA(static_cast<HANDLE>(out_handle_), formatted.data() + start,
|
auto ignored = ::WriteConsoleA(static_cast<HANDLE>(out_handle_), formatted.data() + start,
|
||||||
size, nullptr, nullptr);
|
size, nullptr, nullptr);
|
||||||
|
#endif
|
||||||
(void)(ignored);
|
(void)(ignored);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ SPDLOG_INLINE std::shared_ptr<logger> get(const std::string &name) {
|
|||||||
return details::registry::instance().get(name);
|
return details::registry::instance().get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SPDLOG_INLINE void set_formatter(std::unique_ptr<spdlog::formatter> formatter) {
|
SPDLOG_INLINE void set_formatter(std::unique_ptr<spdlog::formatter> formatter) {
|
||||||
details::registry::instance().set_formatter(std::move(formatter));
|
details::registry::instance().set_formatter(std::move(formatter));
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#define SPDLOG_VER_MAJOR 1
|
#define SPDLOG_VER_MAJOR 1
|
||||||
#define SPDLOG_VER_MINOR 14
|
#define SPDLOG_VER_MINOR 14
|
||||||
#define SPDLOG_VER_PATCH 0
|
#define SPDLOG_VER_PATCH 1
|
||||||
|
|
||||||
#define SPDLOG_TO_VERSION(major, minor, patch) (major * 10000 + minor * 100 + patch)
|
#define SPDLOG_TO_VERSION(major, minor, patch) (major * 10000 + minor * 100 + patch)
|
||||||
#define SPDLOG_VERSION SPDLOG_TO_VERSION(SPDLOG_VER_MAJOR, SPDLOG_VER_MINOR, SPDLOG_VER_PATCH)
|
#define SPDLOG_VERSION SPDLOG_TO_VERSION(SPDLOG_VER_MAJOR, SPDLOG_VER_MINOR, SPDLOG_VER_PATCH)
|
||||||
|
@ -84,11 +84,11 @@ TEST_CASE("dir_name", "[create_dir]") {
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
//
|
//
|
||||||
// test windows cases when drive letter is given e.g. C:\\some-folder
|
// test windows cases when drive letter is given e.g. C:\\some-folder
|
||||||
//
|
//
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <fileapi.h>
|
#include <fileapi.h>
|
||||||
|
|
||||||
std::string get_full_path(const std::string &relative_folder_path) {
|
std::string get_full_path(const std::string &relative_folder_path) {
|
||||||
char full_path[MAX_PATH];
|
char full_path[MAX_PATH];
|
||||||
@ -109,7 +109,7 @@ spdlog::filename_t::value_type find_non_existing_drive() {
|
|||||||
std::string root_path = std::string(1, drive) + ":\\";
|
std::string root_path = std::string(1, drive) + ":\\";
|
||||||
UINT drive_type = GetDriveTypeA(root_path.c_str());
|
UINT drive_type = GetDriveTypeA(root_path.c_str());
|
||||||
if (drive_type == DRIVE_NO_ROOT_DIR) {
|
if (drive_type == DRIVE_NO_ROOT_DIR) {
|
||||||
return static_cast <spdlog::filename_t::value_type>(drive);
|
return static_cast<spdlog::filename_t::value_type>(drive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return '\0'; // No available drive found
|
return '\0'; // No available drive found
|
||||||
@ -134,12 +134,11 @@ TEST_CASE("non_existing_drive", "[create_dir]") {
|
|||||||
spdlog::filename_t path;
|
spdlog::filename_t path;
|
||||||
|
|
||||||
auto non_existing_drive = find_non_existing_drive();
|
auto non_existing_drive = find_non_existing_drive();
|
||||||
path += non_existing_drive ;
|
path += non_existing_drive;
|
||||||
path += SPDLOG_FILENAME_T(":\\");
|
path += SPDLOG_FILENAME_T(":\\");
|
||||||
REQUIRE(create_dir(path) == false);
|
REQUIRE(create_dir(path) == false);
|
||||||
path += SPDLOG_FILENAME_T("subdir");
|
path += SPDLOG_FILENAME_T("subdir");
|
||||||
REQUIRE(create_dir(path) == false);
|
REQUIRE(create_dir(path) == false);
|
||||||
|
|
||||||
}
|
}
|
||||||
//#endif // SPDLOG_WCHAR_FILENAMES
|
// #endif // SPDLOG_WCHAR_FILENAMES
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
Loading…
Reference in New Issue
Block a user