summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--action.c41
-rw-r--r--action.h4
-rw-r--r--doc/features.html1
-rw-r--r--doc/rsyslog_conf.html13
-rw-r--r--doc/rsyslog_ng_comparison.html12
6 files changed, 71 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index d51368c2..ce359720 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/action.c b/action.c
index f7219405..3a2584de 100644
--- a/action.c
+++ b/action.c
@@ -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);
diff --git a/action.h b/action.h
index 99108aab..c910fc1c 100644
--- a/action.h
+++ b/action.h
@@ -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
&lt;seconds&gt; 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 &lt;number&gt; - 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 &lt;number-of-seconds&gt; - 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>