diff --git a/CMakeLists.txt b/CMakeLists.txt index 58e76f52..408c7b88 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,6 +105,7 @@ endif() option(SPDLOG_PREVENT_CHILD_FD "Prevent from child processes to inherit log file descriptors" OFF) option(SPDLOG_NO_THREAD_ID "prevent spdlog from querying the thread id on each log call if thread id is not needed" OFF) +option(SPDLOG_NO_PTHREAD_ID "prevent spdlog from querying the pthread id on each log call if pthread id is not needed (required for %N)" ON) option(SPDLOG_NO_TLS "prevent spdlog from using thread local storage" OFF) option( SPDLOG_NO_ATOMIC_LEVELS @@ -220,6 +221,7 @@ foreach( SPDLOG_CLOCK_COARSE SPDLOG_PREVENT_CHILD_FD SPDLOG_NO_THREAD_ID + SPDLOG_NO_PTHREAD_ID SPDLOG_NO_TLS SPDLOG_NO_ATOMIC_LEVELS SPDLOG_DISABLE_DEFAULT_LOGGER) diff --git a/include/spdlog/details/log_msg-inl.h b/include/spdlog/details/log_msg-inl.h index c6e8a7e0..10661817 100644 --- a/include/spdlog/details/log_msg-inl.h +++ b/include/spdlog/details/log_msg-inl.h @@ -19,6 +19,9 @@ SPDLOG_INLINE log_msg::log_msg(spdlog::log_clock::time_point log_time, spdlog::s , time(log_time) #ifndef SPDLOG_NO_THREAD_ID , thread_id(os::thread_id()) +#endif +#ifndef SPDLOG_NO_PTHREAD_ID + , pthread_id(pthread_self()) #endif , source(loc) , payload(msg) diff --git a/include/spdlog/details/log_msg.h b/include/spdlog/details/log_msg.h index fed51abd..4aa3d3fb 100644 --- a/include/spdlog/details/log_msg.h +++ b/include/spdlog/details/log_msg.h @@ -22,6 +22,10 @@ struct SPDLOG_API log_msg log_clock::time_point time; size_t thread_id{0}; +#ifndef SPDLOG_NO_PTHREAD_ID + pthread_t pthread_id{0}; +#endif + // wrapping the formatted text with color (updated by pattern_formatter). mutable size_t color_range_start{0}; mutable size_t color_range_end{0}; diff --git a/include/spdlog/pattern_formatter-inl.h b/include/spdlog/pattern_formatter-inl.h index ec727032..2a0d46e6 100644 --- a/include/spdlog/pattern_formatter-inl.h +++ b/include/spdlog/pattern_formatter-inl.h @@ -658,6 +658,29 @@ public: } }; +// Thread name +template +class N_formatter final : public flag_formatter +{ +public: + explicit N_formatter(padding_info padinfo) + : flag_formatter(padinfo) + {} + + void format(const details::log_msg &msg, const std::tm &, memory_buf_t &dest) override + { + char threadNameBuffer[16] = { 0 }; +#ifndef SPDLOG_NO_PTHREAD_ID + pthread_getname_np(msg.pthread_id, threadNameBuffer, 16); +#endif + threadName_ = threadNameBuffer; + ScopedPadder p(threadName_.size(), padinfo_, dest); + fmt_helper::append_string_view(threadName_, dest); + } +private: + std::string threadName_; +}; + // Current pid template class pid_formatter final : public flag_formatter @@ -1115,6 +1138,10 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i formatters_.push_back(details::make_unique>(padding)); break; + case ('N'): // thread name + formatters_.push_back(details::make_unique>(padding)); + break; + case ('v'): // the message text formatters_.push_back(details::make_unique>(padding)); break; diff --git a/tests/test_pattern_formatter.cpp b/tests/test_pattern_formatter.cpp index 656f93a0..7fa9e99b 100644 --- a/tests/test_pattern_formatter.cpp +++ b/tests/test_pattern_formatter.cpp @@ -59,6 +59,23 @@ TEST_CASE("date MM/DD/YY ", "[pattern_formatter]") REQUIRE(log_to_str("Some message", "%D %v", spdlog::pattern_time_type::local, "\n") == oss.str()); } + +#ifndef SPDLOG_NO_PTHREAD_ID +TEST_CASE("thread name formatter", "[pattern_formatter]") +{ + char originalName[16] = { 0 }; + pthread_getname_np(pthread_self(), originalName, 16); + std::string expected = "["; + expected += originalName; + expected += "] Some message\n"; + REQUIRE(log_to_str("Some message", "[%N] %v", spdlog::pattern_time_type::local, "\n") == expected); + pthread_setname_np(pthread_self(), "Testname"); + REQUIRE(log_to_str("Some message", "[%N] %v", spdlog::pattern_time_type::local, "\n") == "[Testname] Some message\n"); + pthread_setname_np(pthread_self(), originalName); +} + +#endif + TEST_CASE("color range test1", "[pattern_formatter]") { auto formatter = std::make_shared("%^%v%$", spdlog::pattern_time_type::local, "\n");