From 2c3ae8d341b0937abd643b3dc674fc0ac088740e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20M=C3=BCller?= <26765321+JoernMueller@users.noreply.github.com> Date: Thu, 13 Feb 2025 17:00:36 +0100 Subject: [PATCH] Modified systemd_sink to pass MDC data to journald --- include/spdlog/sinks/systemd_sink.h | 49 +++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/include/spdlog/sinks/systemd_sink.h b/include/spdlog/sinks/systemd_sink.h index d2cd55f2..d22e11c5 100644 --- a/include/spdlog/sinks/systemd_sink.h +++ b/include/spdlog/sinks/systemd_sink.h @@ -18,7 +18,7 @@ namespace spdlog { namespace sinks { /** - * Sink that write to systemd journal using the `sd_journal_send()` library call. + * Sink that write to systemd journal using the `sd_journal_send()` and `sd_journal_sendv()` library calls. */ template class systemd_sink : public base_sink { @@ -56,13 +56,15 @@ protected: payload = msg.payload; } + const string_view_t syslog_identifier = ident_.empty() ? msg.logger_name : ident_; + +#ifdef SPDLOG_NO_TLS size_t length = payload.size(); // limit to max int if (length > static_cast(std::numeric_limits::max())) { length = static_cast(std::numeric_limits::max()); } - const string_view_t syslog_identifier = ident_.empty() ? msg.logger_name : ident_; // Do not send source location if not available if (msg.source.empty()) { @@ -88,6 +90,49 @@ protected: msg.source.funcname, nullptr); } +#else // SPDLOG_NO_TLS + + std::vector iovector; + const std::string message{std::string("MESSAGE=") + payload.data()}; + iovector.push_back({const_cast(message.c_str()), message.length()}); + + const std::string priority{"PRIORITY=" + std::to_string(syslog_level(msg.level))}; + iovector.push_back({const_cast(priority.c_str()), priority.length()}); +#ifndef SPDLOG_NO_THREAD_ID + const std::string tid{"TID=" + std::to_string(msg.thread_id)}; + iovector.push_back({const_cast(tid.c_str()), tid.length()}); +#endif + const std::string syslog_id{std::string("SYSLOG_IDENTIFIER=") + syslog_identifier.data()}; + iovector.push_back({const_cast(syslog_id.c_str()), syslog_id.length()}); + + std::string file, line, func; + if (!msg.source.empty()) { + file.assign(std::move(std::string("CODE_FILE=") + msg.source.filename)); + iovector.push_back({const_cast(file.c_str()), file.length()}); + line.assign(std::move(std::string("CODE_LINE=") + std::to_string(msg.source.line))); + iovector.push_back({const_cast(line.c_str()), line.length()}); + func.assign(std::move(std::string("CODE_FUNC=") + msg.source.funcname)); + iovector.push_back({const_cast(func.c_str()), func.length()}); + } + + auto &context{spdlog::mdc::get_context()}; + std::vector context_strings; + context_strings.reserve(context.size()); + for (const auto &item : context) { + std::string key; + key.reserve(item.first.length() + item.second.length() + 1); + key = item.first; + std::transform(key.begin(), key.end(), key.begin(), ::toupper); + key += '=' + item.second; + context_strings.emplace_back(std::move(key)); + } + for (const auto &item : context_strings) { + iovector.push_back({const_cast(item.c_str()), item.length()}); + } + + err = sd_journal_sendv(iovector.data(), iovector.size()); + +#endif // SPDLOG_NO_TLS if (err) { throw_spdlog_ex("Failed writing to systemd", errno); }