LogIt++
Header-only, macro-first C++ logging library
Loading...
Searching...
No Matches
SyslogLogger.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_LOGGERS_SYSLOGLOGGER_HPP_INCLUDED
3#define LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_LOGGERS_SYSLOGLOGGER_HPP_INCLUDED
4
5#include "ILogger.hpp"
6#include <atomic>
7#include <string>
8#include <memory>
9#include <mutex>
10
13
14#if (defined(__unix__) || defined(__APPLE__)) && defined(LOGIT_HAS_SYSLOG)
15#include <syslog.h>
16#define LOGIT_SYSLOG_ENABLED 1
17#else
18#define LOGIT_SYSLOG_ENABLED 0
19#endif
20
21namespace logit {
22
23# if LOGIT_SYSLOG_ENABLED
24
28 class SyslogLogger : public ILogger {
29 public:
31 struct Config {
32 const char* ident;
33 int facility;
34 bool async;
35 bool use_dedicated_executor = false;
36 std::size_t queue_capacity = 0;
37 QueuePolicy queue_policy = QueuePolicy::Block;
42 Config(const char* i = "log-it", int f = LOG_USER, bool a = true)
43 : ident(i), facility(f), async(a) {}
44 };
45
47 SyslogLogger() : SyslogLogger(Config()) {}
48
51 explicit SyslogLogger(const Config& c) : m_cfg(c) {
52 openlog(m_cfg.ident, LOG_PID | LOG_NDELAY, m_cfg.facility);
53 if (m_cfg.async && m_cfg.use_dedicated_executor) {
54 m_executor.reset(new detail::SingleThreadExecutor());
55 m_executor->set_max_queue_size(m_cfg.queue_capacity);
56 m_executor->set_queue_policy(m_cfg.queue_policy);
57 }
58 }
59
64 SyslogLogger(const char* ident, int facility, bool async)
65 : SyslogLogger(Config(ident, facility, async)) {}
66
69 const char* ident,
70 int facility,
71 bool async,
72 bool use_dedicated_executor,
73 std::size_t queue_capacity,
74 QueuePolicy queue_policy)
75 : SyslogLogger(make_config(
76 ident,
77 facility,
78 async,
79 use_dedicated_executor,
80 queue_capacity,
81 queue_policy)) {}
82
84 ~SyslogLogger() override { shutdown(); closelog(); }
85
89 void log(const LogRecord& rec, const std::string& msg) override {
90 std::lock_guard<std::mutex> lifecycle_lock(m_lifecycle_mutex);
91 if (m_shutdown.load(std::memory_order_acquire)) return;
92 LogLevel lvl = rec.raw_mode ? LogLevel::LOG_LVL_INFO : rec.log_level;
93 bool raw_mode = rec.raw_mode;
94 std::string s = msg;
95 auto task = [this, lvl, raw_mode, s]() {
96 if (!raw_mode && static_cast<int>(lvl) < m_level.load()) return;
97 syslog(m_map(lvl), "%s", s.c_str());
98 };
99 if (m_cfg.async) { if (m_executor) { m_executor->add_task(task); } else { detail::TaskExecutor::get_instance().add_task(task); } }
100 else { task(); }
101 m_last_ts.store(rec.timestamp_ms);
102 }
106 std::string get_string_param(const LoggerParam& param) const override { return {}; }
107
111 int64_t get_int_param(const LoggerParam& param) const override { return 0; }
112
116 double get_float_param(const LoggerParam& param) const override { return 0.0; }
117
120 void set_log_level(LogLevel l) override { m_level.store(static_cast<int>(l)); }
121
124 LogLevel get_log_level() const override { return static_cast<LogLevel>(m_level.load()); }
125
127 void wait() override { if (m_cfg.async) { if (m_executor) { m_executor->wait(); } else { detail::TaskExecutor::get_instance().wait(); } } }
128
130 void shutdown() override {
131 {
132 std::lock_guard<std::mutex> lifecycle_lock(m_lifecycle_mutex);
133 if (m_shutdown.exchange(true, std::memory_order_acq_rel)) return;
134 }
135 if (m_executor) {
136 m_executor->shutdown();
137 } else if (m_cfg.async) {
139 }
140 }
141
142 private:
143 static int m_map(LogLevel l) {
144 switch (l) {
146 case LogLevel::LOG_LVL_DEBUG: return LOG_DEBUG;
147 case LogLevel::LOG_LVL_INFO: return LOG_INFO;
148 case LogLevel::LOG_LVL_WARN: return LOG_WARNING;
149 case LogLevel::LOG_LVL_ERROR: return LOG_ERR;
150 case LogLevel::LOG_LVL_FATAL: return LOG_CRIT;
151 } return LOG_INFO;
152 }
153 Config m_cfg{};
154 std::mutex m_lifecycle_mutex;
155 std::atomic<int> m_level{static_cast<int>(LogLevel::LOG_LVL_TRACE)};
156 std::atomic<int64_t> m_last_ts{0};
157 std::atomic<bool> m_shutdown{false};
158 std::unique_ptr<detail::SingleThreadExecutor> m_executor;
159
160 static Config make_config(
161 const char* ident,
162 int facility,
163 bool async,
164 bool use_dedicated_executor,
165 std::size_t queue_capacity,
166 QueuePolicy queue_policy) {
167 Config config(ident, facility, async);
168 config.use_dedicated_executor = use_dedicated_executor;
169 config.queue_capacity = queue_capacity;
170 config.queue_policy = queue_policy;
171 return config;
172 }
173 };
174
175# else // stub on unsupported
178 class SyslogLogger : public ILogger {
179 public:
181 struct Config {
182 const char* ident;
184 bool async;
185 bool use_dedicated_executor = false;
186 std::size_t queue_capacity = 0;
187 QueuePolicy queue_policy = QueuePolicy::Block;
188 Config(const char* i="", int f=0, bool a=false) : ident(i), facility(f), async(a) {}
189 };
190
193
196 explicit SyslogLogger(const Config& c) { (void)c; }
197
202 SyslogLogger(const char* ident,int facility,bool async) { (void)ident; (void)facility; (void)async; }
203
205 SyslogLogger(const char* ident, int facility, bool async, bool use_dedicated_executor,
206 std::size_t queue_capacity, QueuePolicy queue_policy) {
207 (void)ident; (void)facility; (void)async; (void)use_dedicated_executor;
208 (void)queue_capacity; (void)queue_policy;
209 }
210
214 void log(const LogRecord& rec, const std::string& msg) override { (void)rec; (void)msg; }
215
219 std::string get_string_param(const LoggerParam& param) const override { (void)param; return {}; }
220
224 int64_t get_int_param(const LoggerParam& param) const override { (void)param; return 0; }
225
229 double get_float_param(const LoggerParam& param) const override { (void)param; return 0.0; }
230
233 void set_log_level(LogLevel l) override { (void)l; }
234
237 LogLevel get_log_level() const override { return LogLevel::LOG_LVL_TRACE; }
238
240 void wait() override {}
241 };
242# endif
243
244} // namespace logit
245
246#endif // LOGIT_CPP_HEADER_LOGIT_CPP_LOGIT_LOGGERS_SYSLOGLOGGER_HPP_INCLUDED
Defines the interface for loggers used in the logging system.
virtual void shutdown()
Stops logger-owned asynchronous resources after draining pending work.
Definition ILogger.hpp:159
std::string get_string_param(const LoggerParam &param) const override
Return empty string parameter.
void set_log_level(LogLevel l) override
Ignore level change.
double get_float_param(const LoggerParam &param) const override
Return zero float parameter.
SyslogLogger(const char *ident, int facility, bool async, bool use_dedicated_executor, std::size_t queue_capacity, QueuePolicy queue_policy)
Construct with parameters and ignored dedicated executor options.
SyslogLogger()
Construct stub logger.
SyslogLogger(const Config &c)
Construct with configuration.
LogLevel get_log_level() const override
Return default log level.
void log(const LogRecord &rec, const std::string &msg) override
Ignore log request.
int64_t get_int_param(const LoggerParam &param) const override
Return zero integer parameter.
SyslogLogger(const char *ident, int facility, bool async)
Construct with parameters.
void wait() override
No-op wait.
void add_task(std::function< void()> task)
Enqueue a task for asynchronous execution.
void wait()
Block until the queue is empty or a shutdown is requested.
static TaskExecutor & get_instance()
Returns the global executor instance.
QueuePolicy
Queue overflow handling policy used by TaskExecutor and SingleThreadExecutor.
The primary namespace for the LogIt++ library.
LogLevel
Logging levels.
Definition enums.hpp:15
@ LOG_LVL_TRACE
Trace level logging.
@ LOG_LVL_ERROR
Error level logging.
@ LOG_LVL_INFO
Information level logging.
@ LOG_LVL_FATAL
Fatal level logging.
@ LOG_LVL_DEBUG
Debug level logging.
@ LOG_LVL_WARN
Warning level logging.
LoggerParam
Enumeration for different logger parameters that can be retrieved.
Definition enums.hpp:47
detail::QueuePolicy QueuePolicy
Public queue overflow handling policy.
Definition loggers.hpp:20
Stores log metadata and content.
Definition LogRecord.hpp:17
QueuePolicy queue_policy
Unused.
std::size_t queue_capacity
Unused.
int facility
Unused facility.
const char * ident
Unused identifier.
Config(const char *i="", int f=0, bool a=false)
bool use_dedicated_executor
Unused flag.