Skip to content

Commit bc9cdf8

Browse files
authored
Merge pull request #45 from ssahani/journal-structed-data
Journal structed data
2 parents 9ba7eb0 + 272c056 commit bc9cdf8

8 files changed

+140
-29
lines changed

README.md

+47-3
Original file line numberDiff line numberDiff line change
@@ -47,37 +47,81 @@ systemd-netlogd reads configuration files named `/etc/systemd/netlogd.conf` and
4747
to a unicast UDP address or multicast UDP network group in syslog RFC 5424 format.
4848

4949
The the address string format is similar to socket units. See systemd.socket(1)
50-
50+
5151
Protocol=
5252
Specifies whether to use udp or tcp protocol. Defaults to udp.
53-
54-
LogFormat=
53+
54+
LogFormat=
5555
Specifies whether to use RFC 5424 format or RFC 3339 format. Takes one of rfc5424 or rfc3339. Defaults to rfc5424.
5656
Optional settings
5757

5858
StructuredData=
5959
Meta information about the syslog message, which can be used for Cloud Based
6060
syslog servers, such as Loggly
6161

62+
UseSysLogStructuredData=
63+
A boolean. Specifies whether to extract ```SYSLOG_STRUCTURED_DATA=``` from journal. Defaults to false.
64+
65+
UseSysLogMsgId=
66+
A boolean. Specifies whether to extract ```SYSLOG_MSGID=``` from journal. Defaults to false.
67+
68+
6269
**EXAMPLE**
6370

6471
Example 1. /etc/systemd/netlogd.conf
6572

73+
``` sh
6674
[Network]
6775
Address=239.0.0.1:6000
6876
#Protocol=udp
6977
#LogFormat=rfc5424
78+
79+
```
80+
7081
Example 2. /etc/systemd/netlogd.conf
7182

83+
``` sh
7284
[Network]
7385
Address=192.168.8.101:514
7486
#Protocol=udp
7587
LogFormat=rfc3339
7688

89+
```
90+
7791
Example 3. /etc/systemd/netlogd.conf
7892

93+
``` sh
94+
7995
[Network]
8096
Address=192.168.8.101:514
8197
#Protocol=udp
8298
LogFormat=rfc5424
8399
StructuredData=[1ab456b6-90bb-6578-abcd-5b734584aaaa@41058]
100+
101+
```
102+
103+
Example 4. /etc/systemd/netlogd.conf
104+
105+
``` sh
106+
107+
[Network]
108+
Address=192.168.8.101:514
109+
#Protocol=udp
110+
LogFormat=rfc5424
111+
UseSysLogStructuredData=yes
112+
UseSysLogMsgId=yes
113+
114+
```
115+
116+
Use case of ```UseSysLogStructuredData=``` and ```UseSysLogMsgId=```
117+
118+
```
119+
sd_journal_send(
120+
"MESSAGE=%s", "Message to process",
121+
"PRIORITY=%s", "4",
122+
"SYSLOG_FACILITY=%s", "1",
123+
"SYSLOG_MSGID=%s", "1011",
124+
"SYSLOG_STRUCTURED_DATA=%s", R"([exampleSDID@32473 iut="3" eventSource="Application"])",
125+
NULL
126+
);
127+
```

src/netlog/netlog-conf.c

+5-8
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ int config_parse_netlog_remote_address(const char *unit,
2626

2727
r = socket_address_parse(&m->address, rvalue);
2828
if (r < 0) {
29-
log_syntax(unit, LOG_ERR, filename, line, -r,
30-
"Failed to parse address value, ignoring: %s", rvalue);
29+
log_syntax(unit, LOG_WARNING, filename, line, -r, "Failed to parse '%s=%s', ignoring.", lvalue, rvalue);
3130
return 0;
3231
}
3332

@@ -54,9 +53,8 @@ int config_parse_protocol(const char *unit,
5453

5554
r = protocol_from_string(rvalue);
5655
if (r < 0) {
57-
log_syntax(unit, LOG_ERR, filename, line, -r,
58-
"Unrecognised Protocol '%s'", rvalue);
59-
return -EPROTONOSUPPORT;
56+
log_syntax(unit, LOG_WARNING, filename, line, -r, "Failed to parse '%s=%s', ignoring.", lvalue, rvalue);
57+
return 0;
6058
}
6159

6260
m->protocol = r;
@@ -83,9 +81,8 @@ int config_parse_log_format(const char *unit,
8381

8482
r = log_format_from_string(rvalue);
8583
if (r < 0) {
86-
log_syntax(unit, LOG_ERR, filename, line, -r,
87-
"Unrecognised log format '%s'", rvalue);
88-
return -EPROTONOSUPPORT;
84+
log_syntax(unit, LOG_WARNING, filename, line, -r, "Failed to parse '%s=%s', ignoring.", lvalue, rvalue);
85+
return 0;
8986
}
9087

9188
m->log_format = r;

src/netlog/netlog-gperf.gperf

+6-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ 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.LogFormat, config_parse_log_format, 0, offsetof(Manager, log_format)
21-
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)
22+
Network.UseSysLogStructuredData, config_parse_bool, 0, offsetof(Manager, syslog_structured_data)
23+
Network.UseSysLogMsgId, config_parse_bool, 0, offsetof(Manager, syslog_msgid)

src/netlog/netlog-manager.c

+21-5
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,8 @@ static int parse_field(const void *data, size_t length, const char *field, char
7171
}
7272

7373
static int manager_read_journal_input(Manager *m) {
74-
_cleanup_free_ char *facility = NULL, *identifier = NULL,
75-
*priority = NULL, *message = NULL, *pid = NULL,
76-
*hostname = NULL;
74+
_cleanup_free_ char *facility = NULL, *identifier = NULL, *priority = NULL, *message = NULL, *pid = NULL,
75+
*hostname = NULL, *structured_data = NULL, *msgid = NULL;
7776
unsigned sev = JOURNAL_DEFAULT_SEVERITY;
7877
unsigned fac = JOURNAL_DEFAULT_FACILITY;
7978
struct timeval tv;
@@ -120,6 +119,16 @@ static int manager_read_journal_input(Manager *m) {
120119
r = parse_field(data, length, "MESSAGE=", &message);
121120
if (r < 0)
122121
return r;
122+
123+
r = parse_field(data, length, "SYSLOG_STRUCTURED_DATA=", &structured_data);
124+
if (r < 0)
125+
return r;
126+
else if (r > 0)
127+
continue;
128+
129+
r = parse_field(data, length, "SYSLOG_MSGID=", &msgid);
130+
if (r < 0)
131+
return r;
123132
}
124133

125134
r = sd_journal_get_realtime_usec(m->journal, &realtime);
@@ -148,8 +157,15 @@ static int manager_read_journal_input(Manager *m) {
148157
sev = JOURNAL_DEFAULT_SEVERITY;
149158
}
150159

151-
return manager_push_to_network(m, sev, fac, identifier,
152-
message, hostname, pid, r >= 0 ? &tv : NULL);
160+
return manager_push_to_network(m,
161+
sev,
162+
fac,
163+
identifier,
164+
message, hostname,
165+
pid,
166+
r >= 0 ? &tv : NULL,
167+
structured_data,
168+
msgid);
153169
}
154170

155171
static int update_cursor_state(Manager *m) {

src/netlog/netlog-manager.h

+14-5
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,14 @@ struct Manager {
4444
sd_journal *journal;
4545

4646
char *state_file;
47-
4847
char *last_cursor, *current_cursor;
4948
char *structured_data;
49+
5050
SysLogTransmissionProtocol protocol;
5151
SysLogTransmissionLogFormat log_format;
52+
53+
bool syslog_structured_data;
54+
bool syslog_msgid;
5255
};
5356

5457
int manager_new(const char *state_file, const char *cursor, Manager **ret);
@@ -62,10 +65,16 @@ void manager_disconnect(Manager *m);
6265
void manager_close_network_socket(Manager *m);
6366
int manager_open_network_socket(Manager *m);
6467

65-
int manager_push_to_network(Manager *m, int severity, int facility,
66-
const char *identifier, const char *message,
67-
const char *hostname, const char *pid,
68-
const struct timeval *tv);
68+
int manager_push_to_network(Manager *m,
69+
int severity,
70+
int facility,
71+
const char *identifier,
72+
const char *message,
73+
const char *hostname,
74+
const char *pid,
75+
const struct timeval *tv,
76+
const char *syslog_structured_data,
77+
const char *syslog_msgid);
6978

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

src/netlog/netlog-network.c

+14-4
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ static int format_rfc5424(Manager *m,
9494
const char *message,
9595
const char *hostname,
9696
const char *pid,
97-
const struct timeval *tv) {
97+
const struct timeval *tv,
98+
const char *syslog_structured_data,
99+
const char *syslog_msgid) {
98100

99101
char header_time[FORMAT_TIMESTAMP_MAX];
100102
char header_priority[sizeof("< >1 ")];
@@ -140,12 +142,18 @@ static int format_rfc5424(Manager *m,
140142
IOVEC_SET_STRING(iov[n++], " ");
141143

142144
/* Seventh: msgid */
143-
IOVEC_SET_STRING(iov[n++], RFC_5424_NILVALUE);
145+
if (syslog_msgid)
146+
IOVEC_SET_STRING(iov[n++], syslog_msgid);
147+
else
148+
IOVEC_SET_STRING(iov[n++], RFC_5424_NILVALUE);
149+
144150
IOVEC_SET_STRING(iov[n++], " ");
145151

146152
/* Eighth: [structured-data] */
147153
if (m->structured_data)
148154
IOVEC_SET_STRING(iov[n++], m->structured_data);
155+
else if (syslog_structured_data)
156+
IOVEC_SET_STRING(iov[n++], syslog_structured_data);
149157
else
150158
IOVEC_SET_STRING(iov[n++], RFC_5424_NILVALUE);
151159

@@ -238,7 +246,9 @@ int manager_push_to_network(Manager *m,
238246
const char *message,
239247
const char *hostname,
240248
const char *pid,
241-
const struct timeval *tv) {
249+
const struct timeval *tv,
250+
const char *syslog_structured_data,
251+
const char *syslog_msgid) {
242252

243253
int r;
244254

@@ -248,7 +258,7 @@ int manager_push_to_network(Manager *m,
248258
return 0;
249259

250260
if (m->log_format == SYSLOG_TRANSMISSION_LOG_FORMAT_RFC_5424)
251-
r = format_rfc5424(m, severity, facility, identifier, message, hostname, pid, tv);
261+
r = format_rfc5424(m, severity, facility, identifier, message, hostname, pid, tv, syslog_structured_data, syslog_msgid);
252262
else
253263
r = format_rfc3339(m, severity, facility, identifier, message, hostname, pid, tv);
254264

src/share/conf-parser.c

+32
Original file line numberDiff line numberDiff line change
@@ -479,3 +479,35 @@ int config_parse_string(
479479

480480
return 0;
481481
}
482+
483+
int config_parse_bool(
484+
const char* unit,
485+
const char *filename,
486+
unsigned line,
487+
const char *section,
488+
unsigned section_line,
489+
const char *lvalue,
490+
int ltype,
491+
const char *rvalue,
492+
void *data,
493+
void *userdata) {
494+
495+
bool fatal = ltype;
496+
bool *b = data;
497+
int k;
498+
499+
assert(filename);
500+
assert(lvalue);
501+
assert(rvalue);
502+
503+
k = parse_boolean(rvalue);
504+
if (k < 0) {
505+
log_syntax(unit, fatal ? LOG_ERR : LOG_WARNING, filename, line, k,
506+
"Failed to parse boolean value%s: %s",
507+
fatal ? "" : ", ignoring", rvalue);
508+
return fatal ? -ENOEXEC : 0;
509+
}
510+
511+
*b = k;
512+
return 0;
513+
}

src/share/conf-parser.h

+1
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ int config_parse_many(const char *conf_file, /* possibly NULL */
8888

8989
/* Generic parsers */
9090
int config_parse_string(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);
91+
int config_parse_bool(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);
9192

9293
#define DEFINE_CONFIG_PARSE_ENUM(function,name,type,msg) \
9394
int function(const char *unit, \

0 commit comments

Comments
 (0)