Photon 1.0.0
Loading...
Searching...
No Matches
systemd_sink.h
Go to the documentation of this file.
1// Copyright(c) 2019 ZVYAGIN.Alexander@gmail.com
2// Distributed under the MIT License (http://opensource.org/licenses/MIT)
3
4#pragma once
5
7#include <spdlog/details/os.h>
10
11#include <array>
12#ifndef SD_JOURNAL_SUPPRESS_LOCATION
13#define SD_JOURNAL_SUPPRESS_LOCATION
14#endif
15#include <systemd/sd-journal.h>
16
17namespace spdlog
18{
19 namespace sinks
20 {
21
25 template <typename Mutex>
26 class systemd_sink : public base_sink<Mutex>
27 {
28 public:
29 systemd_sink(std::string ident = "", bool enable_formatting = false)
30 : ident_{std::move(ident)}, enable_formatting_{enable_formatting}, syslog_levels_{{/* spdlog::level::trace */ LOG_DEBUG,
31 /* spdlog::level::debug */ LOG_DEBUG,
32 /* spdlog::level::info */ LOG_INFO,
33 /* spdlog::level::warn */ LOG_WARNING,
34 /* spdlog::level::err */ LOG_ERR,
35 /* spdlog::level::critical */ LOG_CRIT,
36 /* spdlog::level::off */ LOG_INFO}}
37 {
38 }
39
40 ~systemd_sink() override
41 {
42 }
43
44 systemd_sink(const systemd_sink&) = delete;
46
47 protected:
48 const std::string ident_;
49 bool enable_formatting_ = false;
50 using levels_array = std::array<int, 7>;
52
53 void sink_it_(const details::log_msg& msg) override
54 {
55 int err;
56 string_view_t payload;
57 memory_buf_t formatted;
58 if (enable_formatting_)
59 {
60 base_sink<Mutex>::formatter_->format(msg, formatted);
61 payload = string_view_t(formatted.data(), formatted.size());
62 }
63 else
64 {
65 payload = msg.payload;
66 }
67
68 size_t length = payload.size();
69 // limit to max int
70 if (length > static_cast<size_t>(std::numeric_limits<int>::max()))
71 {
72 length = static_cast<size_t>(std::numeric_limits<int>::max());
73 }
74
75 const string_view_t syslog_identifier = ident_.empty() ? msg.logger_name : ident_;
76
77 // Do not send source location if not available
78 if (msg.source.empty())
79 {
80 // Note: function call inside '()' to avoid macro expansion
81 err = (sd_journal_send)("MESSAGE=%.*s", static_cast<int>(length), payload.data(), "PRIORITY=%d", syslog_level(msg.level),
82#ifndef SPDLOG_NO_THREAD_ID
83 "TID=%zu", os::thread_id(),
84#endif
85 "SYSLOG_IDENTIFIER=%.*s", static_cast<int>(syslog_identifier.size()), syslog_identifier.data(), nullptr);
86 }
87 else
88 {
89 err = (sd_journal_send)("MESSAGE=%.*s", static_cast<int>(length), payload.data(), "PRIORITY=%d", syslog_level(msg.level),
90#ifndef SPDLOG_NO_THREAD_ID
91 "TID=%zu", os::thread_id(),
92#endif
93 "SYSLOG_IDENTIFIER=%.*s", static_cast<int>(syslog_identifier.size()), syslog_identifier.data(), "CODE_FILE=%s",
94 msg.source.filename, "CODE_LINE=%d", msg.source.line, "CODE_FUNC=%s", msg.source.funcname, nullptr);
95 }
96
97 if (err)
98 {
99 throw_spdlog_ex("Failed writing to systemd", errno);
100 }
101 }
102
104 {
105 return syslog_levels_.at(static_cast<levels_array::size_type>(l));
106 }
107
108 void flush_() override
109 {
110 }
111 };
112
115 } // namespace sinks
116
117 // Create and register a syslog logger
118 template <typename Factory = spdlog::synchronous_factory>
119 inline std::shared_ptr<logger> systemd_logger_mt(
120 const std::string& logger_name, const std::string& ident = "", bool enable_formatting = false)
121 {
122 return Factory::template create<sinks::systemd_sink_mt>(logger_name, ident, enable_formatting);
123 }
124
125 template <typename Factory = spdlog::synchronous_factory>
126 inline std::shared_ptr<logger> systemd_logger_st(
127 const std::string& logger_name, const std::string& ident = "", bool enable_formatting = false)
128 {
129 return Factory::template create<sinks::systemd_sink_st>(logger_name, ident, enable_formatting);
130 }
131} // namespace spdlog
Definition base_sink.h:22
Definition systemd_sink.h:27
void flush_() override
Definition systemd_sink.h:108
levels_array syslog_levels_
Definition systemd_sink.h:51
int syslog_level(level::level_enum l)
Definition systemd_sink.h:103
~systemd_sink() override
Definition systemd_sink.h:40
const std::string ident_
Definition systemd_sink.h:48
systemd_sink(std::string ident="", bool enable_formatting=false)
Definition systemd_sink.h:29
void sink_it_(const details::log_msg &msg) override
Definition systemd_sink.h:53
std::array< int, 7 > levels_array
Definition systemd_sink.h:50
systemd_sink(const systemd_sink &)=delete
systemd_sink & operator=(const systemd_sink &)=delete
bool enable_formatting_
Definition systemd_sink.h:49
level_enum
Definition common.h:233
systemd_sink< std::mutex > systemd_sink_mt
Definition systemd_sink.h:113
systemd_sink< details::null_mutex > systemd_sink_st
Definition systemd_sink.h:114
Definition async.h:26
std::shared_ptr< logger > systemd_logger_mt(const std::string &logger_name, const std::string &ident="", bool enable_formatting=false)
Definition systemd_sink.h:119
std::shared_ptr< logger > systemd_logger_st(const std::string &logger_name, const std::string &ident="", bool enable_formatting=false)
Definition systemd_sink.h:126
fmt::basic_string_view< char > string_view_t
Definition common.h:172
SPDLOG_INLINE void throw_spdlog_ex(const std::string &msg, int last_errno)
Definition common-inl.h:75
fmt::basic_memory_buffer< char, 250 > memory_buf_t
Definition common.h:173
Definition uuid.h:926
Definition log_msg.h:14
string_view_t payload
Definition log_msg.h:32
level::level_enum level
Definition log_msg.h:23
source_loc source
Definition log_msg.h:31
string_view_t logger_name
Definition log_msg.h:22
int line
Definition common.h:324
const char * funcname
Definition common.h:325
SPDLOG_CONSTEXPR bool empty() const SPDLOG_NOEXCEPT
Definition common.h:319
const char * filename
Definition common.h:323