Skip to content

Commit

Permalink
Introduce RFC 3339
Browse files Browse the repository at this point in the history
  • Loading branch information
ssahani committed Mar 30, 2024
1 parent 7dfb74b commit ffc66dd
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 20 deletions.
1 change: 1 addition & 0 deletions conf/systemd-netlogd.conf.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[Network]
#Address=239.0.0.1:6000
#Protocol=udp
#LogFormat=rfc5424
29 changes: 29 additions & 0 deletions src/netlog/netlog-conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,35 @@ int config_parse_protocol(const char *unit,
return 0;
}

int config_parse_log_format(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Manager *m = userdata;
int r;

assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);

r = log_format_from_string(rvalue);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, -r,
"Unrecognised log format '%s'", rvalue);
return -EPROTONOSUPPORT;
}

m->log_format = r;
return 0;
}

int manager_parse_config_file(Manager *m) {
assert(m);

Expand Down
13 changes: 13 additions & 0 deletions src/netlog/netlog-conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ int config_parse_netlog_remote_address(const char *unit,
const char *rvalue,
void *data,
void *userdata);

int config_parse_protocol(const char *unit,
const char *filename,
unsigned line,
Expand All @@ -27,4 +28,16 @@ int config_parse_protocol(const char *unit,
const char *rvalue,
void *data,
void *userdata);

int config_parse_log_format(const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata);

int manager_parse_config_file(Manager *m);
7 changes: 4 additions & 3 deletions src/netlog/netlog-gperf.gperf
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ struct ConfigPerfItem;
%struct-type
%includes
%%
Network.Address, config_parse_netlog_remote_address, 0, 0
Network.Protocol, config_parse_protocol, 0, offsetof(Manager, protocol)
Network.StructuredData, config_parse_string, 0, offsetof(Manager, structured_data)
Network.Address, config_parse_netlog_remote_address, 0, 0
Network.Protocol, config_parse_protocol, 0, offsetof(Manager, protocol)
Network.LogFormat, config_parse_log_format, 0, offsetof(Manager, log_format)
Network.StructuredData, config_parse_string, 0, offsetof(Manager, structured_data)
17 changes: 14 additions & 3 deletions src/netlog/netlog-manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ static const char *const protocol_table[_SYSLOG_TRANSMISSION_PROTOCOL_MAX] = {

DEFINE_STRING_TABLE_LOOKUP(protocol, int);

static const char *const log_format_table[_SYSLOG_TRANSMISSION_LOG_FORMAT_MAX] = {
[SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5424] = "rfc5424",
[SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_3339] = "rfc3339",
};

DEFINE_STRING_TABLE_LOOKUP(log_format, int);

static int parse_field(const void *data, size_t length, const char *field, char **target) {
size_t fl, nl;
void *buf;
Expand Down Expand Up @@ -351,11 +358,11 @@ int manager_connect(Manager *m) {

r = manager_open_network_socket(m);
if (r < 0)
return r;
return log_error_errno(r, "Failed to create network socket: %m");

r = manager_journal_monitor_listen(m);
if (r < 0)
return r;
return log_error_errno(r, "Failed to monitor journal: %m");

return 0;
}
Expand Down Expand Up @@ -470,7 +477,7 @@ int manager_new(Manager **ret, const char *state_file, const char *cursor) {
return -ENOMEM;
}

r = sd_event_default(&m->event);
r = sd_event_default(&m->event);
if (r < 0)
return log_error_errno(r, "Failed to allocate event loop: %m");

Expand All @@ -484,6 +491,10 @@ int manager_new(Manager **ret, const char *state_file, const char *cursor) {
if (r < 0)
return r;

m->protocol = SYSLOG_TRANSMISSION_PROTOCOL_UDP;
m->log_format = SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5424;
socket_address_parse(&m->address, "239.0.0.1:6000");

*ret = TAKE_PTR(m);
return 0;
}
11 changes: 11 additions & 0 deletions src/netlog/netlog-manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ typedef enum SysLogTransmissionProtocol {
_SYSLOG_TRANSMISSION_PROTOCOL_INVALID = -EINVAL,
} SysLogTransmissionProtocol;

typedef enum SysLogTransmissionLogFormat {
SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5424 = 1 << 0,
SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_3339 = 1 << 1,
_SYSLOG_TRANSMISSION_LOG_FORMAT_MAX,
_SYSLOG_TRANSMISSION_LOG_FORMAT_INVALID = -EINVAL,
} SysLogTransmissionLogFormat;

typedef struct Manager Manager;

struct Manager {
Expand Down Expand Up @@ -41,6 +48,7 @@ struct Manager {
char *last_cursor, *current_cursor;
char *structured_data;
SysLogTransmissionProtocol protocol;
SysLogTransmissionLogFormat log_format;
};

int manager_new(Manager **ret, const char *state_file, const char *cursor);
Expand All @@ -61,3 +69,6 @@ int manager_push_to_network(Manager *m, int severity, int facility,

const char *protocol_to_string(int v) _const_;
int protocol_from_string(const char *s) _pure_;

const char *log_format_to_string(int v) _const_;
int log_format_from_string(const char *s) _pure_;
118 changes: 106 additions & 12 deletions src/netlog/netlog-network.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,18 +87,19 @@ static void format_rfc3339_timestamp(const struct timeval *tv, char *header_time
/* The Syslog Protocol RFC5424 format :
* <pri>version sp timestamp sp hostname sp app-name sp procid sp msgid sp [sd-id]s sp msg
*/
int manager_push_to_network(Manager *m,
int severity,
int facility,
const char *identifier,
const char *message,
const char *hostname,
const char *pid,
const struct timeval *tv) {
char header_priority[sizeof("< >1 ")];
static int format_rfc5424(Manager *m,
int severity,
int facility,
const char *identifier,
const char *message,
const char *hostname,
const char *pid,
const struct timeval *tv) {

char header_time[FORMAT_TIMESTAMP_MAX];
uint8_t makepri;
char header_priority[sizeof("< >1 ")];
struct iovec iov[14];
uint8_t makepri;
int n = 0;

assert(m);
Expand Down Expand Up @@ -153,7 +154,7 @@ int manager_push_to_network(Manager *m,
/* Ninth: message */
IOVEC_SET_STRING(iov[n++], message);

/* Tenth: Optional newline message separator, if not implicitly terminated by end of UDP frame
/* Last Optional newline message separator, if not implicitly terminated by end of UDP frame
* De facto standard: separate messages by a newline
*/
if (m->protocol == SYSLOG_TRANSMISSION_PROTOCOL_TCP)
Expand All @@ -162,8 +163,101 @@ int manager_push_to_network(Manager *m,
return network_send(m, iov, n);
}

void manager_close_network_socket(Manager *m) {
static int format_rfc3339(Manager *m,
int severity,
int facility,
const char *identifier,
const char *message,
const char *hostname,
const char *pid,
const struct timeval *tv) {

char header_priority[sizeof("< >1 ")];
char header_time[FORMAT_TIMESTAMP_MAX];
struct iovec iov[14];
uint8_t makepri;
int n = 0;

assert(m);
assert(message);

makepri = (facility << 3) + severity;

/* rfc3339
* <35>Oct 12 22:14:15 client_machine su: 'su root' failed for joe on /dev/pts/2
*/

/* First: priority field '<pri>' */
snprintf(header_priority, sizeof(header_priority), "<%i>", makepri);
IOVEC_SET_STRING(iov[n++], header_priority);

/* Third: timestamp */
format_rfc3339_timestamp(tv, header_time, sizeof(header_time));
IOVEC_SET_STRING(iov[n++], header_time);

/* Fourth: hostname */
if (hostname)
IOVEC_SET_STRING(iov[n++], hostname);
else
IOVEC_SET_STRING(iov[n++], RFC_5424_NILVALUE);

IOVEC_SET_STRING(iov[n++], " ");

/* Fifth: identifier */
if (identifier)
IOVEC_SET_STRING(iov[n++], identifier);
else
IOVEC_SET_STRING(iov[n++], RFC_5424_NILVALUE);

IOVEC_SET_STRING(iov[n++], "[");

/* Sixth: procid */
if (pid)
IOVEC_SET_STRING(iov[n++], pid);
else
IOVEC_SET_STRING(iov[n++], RFC_5424_NILVALUE);

IOVEC_SET_STRING(iov[n++], "]: ");

/* Ninth: message */
IOVEC_SET_STRING(iov[n++], message);

/* Last Optional newline message separator, if not implicitly terminated by end of UDP frame
* De facto standard: separate messages by a newline
*/
if (m->protocol == SYSLOG_TRANSMISSION_PROTOCOL_TCP)
IOVEC_SET_STRING(iov[n++], "\n");

return network_send(m, iov, n);
}

int manager_push_to_network(Manager *m,
int severity,
int facility,
const char *identifier,
const char *message,
const char *hostname,
const char *pid,
const struct timeval *tv) {

int r;

assert(m);
assert(message);

if (m->log_format == SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5424)
r = format_rfc5424(m, severity, facility, identifier, message, hostname, pid, tv);
else
r = format_rfc3339(m, severity, facility, identifier, message, hostname, pid, tv);

if (r < 0)
return 0;

return 0;
}

void manager_close_network_socket(Manager *m) {
assert(m);

if (m->protocol == SYSLOG_TRANSMISSION_PROTOCOL_TCP) {
int r = shutdown(m->socket, SHUT_RDWR);
Expand Down
4 changes: 2 additions & 2 deletions src/netlog/systemd-netlogd.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ static int setup_cursor_state_file(Manager *m, uid_t uid, gid_t gid) {
static void help(void) {
printf("%s ..\n\n"
"Forwards messages from the journal to other hosts over the network using the syslog\n"
"RFC 5424 format in both unicast and multicast addresses.\n\n"
"RFC 5424 or RFC3339 format in both unicast and multicast addresses.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
" --cursor=CURSOR Start at the specified cursor\n"
Expand Down Expand Up @@ -191,7 +191,7 @@ int main(int argc, char **argv) {

if (network_is_online()) {
r = manager_connect(m);
if (r < 0)
if (r < 0)
goto finish;
}

Expand Down

0 comments on commit ffc66dd

Please sign in to comment.