From 4c0c501383fd992f08c55278edf1d43b6569930e Mon Sep 17 00:00:00 2001 From: Tomas Heinrich Date: Wed, 12 Feb 2014 15:43:19 +0100 Subject: [PATCH] Add a patch to prevent message loss in imjournal --- ...4.8-bz1026804-imjournal-message-loss.patch | 267 ++++++++++++++++++ rsyslog.spec | 4 + 2 files changed, 271 insertions(+) create mode 100644 rsyslog-7.4.8-bz1026804-imjournal-message-loss.patch diff --git a/rsyslog-7.4.8-bz1026804-imjournal-message-loss.patch b/rsyslog-7.4.8-bz1026804-imjournal-message-loss.patch new file mode 100644 index 0000000..73134f5 --- /dev/null +++ b/rsyslog-7.4.8-bz1026804-imjournal-message-loss.patch @@ -0,0 +1,267 @@ +From effa35d1ae33c1ac825317802b6e970e68f98af2 Mon Sep 17 00:00:00 2001 +From: Tomas Heinrich +Date: Fri, 31 Jan 2014 11:35:55 +0100 +Subject: [PATCH] Improve handling of messages without syslog properties + +* Don't drop messages without the MESSAGE field +* Set default severity for all messages + Some messages comming from journald don't have the SYSLOG_PRIORITY + field. These are typically the messages logged through journald's + native API. Set the default severity for these messages to 'notice'. +* Set default facility for all messages + Some messages comming from journald don't have the SYSLOG_FACILITY + field. These are typically the messages logged through journald's + native API. Set the default facility for these messages to 'user'. +* Make default priority configurable +--- + doc/imjournal.html | 16 ++++++ + plugins/imjournal/imjournal.c | 124 +++++++++++++++++++++++++++++++----------- + 2 files changed, 109 insertions(+), 31 deletions(-) + +diff --git a/doc/imjournal.html b/doc/imjournal.html +index 8f29169..b4d2105 100644 +--- a/doc/imjournal.html ++++ b/doc/imjournal.html +@@ -69,6 +69,18 @@ journal and read only new messages. This option is only used when there is + no StateFile to avoid message loss. + + ++
  • DefaultSeverity <severity>
    ++Some messages comming from journald don't have the SYSLOG_PRIORITY ++field. These are typically the messages logged through journald's ++native API. This option specifies the default severity for these ++messages. Defaults to 'notice'. ++ ++
  • DefaultFacility <facility>
    ++Some messages comming from journald don't have the SYSLOG_FACILITY ++field. These are typically the messages logged through journald's ++native API. This option specifies the default facility for these ++messages. Defaults to 'user'. ++ + Caveats/Known Bugs: +

    +

      +@@ -105,6 +117,10 @@ Equivalent to: ratelimit.interval + Equivalent to: ratelimit.burst +
    • $ImjournalIgnorePreviousMessages
      + Equivalent to: ignorePreviousMessages
    • ++
    • $ImjournalDefaultSeverity
      ++Equivalent to: DefaultSeverity
    • ++
    • $ImjournalDefaultFacility
      ++Equivalent to: DefaultFacility
    • +
    + + +diff --git a/plugins/imjournal/imjournal.c b/plugins/imjournal/imjournal.c +index 36c7e04..7d42b84 100755 +--- a/plugins/imjournal/imjournal.c ++++ b/plugins/imjournal/imjournal.c +@@ -68,15 +68,21 @@ static struct configSettings_s { + int ratelimitInterval; + int ratelimitBurst; + int bIgnorePrevious; ++ int iDfltSeverity; ++ int iDfltFacility; + } cs; + ++static rsRetVal facilityHdlr(uchar **pp, void *pVal); ++ + /* module-global parameters */ + static struct cnfparamdescr modpdescr[] = { + { "statefile", eCmdHdlrGetWord, 0 }, + { "ratelimit.interval", eCmdHdlrInt, 0 }, + { "ratelimit.burst", eCmdHdlrInt, 0 }, + { "persiststateinterval", eCmdHdlrInt, 0 }, +- { "ignorepreviousmessages", eCmdHdlrBinary, 0 } ++ { "ignorepreviousmessages", eCmdHdlrBinary, 0 }, ++ { "defaultseverity", eCmdHdlrSeverity, 0 }, ++ { "defaultfacility", eCmdHdlrString, 0 } + }; + static struct cnfparamblk modpblk = + { CNFPARAMBLK_VERSION, +@@ -85,6 +91,8 @@ static struct cnfparamblk modpblk = + }; + + #define DFLT_persiststateinterval 10 ++#define DFLT_SEVERITY LOG_PRI(LOG_NOTICE) ++#define DFLT_FACILITY LOG_FAC(LOG_USER) + + static int bLegacyCnfModGlobalsPermitted = 1;/* are legacy module-global config parameters permitted? */ + +@@ -94,6 +102,37 @@ static prop_t *pLocalHostIP = NULL; /* a pseudo-constant propterty for 127.0.0.1 + static ratelimit_t *ratelimiter = NULL; + static sd_journal *j; + ++/* ugly workaround to handle facility numbers; values ++ derived from names need to be eight times smaller */ ++static rsRetVal facilityHdlr(uchar **pp, void *pVal) ++{ ++ DEFiRet; ++ char *p; ++ ++ skipWhiteSpace(pp); ++ p = (char *) *pp; ++ ++ if (isdigit((int) *p)) { ++ *((int *) pVal) = (int) strtol(p, (char **) pp, 10); ++ } else { ++ int len; ++ syslogName_t *c; ++ ++ for (len = 0; p[len] && !isspace((int) p[len]); len++) ++ /* noop */; ++ for (c = syslogFacNames; c->c_name; c++) { ++ if (!strncasecmp(p, (char *) c->c_name, len)) { ++ *((int *) pVal) = LOG_FAC(c->c_val); ++ break; ++ } ++ } ++ *pp += len; ++ } ++ ++ RETiRet; ++} ++ ++ + /* enqueue the the journal message into the message queue. + * The provided msg string is not freed - thus must be done + * by the caller. +@@ -158,7 +197,6 @@ readjournal() { + const void *get; + const void *pidget; + char *parse; +- char *get2; + size_t length; + size_t pidlength; + +@@ -170,45 +208,52 @@ readjournal() { + + long prefixlen = 0; + +- int priority = 0; +- int facility = 0; ++ int severity = cs.iDfltSeverity; ++ int facility = cs.iDfltFacility; + + /* Get message text */ + if (sd_journal_get_data(j, "MESSAGE", &get, &length) < 0) { +- logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar *)"log message from journal doesn't have MESSAGE", 0); +- iRet = RS_RET_OK; +- goto ret; +- } +- message = strndup(get+8, length-8); +- if (message == NULL) { +- iRet = RS_RET_OUT_OF_MEMORY; +- goto ret; ++ message = strdup(""); ++ } else { ++ message = strndup(get+8, length-8); ++ if (message == NULL) { ++ iRet = RS_RET_OUT_OF_MEMORY; ++ goto ret; ++ } + } + +- /* Get message priority */ ++ /* Get message severity ("priority" in journald's terminology) */ + if (sd_journal_get_data(j, "PRIORITY", &get, &length) >= 0) { +- get2 = strndup(get, length); +- priority = ((char *)get2)[9] - '0'; +- free (get2); ++ if (length == 10) { ++ severity = ((char *)get)[9] - '0'; ++ if (severity < 0 || 7 < severity) { ++ dbgprintf("The value of the 'PRIORITY' field is " ++ "out of bounds: %d, resetting\n", severity); ++ severity = cs.iDfltSeverity; ++ } ++ } else { ++ dbgprintf("The value of the 'PRIORITY' field has an " ++ "unexpected length: %d\n", length); ++ } + } + + /* Get syslog facility */ + if (sd_journal_get_data(j, "SYSLOG_FACILITY", &get, &length) >= 0) { +- get2 = strndup(get, length); +- char f = ((char *)get2)[16]; +- if (f >= '0' && f <= '9') { +- facility += f - '0'; +- } +- f = ((char *)get2)[17]; +- if (f >= '0' && f <= '9') { +- facility *= 10; +- facility += (f - '0'); ++ if (length == 17 || length == 18) { ++ facility = ((char *)get)[16] - '0'; ++ if (length == 18) { ++ facility *= 10; ++ facility += ((char *)get)[17] - '0'; ++ } ++ if (facility < 0 || 23 < facility) { ++ dbgprintf("The value of the 'FACILITY' field is " ++ "out of bounds: %d, resetting\n", facility); ++ facility = cs.iDfltFacility; ++ } ++ } else { ++ dbgprintf("The value of the 'FACILITY' field has an " ++ "unexpected length: %d\n", length); + } +- free (get2); +- } else { +- /* message is missing facility -> internal systemd journal msg, drop */ +- iRet = RS_RET_OK; +- goto free_message; + } + + /* Get message identifier, client pid and add ':' */ +@@ -349,7 +394,7 @@ readjournal() { + } + + /* submit message */ +- enqMsg((uchar *)message, (uchar *) sys_iden_help, facility, priority, &tv, json); ++ enqMsg((uchar *)message, (uchar *) sys_iden_help, facility, severity, &tv, json); + + finalize_it: + free(sys_iden_help); +@@ -569,6 +614,8 @@ CODESTARTbeginCnfLoad + cs.stateFile = NULL; + cs.ratelimitBurst = 20000; + cs.ratelimitInterval = 600; ++ cs.iDfltSeverity = DFLT_SEVERITY; ++ cs.iDfltFacility = DFLT_FACILITY; + ENDbeginCnfLoad + + +@@ -657,6 +704,17 @@ CODESTARTsetModCnf + cs.ratelimitInterval = (int) pvals[i].val.d.n; + } else if (!strcmp(modpblk.descr[i].name, "ignorepreviousmessages")) { + cs.bIgnorePrevious = (int) pvals[i].val.d.n; ++ } else if (!strcmp(modpblk.descr[i].name, "defaultseverity")) { ++ cs.iDfltSeverity = (int) pvals[i].val.d.n; ++ } else if (!strcmp(modpblk.descr[i].name, "defaultfacility")) { ++ /* ugly workaround to handle facility numbers; values ++ derived from names need to be eight times smaller */ ++ ++ char *fac, *p; ++ ++ fac = p = es_str2cstr(pvals[i].val.d.estr, NULL); ++ facilityHdlr((uchar **) &p, (void *) &cs.iDfltFacility); ++ free(fac); + } else { + dbgprintf("imjournal: program error, non-handled " + "param '%s' in beginCnfLoad\n", modpblk.descr[i].name); +@@ -710,6 +768,10 @@ CODEmodInit_QueryRegCFSLineHdlr + NULL, &cs.stateFile, STD_LOADABLE_MODULE_ID)); + CHKiRet(omsdRegCFSLineHdlr((uchar *)"imjournalignorepreviousmessages", 0, eCmdHdlrBinary, + NULL, &cs.bIgnorePrevious, STD_LOADABLE_MODULE_ID)); ++ CHKiRet(omsdRegCFSLineHdlr((uchar *)"imjournaldefaultseverity", 0, eCmdHdlrSeverity, ++ NULL, &cs.iDfltSeverity, STD_LOADABLE_MODULE_ID)); ++ CHKiRet(omsdRegCFSLineHdlr((uchar *)"imjournaldefaultfacility", 0, eCmdHdlrCustomHandler, ++ facilityHdlr, &cs.iDfltFacility, STD_LOADABLE_MODULE_ID)); + + + ENDmodInit +-- +1.8.4.3 + diff --git a/rsyslog.spec b/rsyslog.spec index 43aaec7..a1a60c6 100644 --- a/rsyslog.spec +++ b/rsyslog.spec @@ -32,6 +32,7 @@ Patch5: rsyslog-7.4.7-numeric-uid.patch Patch6: rsyslog-7.4.7-atomicops.patch # merged upstream Patch7: rsyslog-7.4.8-dont-link-libee.patch +Patch8: rsyslog-7.4.8-bz1026804-imjournal-message-loss.patch BuildRequires: bison BuildRequires: flex @@ -255,6 +256,7 @@ of source ports. %patch5 -p1 %patch6 -p1 %patch7 -p1 +%patch8 -p1 %build %ifarch sparc64 @@ -495,6 +497,8 @@ done - replace rsyslog-7.3.15-imuxsock-warning.patch with rsyslog-7.4.8-imuxsock-wrn.patch - link to libhiredis explicitly +- add a patch to prevent message loss in imjournal + rsyslog-7.4.8-bz1026804-imjournal-message-loss.patch * Sun Feb 09 2014 Lubomir Rintel 7.4.7-3 - Fixed 32-bit PowerPC build