Skip to content

Commit

Permalink
Add syslog_formatter
Browse files Browse the repository at this point in the history
The formatter enables remote(udp/tcp) syslog sink
  • Loading branch information
sivachandran committed Aug 15, 2024
1 parent 5ebfc92 commit 10e4d20
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 0 deletions.
13 changes: 13 additions & 0 deletions example/example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ void custom_flags_example();
void file_events_example();
void replace_default_logger_example();
void mdc_example();
void syslog_formatter_example();

#include "spdlog/spdlog.h"
#include "spdlog/cfg/env.h" // support for loading levels from the environment variable
Expand Down Expand Up @@ -86,6 +87,7 @@ int main(int, char *[]) {
file_events_example();
replace_default_logger_example();
mdc_example();
syslog_formatter_example();

// Flush all *registered* loggers using a worker thread every 3 seconds.
// note: registered loggers *must* be thread safe for this to work correctly!
Expand Down Expand Up @@ -391,3 +393,14 @@ void mdc_example()
spdlog::set_pattern("[%H:%M:%S %z] [%^%L%$] [%&] %v");
spdlog::info("Some log message with context");
}

#include "spdlog/syslog_formatter.h"
void syslog_formatter_example()
{
// run "nc -klu 514" to receive the syslog message
spdlog::sinks::udp_sink_config udp_sink_config("127.0.0.1", 514);
auto udp_logger = spdlog::udp_logger_mt("udp_logger", udp_sink_config);
spdlog::syslog_formatter syslog_formatter(spdlog::facility::user, "localhost", "example");
udp_logger->set_formatter(syslog_formatter.clone());
udp_logger->info("this message will be logged in local syslog receiver");
}
107 changes: 107 additions & 0 deletions include/spdlog/syslog_formatter-inl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#pragma once

#ifndef SPDLOG_HEADER_ONLY
#include <spdlog/syslog_formatter.h>
#endif

#include <spdlog/details/fmt_helper.h>

namespace spdlog {
namespace details {

namespace severity {
enum severity_enum : int {
emergency = 0,
alert = 1,
critical = 2,
error = 3,
warning = 4,
notice = 5,
informational = 6,
debug = 7,
};
}

} // namespace details

SPDLOG_INLINE syslog_formatter::syslog_formatter(int facility, std::string hostname, std::string appname)
: facility_(facility),
hostname_(std::move(hostname)),
appname_(std::move(appname)),
pattern_formatter_("%Y-%m-%dT%H:%M:%SZ", pattern_time_type::utc, "") {
pattern_formatter_.need_localtime();
}

SPDLOG_INLINE std::unique_ptr<formatter> syslog_formatter::clone() const {
auto cloned = details::make_unique<syslog_formatter>(facility_, hostname_, appname_);
#if defined(__GNUC__) && __GNUC__ < 5
return std::move(cloned);
#else
return cloned;
#endif
}

SPDLOG_INLINE void syslog_formatter::format(const details::log_msg &msg, memory_buf_t &dest) {
details::severity::severity_enum severity;

switch (msg.level) {
case level::critical:
severity = details::severity::critical;

case level::err:
severity = details::severity::error;
break;

case level::warn:
severity = details::severity::warning;
break;

case level::info:
severity = details::severity::informational;
break;

default:
severity = details::severity::debug;
break;
}

dest.push_back('<');
details::fmt_helper::append_int((facility_ * 8) + severity, dest);
dest.push_back('>');
dest.push_back('1');

dest.push_back(' ');
pattern_formatter_.format(msg, dest);

dest.push_back(' ');
if (hostname_.empty()) {
dest.push_back('-');
} else {
details::fmt_helper::append_string_view(hostname_, dest);
}

dest.push_back(' ');
if (appname_.empty()) {
dest.push_back('-');
} else {
details::fmt_helper::append_string_view(appname_, dest);
}

dest.push_back(' ');
details::fmt_helper::append_int(details::os::pid(), dest);

dest.push_back(' ');
if (msg.logger_name.size() == 0) {
dest.push_back('-');
} else {
details::fmt_helper::append_string_view(msg.logger_name, dest);
}

dest.push_back(' ');
dest.push_back('-'); // nil structured data

dest.push_back(' ');
details::fmt_helper::append_string_view(msg.payload, dest);
}

} // namespace spdlog
63 changes: 63 additions & 0 deletions include/spdlog/syslog_formatter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#pragma once

#include <spdlog/common.h>
#include <spdlog/formatter.h>
#include <spdlog/pattern_formatter.h>
#include <spdlog/details/log_msg.h>

#include <memory>
#include <string>

namespace spdlog {

namespace facility {
enum facility_enum : int {
kernel = 0,
user = 1,
mail = 2,
daemons = 3,
security = 4,
syslogd = 5,
printer = 6,
network = 7,
uucp = 8,
clock = 9,
security2 = 10,
ftp = 11,
ntp = 12,
audit = 13,
alert = 14,
clock2 = 15,
local0 = 16,
local1 = 17,
local2 = 18,
local3 = 19,
local4 = 20,
local5 = 21,
local6 = 22,
local7 = 23
};
}

class SPDLOG_API syslog_formatter : public formatter {
public:
explicit syslog_formatter(int facility, std::string hostname, std::string appname);

syslog_formatter(const syslog_formatter &other) = delete;
syslog_formatter &operator=(const syslog_formatter &other) = delete;

std::unique_ptr<formatter> clone() const override;
void format(const details::log_msg &msg, memory_buf_t &dest) override;

private:
int facility_;
std::string hostname_;
std::string appname_;
spdlog::pattern_formatter pattern_formatter_;
};

} // namespace spdlog

#ifdef SPDLOG_HEADER_ONLY
#include "syslog_formatter-inl.h"
#endif
1 change: 1 addition & 0 deletions src/spdlog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <spdlog/sinks/base_sink-inl.h>
#include <spdlog/sinks/sink-inl.h>
#include <spdlog/spdlog-inl.h>
#include <spdlog/syslog_formatter-inl.h>

#include <mutex>

Expand Down

0 comments on commit 10e4d20

Please sign in to comment.