Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce RFC 3339 #42

Merged
merged 1 commit into from
Mar 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
29 changes: 19 additions & 10 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 @@ -448,29 +455,31 @@ void manager_free(Manager *m) {
free(m);
}

int manager_new(Manager **ret, const char *state_file, const char *cursor) {
int manager_new(const char *state_file, const char *cursor, Manager **ret) {
_cleanup_(manager_freep) Manager *m = NULL;
int r;

assert(ret);

m = new0(Manager, 1);
m = new(Manager, 1);
if (!m)
return -ENOMEM;

m->socket = m->journal_watch_fd = -1;

m->state_file = strdup(state_file);
if (!m->state_file)
return -ENOMEM;
*m = (Manager) {
.socket = -1,
.journal_watch_fd = -1,
.state_file = strdup(state_file),
.protocol = SYSLOG_TRANSMISSION_PROTOCOL_UDP,
.log_format = SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5424,
};

if (cursor) {
m->last_cursor = strdup(cursor);
if (!m->last_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 Down
13 changes: 12 additions & 1 deletion 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,9 +48,10 @@ 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);
int manager_new(const char *state_file, const char *cursor, Manager **ret);
void manager_free(Manager *m);

DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
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
6 changes: 3 additions & 3 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 @@ -159,7 +159,7 @@ int main(int argc, char **argv) {
goto finish;
}

r = manager_new(&m, arg_save_state, arg_cursor);
r = manager_new(arg_save_state, arg_cursor, &m);
if (r < 0) {
log_error_errno(r, "Failed to allocate manager: %m");
goto finish;
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
2 changes: 1 addition & 1 deletion src/share/alloc-util.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

#include "macro.h"

#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
#define new(t, n) ((t*) malloc_multiply(n, sizeof(t)))

#define new0(t, n) ((t*) calloc((n), sizeof(t)))

Expand Down