Blame SOURCES/rsyslog-7.4.7-bz1038136-imjournal-message-loss.patch

92fbf8
From effa35d1ae33c1ac825317802b6e970e68f98af2 Mon Sep 17 00:00:00 2001
92fbf8
From: Tomas Heinrich <theinric@redhat.com>
92fbf8
Date: Fri, 31 Jan 2014 11:35:55 +0100
92fbf8
Subject: [PATCH] Improve handling of messages without syslog properties
92fbf8
92fbf8
* Don't drop messages without the MESSAGE field
92fbf8
* Set default severity for all messages
92fbf8
  Some messages comming from journald don't have the SYSLOG_PRIORITY
92fbf8
  field. These are typically the messages logged through journald's
92fbf8
  native API. Set the default severity for these messages to 'notice'.
92fbf8
* Set default facility for all messages
92fbf8
  Some messages comming from journald don't have the SYSLOG_FACILITY
92fbf8
  field. These are typically the messages logged through journald's
92fbf8
  native API. Set the default facility for these messages to 'user'.
92fbf8
* Make default priority configurable
92fbf8
---
92fbf8
 doc/imjournal.html            |  16 ++++++
92fbf8
 plugins/imjournal/imjournal.c | 124 +++++++++++++++++++++++++++++++-----------
92fbf8
 2 files changed, 109 insertions(+), 31 deletions(-)
92fbf8
92fbf8
diff --git a/doc/imjournal.html b/doc/imjournal.html
92fbf8
index 8f29169..b4d2105 100644
92fbf8
--- a/doc/imjournal.html
92fbf8
+++ b/doc/imjournal.html
92fbf8
@@ -69,6 +69,18 @@ journal and read only new messages. This option is only used when there is
92fbf8
 no StateFile to avoid message loss.
92fbf8
 
92fbf8
 
92fbf8
+
  • DefaultSeverity <severity>
  • 92fbf8
    +Some messages comming from journald don't have the SYSLOG_PRIORITY
    92fbf8
    +field. These are typically the messages logged through journald's
    92fbf8
    +native API. This option specifies the default severity for these
    92fbf8
    +messages. Defaults to 'notice'.
    92fbf8
    +
    92fbf8
    +
  • DefaultFacility <facility>
  • 92fbf8
    +Some messages comming from journald don't have the SYSLOG_FACILITY
    92fbf8
    +field. These are typically the messages logged through journald's
    92fbf8
    +native API. This option specifies the default facility for these
    92fbf8
    +messages. Defaults to 'user'.
    92fbf8
    +
    92fbf8
     Caveats/Known Bugs:
    92fbf8
     

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