diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | action.c | 41 | ||||
-rw-r--r-- | action.h | 4 | ||||
-rw-r--r-- | doc/features.html | 1 | ||||
-rw-r--r-- | doc/rsyslog_conf.html | 13 | ||||
-rw-r--r-- | doc/rsyslog_ng_comparison.html | 12 |
6 files changed, 71 insertions, 9 deletions
@@ -1,5 +1,12 @@ --------------------------------------------------------------------------- -Version 3.21.3 [DEVEL] (rgerhards), 2008-08-05 +Version 3.21.3 [DEVEL] (rgerhards), 2008-08-?? +- added ability to execute actions only after the n-th call of the action + This also lead to the addition of two new config directives: + $ActionExecOnlyEveryNthTime and $ActionExecOnlyEveryNthTimeTimeout + This feature is useful, for example, for alerting: it permits you to + send an alert only after at least n occurences of a specific message + have been seen by rsyslogd. This protectes against false positives + due to waiting for additional confirmation. - bugfix: IPv6 addresses could not be specified in forwarding actions New syntax @[addr]:port introduced to enable that. Root problem was IPv6 addresses contain colons. @@ -54,6 +54,8 @@ DEFobjCurrIf(datetime) DEFobjCurrIf(module) DEFobjCurrIf(errmsg) +static int iActExecEveryNthOccur = 0; /* execute action every n-th occurence (0,1=always) */ +static time_t iActExecEveryNthOccurTO = 0; /* timeout for n-occurence setting (in seconds, 0=never) */ static int glbliActionResumeInterval = 30; int glbliActionResumeRetryCount = 0; /* how often should suspended actions be retried? */ @@ -174,6 +176,7 @@ rsRetVal actionConstruct(action_t **ppThis) pThis->iResumeInterval = glbliActionResumeInterval; pThis->iResumeRetryCount = glbliActionResumeRetryCount; + pThis->tLastOccur = time(NULL); pthread_mutex_init(&pThis->mutActExec, NULL); SYNC_OBJ_TOOL_INIT(pThis); @@ -510,7 +513,36 @@ actionWriteToAction(action_t *pAction) DEFiRet; pMsgSave = NULL; /* indicate message poiner not saved */ - /* first check if this is a regular message or the repeation of + time(&now); /* we need this for several use cases, but obtain it once for performance reasons */ + + /* first, we check if the action should actually be called. The action-specific + * $ActionExecOnlyEveryNthTime permits us to execute an action only every Nth + * time. So we need to check if we need to drop the (otherwise perfectly executable) + * action for this reason. Note that in case we need to drop it, we return RS_RET_OK + * as the action was properly "passed to execution" from the upper layer's point + * of view. -- rgerhards, 2008-08-07. + */ +dbgprintf("NTH: conf: %d, actual %d\n", pAction->iExecEveryNthOccur, pAction->iNbrNoExec); + if(pAction->iExecEveryNthOccur > 1) { + /* we need to care about multiple occurences */ + if( pAction->iExecEveryNthOccurTO > 0 + && (now - pAction->tLastOccur) > pAction->iExecEveryNthOccurTO) { + dbgprintf("n-th occurence handling timed out (%d sec), restarting from 0\n", + (int) (now - pAction->tLastOccur)); + pAction->iNbrNoExec = 0; + pAction->tLastOccur = now; + } + if(pAction->iNbrNoExec < pAction->iExecEveryNthOccur - 1) { + ++pAction->iNbrNoExec; + dbgprintf("action %p passed %d times to execution - less than neded - discarding\n", + pAction, pAction->iNbrNoExec); + FINALIZE; + } else { + pAction->iNbrNoExec = 0; /* we execute the action now, so the number of no execs is down to */ + } + } + + /* then check if this is a regular message or the repeation of * a previous message. If so, we need to change the message text * to "last message repeated n times" and then go ahead and write * it. Please note that we can not modify the message object, because @@ -545,7 +577,6 @@ actionWriteToAction(action_t *pAction) dbgprintf("Called action, logging to %s\n", module.GetStateName(pAction->pMod)); - time(&now); /* we need this for message repeation processing AND $ActionExecOnlyOnceEveryInterval */ /* now check if we need to drop the message because otherwise the action would be too * frequently called. -- rgerhards, 2008-04-08 */ @@ -706,6 +737,8 @@ actionAddCfSysLineHdrl(void) CHKiRet(regCfSysLineHdlr((uchar *)"actionqueuedequeueslowdown", 0, eCmdHdlrInt, NULL, &iActionQueueDeqSlowdown, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionqueuedequeuetimebegin", 0, eCmdHdlrInt, NULL, &iActionQueueDeqtWinFromHr, NULL)); CHKiRet(regCfSysLineHdlr((uchar *)"actionqueuedequeuetimeend", 0, eCmdHdlrInt, NULL, &iActionQueueDeqtWinToHr, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlyeverynthtime", 0, eCmdHdlrInt, NULL, &iActExecEveryNthOccur, NULL)); + CHKiRet(regCfSysLineHdlr((uchar *)"actionexeconlyeverynthtimetimeout", 0, eCmdHdlrInt, NULL, &iActExecEveryNthOccurTO, NULL)); finalize_it: RETiRet; @@ -737,6 +770,10 @@ addAction(action_t **ppAction, modInfo_t *pMod, void *pModData, omodStringReques pAction->pModData = pModData; pAction->bExecWhenPrevSusp = bActExecWhenPrevSusp; pAction->iSecsExecOnceInterval = iActExecOnceInterval; + pAction->iExecEveryNthOccur = iActExecEveryNthOccur; + pAction->iExecEveryNthOccurTO = iActExecEveryNthOccurTO; + iActExecEveryNthOccur = 0; /* auto-reset */ + iActExecEveryNthOccurTO = 0; /* auto-reset */ /* check if we can obtain the template pointers - TODO: move to separate function? */ pAction->iNumTpls = OMSRgetEntryCount(pOMSR); @@ -49,6 +49,10 @@ struct action_s { int iResumeInterval;/* resume interval for this action */ int iResumeRetryCount;/* how often shall we retry a suspended action? (-1 --> eternal) */ int iNbrResRtry; /* number of retries since last suspend */ + int iNbrNoExec; /* number of matches that did not yet yield to an exec */ + int iExecEveryNthOccur;/* execute this action only every n-th occurence (with n=0,1 -> always) */ + int iExecEveryNthOccurTO;/* timeout for n-th occurence feature */ + time_t tLastOccur; /* time last occurence was seen (for timing them out) */ struct modInfo_s *pMod;/* pointer to output module handling this selector */ void *pModData; /* pointer to module data - content is module-specific */ int f_ReduceRepeated;/* reduce repeated lines 0 - no, 1 - yes */ diff --git a/doc/features.html b/doc/features.html index 2b3b31d9..8e28daae 100644 --- a/doc/features.html +++ b/doc/features.html @@ -94,6 +94,7 @@ loadable plug-in</li> via custom plugins</li> <li> an easy-to-write to plugin interface</li> <li> ability to send SNMP trap messages</li> +<li> ability to filter out messages based on sequence of arrival</li> <li>support for arbitrary complex boolean, string and arithmetic expressions in message filters</li> </ul> diff --git a/doc/rsyslog_conf.html b/doc/rsyslog_conf.html index d2dfaaaf..ac97ecb1 100644 --- a/doc/rsyslog_conf.html +++ b/doc/rsyslog_conf.html @@ -79,8 +79,17 @@ default, it is usually well-chosen and applicable in most cases.</p> execute action only if the last execute is at last <seconds> seconds in the past (more info in <a href="ommail.html">ommail</a>, but may be used with any action)</li> -<li>$ActionFileDefaultTemplate [templateName] - sets a new -default template for file actions</li> +<li>$ActionExecOnlyEveryNthTime <number> - If configured, the next action will +only be executed every n-th time. For example, if configured to 3, the first two messages +that go into the action will be dropped, the 3rd will actually cause the action to execute, +the 4th and 5th will be dropped, the 6th executed under the action, ... and so on. Note: +this setting is automatically re-set when the actual action is defined.</li> +<li>$ActionExecOnlyEveryNthTimeTimeout <number-of-seconds> - has a meaning only if +$ActionExecOnlyEveryNthTime is also configured for the same action. If so, the timeout +setting specifies after which period the counting of "previous actions" expires and +a new action count is begun. Specify 0 (the default) to disable timeouts.:w + +<li>$ActionFileDefaultTemplate [templateName] - sets a new default template for file actions</li> <li>$ActionFileEnableSync [on/<span style="font-weight: bold;">off</span>] - enables file syncing capability of omfile</li> <li>$ActionForwardDefaultTemplate [templateName] - sets a new diff --git a/doc/rsyslog_ng_comparison.html b/doc/rsyslog_ng_comparison.html index 600875a8..74d83f72 100644 --- a/doc/rsyslog_ng_comparison.html +++ b/doc/rsyslog_ng_comparison.html @@ -209,10 +209,8 @@ priority</td> <td></td> </tr> <tr> -<td valign="top">ability to filter on any other -message -field not mentioned above -(including substrings and the like)</td> +<td valign="top">ability to filter on any other message +field not mentioned above (including substrings and the like)</td> <td valign="top">yes</td> <td valign="top">no</td> </tr> @@ -248,6 +246,12 @@ based on filters</td> <td></td> </tr> <tr> +<td valign="top">ability to filter out messages based on sequence of appearing</td> +<td valign="top">yes</td> +<td valign="top">no</td> +<td></td> +</tr> +<tr> <td valign="top">powerful BSD-style hostname and program name blocks for easy multi-host support</td> <td valign="top">yes</td> |