Skip to content

Commit 1cade37

Browse files
committed
Introduce RFC 3339
1 parent 7dfb74b commit 1cade37

File tree

9 files changed

+188
-30
lines changed

9 files changed

+188
-30
lines changed

conf/systemd-netlogd.conf.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[Network]
22
#Address=239.0.0.1:6000
33
#Protocol=udp
4+
#LogFormat=rfc5424

src/netlog/netlog-conf.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,35 @@ int config_parse_protocol(const char *unit,
6363
return 0;
6464
}
6565

66+
int config_parse_log_format(const char *unit,
67+
const char *filename,
68+
unsigned line,
69+
const char *section,
70+
unsigned section_line,
71+
const char *lvalue,
72+
int ltype,
73+
const char *rvalue,
74+
void *data,
75+
void *userdata) {
76+
Manager *m = userdata;
77+
int r;
78+
79+
assert(filename);
80+
assert(lvalue);
81+
assert(rvalue);
82+
assert(data);
83+
84+
r = log_format_from_string(rvalue);
85+
if (r < 0) {
86+
log_syntax(unit, LOG_ERR, filename, line, -r,
87+
"Unrecognised log format '%s'", rvalue);
88+
return -EPROTONOSUPPORT;
89+
}
90+
91+
m->log_format = r;
92+
return 0;
93+
}
94+
6695
int manager_parse_config_file(Manager *m) {
6796
assert(m);
6897

src/netlog/netlog-conf.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ int config_parse_netlog_remote_address(const char *unit,
1717
const char *rvalue,
1818
void *data,
1919
void *userdata);
20+
2021
int config_parse_protocol(const char *unit,
2122
const char *filename,
2223
unsigned line,
@@ -27,4 +28,16 @@ int config_parse_protocol(const char *unit,
2728
const char *rvalue,
2829
void *data,
2930
void *userdata);
31+
32+
int config_parse_log_format(const char *unit,
33+
const char *filename,
34+
unsigned line,
35+
const char *section,
36+
unsigned section_line,
37+
const char *lvalue,
38+
int ltype,
39+
const char *rvalue,
40+
void *data,
41+
void *userdata);
42+
3043
int manager_parse_config_file(Manager *m);

src/netlog/netlog-gperf.gperf

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ struct ConfigPerfItem;
1515
%struct-type
1616
%includes
1717
%%
18-
Network.Address, config_parse_netlog_remote_address, 0, 0
19-
Network.Protocol, config_parse_protocol, 0, offsetof(Manager, protocol)
20-
Network.StructuredData, config_parse_string, 0, offsetof(Manager, structured_data)
18+
Network.Address, config_parse_netlog_remote_address, 0, 0
19+
Network.Protocol, config_parse_protocol, 0, offsetof(Manager, protocol)
20+
Network.LogFormat, config_parse_log_format, 0, offsetof(Manager, log_format)
21+
Network.StructuredData, config_parse_string, 0, offsetof(Manager, structured_data)

src/netlog/netlog-manager.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ static const char *const protocol_table[_SYSLOG_TRANSMISSION_PROTOCOL_MAX] = {
3434

3535
DEFINE_STRING_TABLE_LOOKUP(protocol, int);
3636

37+
static const char *const log_format_table[_SYSLOG_TRANSMISSION_LOG_FORMAT_MAX] = {
38+
[SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5424] = "rfc5424",
39+
[SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_3339] = "rfc3339",
40+
};
41+
42+
DEFINE_STRING_TABLE_LOOKUP(log_format, int);
43+
3744
static int parse_field(const void *data, size_t length, const char *field, char **target) {
3845
size_t fl, nl;
3946
void *buf;
@@ -351,11 +358,11 @@ int manager_connect(Manager *m) {
351358

352359
r = manager_open_network_socket(m);
353360
if (r < 0)
354-
return r;
361+
return log_error_errno(r, "Failed to create network socket: %m");
355362

356363
r = manager_journal_monitor_listen(m);
357364
if (r < 0)
358-
return r;
365+
return log_error_errno(r, "Failed to monitor journal: %m");
359366

360367
return 0;
361368
}
@@ -448,29 +455,31 @@ void manager_free(Manager *m) {
448455
free(m);
449456
}
450457

451-
int manager_new(Manager **ret, const char *state_file, const char *cursor) {
458+
int manager_new(const char *state_file, const char *cursor, Manager **ret) {
452459
_cleanup_(manager_freep) Manager *m = NULL;
453460
int r;
454461

455462
assert(ret);
456463

457-
m = new0(Manager, 1);
464+
m = new(Manager, 1);
458465
if (!m)
459466
return -ENOMEM;
460467

461-
m->socket = m->journal_watch_fd = -1;
462-
463-
m->state_file = strdup(state_file);
464-
if (!m->state_file)
465-
return -ENOMEM;
468+
*m = (Manager) {
469+
.socket = -1,
470+
.journal_watch_fd = -1,
471+
.state_file = strdup(state_file),
472+
.protocol = SYSLOG_TRANSMISSION_PROTOCOL_UDP,
473+
.log_format = SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5424,
474+
};
466475

467476
if (cursor) {
468477
m->last_cursor = strdup(cursor);
469478
if (!m->last_cursor)
470479
return -ENOMEM;
471480
}
472481

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

src/netlog/netlog-manager.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ typedef enum SysLogTransmissionProtocol {
1414
_SYSLOG_TRANSMISSION_PROTOCOL_INVALID = -EINVAL,
1515
} SysLogTransmissionProtocol;
1616

17+
typedef enum SysLogTransmissionLogFormat {
18+
SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5424 = 1 << 0,
19+
SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_3339 = 1 << 1,
20+
_SYSLOG_TRANSMISSION_LOG_FORMAT_MAX,
21+
_SYSLOG_TRANSMISSION_LOG_FORMAT_INVALID = -EINVAL,
22+
} SysLogTransmissionLogFormat;
23+
1724
typedef struct Manager Manager;
1825

1926
struct Manager {
@@ -41,9 +48,10 @@ struct Manager {
4148
char *last_cursor, *current_cursor;
4249
char *structured_data;
4350
SysLogTransmissionProtocol protocol;
51+
SysLogTransmissionLogFormat log_format;
4452
};
4553

46-
int manager_new(Manager **ret, const char *state_file, const char *cursor);
54+
int manager_new(const char *state_file, const char *cursor, Manager **ret);
4755
void manager_free(Manager *m);
4856

4957
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
@@ -61,3 +69,6 @@ int manager_push_to_network(Manager *m, int severity, int facility,
6169

6270
const char *protocol_to_string(int v) _const_;
6371
int protocol_from_string(const char *s) _pure_;
72+
73+
const char *log_format_to_string(int v) _const_;
74+
int log_format_from_string(const char *s) _pure_;

src/netlog/netlog-network.c

Lines changed: 106 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,19 @@ static void format_rfc3339_timestamp(const struct timeval *tv, char *header_time
8787
/* The Syslog Protocol RFC5424 format :
8888
* <pri>version sp timestamp sp hostname sp app-name sp procid sp msgid sp [sd-id]s sp msg
8989
*/
90-
int manager_push_to_network(Manager *m,
91-
int severity,
92-
int facility,
93-
const char *identifier,
94-
const char *message,
95-
const char *hostname,
96-
const char *pid,
97-
const struct timeval *tv) {
98-
char header_priority[sizeof("< >1 ")];
90+
static int format_rfc5424(Manager *m,
91+
int severity,
92+
int facility,
93+
const char *identifier,
94+
const char *message,
95+
const char *hostname,
96+
const char *pid,
97+
const struct timeval *tv) {
98+
9999
char header_time[FORMAT_TIMESTAMP_MAX];
100-
uint8_t makepri;
100+
char header_priority[sizeof("< >1 ")];
101101
struct iovec iov[14];
102+
uint8_t makepri;
102103
int n = 0;
103104

104105
assert(m);
@@ -153,7 +154,7 @@ int manager_push_to_network(Manager *m,
153154
/* Ninth: message */
154155
IOVEC_SET_STRING(iov[n++], message);
155156

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

165-
void manager_close_network_socket(Manager *m) {
166+
static int format_rfc3339(Manager *m,
167+
int severity,
168+
int facility,
169+
const char *identifier,
170+
const char *message,
171+
const char *hostname,
172+
const char *pid,
173+
const struct timeval *tv) {
174+
175+
char header_priority[sizeof("< >1 ")];
176+
char header_time[FORMAT_TIMESTAMP_MAX];
177+
struct iovec iov[14];
178+
uint8_t makepri;
179+
int n = 0;
180+
166181
assert(m);
182+
assert(message);
183+
184+
makepri = (facility << 3) + severity;
185+
186+
/* rfc3339
187+
* <35>Oct 12 22:14:15 client_machine su: 'su root' failed for joe on /dev/pts/2
188+
*/
189+
190+
/* First: priority field '<pri>' */
191+
snprintf(header_priority, sizeof(header_priority), "<%i>", makepri);
192+
IOVEC_SET_STRING(iov[n++], header_priority);
193+
194+
/* Third: timestamp */
195+
format_rfc3339_timestamp(tv, header_time, sizeof(header_time));
196+
IOVEC_SET_STRING(iov[n++], header_time);
197+
198+
/* Fourth: hostname */
199+
if (hostname)
200+
IOVEC_SET_STRING(iov[n++], hostname);
201+
else
202+
IOVEC_SET_STRING(iov[n++], RFC_5424_NILVALUE);
203+
204+
IOVEC_SET_STRING(iov[n++], " ");
205+
206+
/* Fifth: identifier */
207+
if (identifier)
208+
IOVEC_SET_STRING(iov[n++], identifier);
209+
else
210+
IOVEC_SET_STRING(iov[n++], RFC_5424_NILVALUE);
211+
212+
IOVEC_SET_STRING(iov[n++], "[");
213+
214+
/* Sixth: procid */
215+
if (pid)
216+
IOVEC_SET_STRING(iov[n++], pid);
217+
else
218+
IOVEC_SET_STRING(iov[n++], RFC_5424_NILVALUE);
219+
220+
IOVEC_SET_STRING(iov[n++], "]: ");
221+
222+
/* Ninth: message */
223+
IOVEC_SET_STRING(iov[n++], message);
224+
225+
/* Last Optional newline message separator, if not implicitly terminated by end of UDP frame
226+
* De facto standard: separate messages by a newline
227+
*/
228+
if (m->protocol == SYSLOG_TRANSMISSION_PROTOCOL_TCP)
229+
IOVEC_SET_STRING(iov[n++], "\n");
230+
231+
return network_send(m, iov, n);
232+
}
233+
234+
int manager_push_to_network(Manager *m,
235+
int severity,
236+
int facility,
237+
const char *identifier,
238+
const char *message,
239+
const char *hostname,
240+
const char *pid,
241+
const struct timeval *tv) {
242+
243+
int r;
244+
245+
assert(m);
246+
assert(message);
247+
248+
if (m->log_format == SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5424)
249+
r = format_rfc5424(m, severity, facility, identifier, message, hostname, pid, tv);
250+
else
251+
r = format_rfc3339(m, severity, facility, identifier, message, hostname, pid, tv);
252+
253+
if (r < 0)
254+
return 0;
255+
256+
return 0;
257+
}
258+
259+
void manager_close_network_socket(Manager *m) {
260+
assert(m);
167261

168262
if (m->protocol == SYSLOG_TRANSMISSION_PROTOCOL_TCP) {
169263
int r = shutdown(m->socket, SHUT_RDWR);

src/netlog/systemd-netlogd.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ static int setup_cursor_state_file(Manager *m, uid_t uid, gid_t gid) {
6060
static void help(void) {
6161
printf("%s ..\n\n"
6262
"Forwards messages from the journal to other hosts over the network using the syslog\n"
63-
"RFC 5424 format in both unicast and multicast addresses.\n\n"
63+
"RFC 5424 or RFC3339 format in both unicast and multicast addresses.\n\n"
6464
" -h --help Show this help\n"
6565
" --version Show package version\n"
6666
" --cursor=CURSOR Start at the specified cursor\n"
@@ -159,7 +159,7 @@ int main(int argc, char **argv) {
159159
goto finish;
160160
}
161161

162-
r = manager_new(&m, arg_save_state, arg_cursor);
162+
r = manager_new(arg_save_state, arg_cursor, &m);
163163
if (r < 0) {
164164
log_error_errno(r, "Failed to allocate manager: %m");
165165
goto finish;
@@ -191,7 +191,7 @@ int main(int argc, char **argv) {
191191

192192
if (network_is_online()) {
193193
r = manager_connect(m);
194-
if (r < 0)
194+
if (r < 0)
195195
goto finish;
196196
}
197197

src/share/alloc-util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#include "macro.h"
1010

11-
#define new(t, n) ((t*) malloc_multiply(sizeof(t), (n)))
11+
#define new(t, n) ((t*) malloc_multiply(n, sizeof(t)))
1212

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

0 commit comments

Comments
 (0)