Add RFC5424 support for remote syslog servers
This patch adds support for sending in RFC5424[1] style format to remote log servers. Section 6.5[2] lists some examples, here's one: <30>1 2019-10-12T18:21:01.123456+02:00 troglobit finit 321 - - Starting service 'firewalld:1' Note, sysklogd currently does not support MSGID and structured data, see the RFC for more information on this. [1] - https://tools.ietf.org/html/rfc5424 [2] - https://tools.ietf.org/html/rfc5424#section-6.5 Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
parent
a2eb744f26
commit
301081604a
134
src/syslogd.c
134
src/syslogd.c
@ -653,6 +653,14 @@ int funix[MAXFUNIX] = {
|
|||||||
#define SYNC_FILE 0x002 /* do fsync on file after printing */
|
#define SYNC_FILE 0x002 /* do fsync on file after printing */
|
||||||
#define ADDDATE 0x004 /* add a date to the message */
|
#define ADDDATE 0x004 /* add a date to the message */
|
||||||
#define MARK 0x008 /* this message is a mark */
|
#define MARK 0x008 /* this message is a mark */
|
||||||
|
#define RFC5424 0x010 /* format log message according to RFC 5424 */
|
||||||
|
|
||||||
|
/* Timestamps of log entries. */
|
||||||
|
struct logtime {
|
||||||
|
struct tm tm;
|
||||||
|
suseconds_t usec;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This table contains plain text for h_errno errors used by the
|
* This table contains plain text for h_errno errors used by the
|
||||||
@ -1906,6 +1914,114 @@ void logrotate(struct filed *f)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Trims the application name ("TAG" in RFC 3164 terminology) and
|
||||||
|
* process ID from a message if present.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
parsemsg_rfc3164_app_name_procid(char **msg, char **app_name, char **procid)
|
||||||
|
{
|
||||||
|
char *m, *app_name_begin, *procid_begin;
|
||||||
|
size_t app_name_length, procid_length;
|
||||||
|
|
||||||
|
m = *msg;
|
||||||
|
|
||||||
|
/* Application name. */
|
||||||
|
app_name_begin = m;
|
||||||
|
app_name_length = strspn(m,
|
||||||
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
|
"0123456789"
|
||||||
|
"_-/");
|
||||||
|
if (app_name_length == 0)
|
||||||
|
goto bad;
|
||||||
|
m += app_name_length;
|
||||||
|
|
||||||
|
/* Process identifier (optional). */
|
||||||
|
if (*m == '[') {
|
||||||
|
procid_begin = ++m;
|
||||||
|
procid_length = strspn(m, "0123456789");
|
||||||
|
if (procid_length == 0)
|
||||||
|
goto bad;
|
||||||
|
m += procid_length;
|
||||||
|
if (*m++ != ']')
|
||||||
|
goto bad;
|
||||||
|
} else {
|
||||||
|
procid_begin = NULL;
|
||||||
|
procid_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Separator. */
|
||||||
|
if (m[0] != ':' || m[1] != ' ')
|
||||||
|
goto bad;
|
||||||
|
|
||||||
|
/* Split strings from input. */
|
||||||
|
app_name_begin[app_name_length] = '\0';
|
||||||
|
if (procid_begin != 0)
|
||||||
|
procid_begin[procid_length] = '\0';
|
||||||
|
|
||||||
|
*msg = m + 2;
|
||||||
|
*app_name = app_name_begin;
|
||||||
|
*procid = procid_begin;
|
||||||
|
return;
|
||||||
|
bad:
|
||||||
|
*app_name = NULL;
|
||||||
|
*procid = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Currently unsupported RFC 5424 fields: msgid, structured_data
|
||||||
|
*/
|
||||||
|
static void fmt5424(char *line, size_t len, int pri, char *msg)
|
||||||
|
{
|
||||||
|
struct logtime *timestamp = NULL;
|
||||||
|
struct logtime timestamp_now;
|
||||||
|
struct timeval tv;
|
||||||
|
suseconds_t usec;
|
||||||
|
char *structured_data = NULL;
|
||||||
|
char *app_name = NULL;
|
||||||
|
char *procid = NULL;
|
||||||
|
char *msgid = NULL;
|
||||||
|
char hostname[256];
|
||||||
|
char timebuf[33];
|
||||||
|
|
||||||
|
parsemsg_rfc3164_app_name_procid(&msg, &app_name, &procid);
|
||||||
|
|
||||||
|
gethostname(hostname, sizeof(hostname));
|
||||||
|
|
||||||
|
(void)gettimeofday(&tv, NULL);
|
||||||
|
now = tv.tv_sec;
|
||||||
|
|
||||||
|
if (timestamp == NULL) {
|
||||||
|
localtime_r(&now, ×tamp_now.tm);
|
||||||
|
timestamp_now.usec = tv.tv_usec;
|
||||||
|
timestamp = ×tamp_now;
|
||||||
|
}
|
||||||
|
|
||||||
|
strftime(timebuf, sizeof(timebuf), "%FT%T.______%z", ×tamp->tm);
|
||||||
|
|
||||||
|
/* Add colon to the time zone offset, which %z doesn't do */
|
||||||
|
timebuf[32] = '\0';
|
||||||
|
timebuf[31] = timebuf[30];
|
||||||
|
timebuf[30] = timebuf[29];
|
||||||
|
timebuf[29] = ':';
|
||||||
|
|
||||||
|
/* Overwrite space for microseconds with actual value */
|
||||||
|
usec = timestamp->usec;
|
||||||
|
for (int i = 25; i >= 20; --i) {
|
||||||
|
timebuf[i] = usec % 10 + '0';
|
||||||
|
usec /= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(line, len, "<%d>1 %s %s %s %s %s %s %s",
|
||||||
|
pri, timebuf, hostname,
|
||||||
|
app_name == NULL ? "-" : app_name,
|
||||||
|
procid == NULL ? "-" : procid,
|
||||||
|
msgid == NULL ? "-" : msgid,
|
||||||
|
structured_data == NULL ? "-" : structured_data,
|
||||||
|
msg);
|
||||||
|
}
|
||||||
|
|
||||||
void fprintlog(struct filed *f, char *from, int flags, char *msg)
|
void fprintlog(struct filed *f, char *from, int flags, char *msg)
|
||||||
{
|
{
|
||||||
struct iovec iov[6];
|
struct iovec iov[6];
|
||||||
@ -2020,8 +2136,12 @@ void fprintlog(struct filed *f, char *from, int flags, char *msg)
|
|||||||
else if (finet) {
|
else if (finet) {
|
||||||
int i;
|
int i;
|
||||||
f->f_time = now;
|
f->f_time = now;
|
||||||
(void)snprintf(line, sizeof(line), "<%d>%s", f->f_prevpri,
|
if (f->f_flags & RFC5424)
|
||||||
(char *)iov[4].iov_base);
|
fmt5424(line, sizeof(line), f->f_prevpri,
|
||||||
|
(char *)iov[4].iov_base);
|
||||||
|
else
|
||||||
|
snprintf(line, sizeof(line), "<%d>%s", f->f_prevpri,
|
||||||
|
(char *)iov[4].iov_base);
|
||||||
l = strlen(line);
|
l = strlen(line);
|
||||||
if (l > MAXLINE)
|
if (l > MAXLINE)
|
||||||
l = MAXLINE;
|
l = MAXLINE;
|
||||||
@ -2934,6 +3054,16 @@ void cfline(char *line, struct filed *f)
|
|||||||
switch (*p) {
|
switch (*p) {
|
||||||
case '@':
|
case '@':
|
||||||
#ifdef SYSLOG_INET
|
#ifdef SYSLOG_INET
|
||||||
|
bp = p;
|
||||||
|
while ((q = strchr(bp, ';'))) {
|
||||||
|
*q++ = 0;
|
||||||
|
if (q) {
|
||||||
|
if (!strncmp(q, "RFC5424", 7))
|
||||||
|
f->f_flags |= RFC5424;
|
||||||
|
/* More flags can be added here */
|
||||||
|
}
|
||||||
|
bp = q;
|
||||||
|
}
|
||||||
(void)strcpy(f->f_un.f_forw.f_hname, ++p);
|
(void)strcpy(f->f_un.f_forw.f_hname, ++p);
|
||||||
logit("forwarding host: %s\n", p); /*ASP*/
|
logit("forwarding host: %s\n", p); /*ASP*/
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user