diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | action.c | 65 | ||||
-rw-r--r-- | action.h | 4 | ||||
-rw-r--r-- | doc/impstats.html | 4 | ||||
-rw-r--r-- | plugins/impstats/impstats.c | 2 | ||||
-rw-r--r-- | plugins/imudp/imudp.c | 17 | ||||
-rw-r--r-- | runtime/msg.c | 4 | ||||
-rw-r--r-- | runtime/queue.c | 9 | ||||
-rw-r--r-- | runtime/queue.h | 2 |
9 files changed, 100 insertions, 14 deletions
@@ -1,5 +1,6 @@ --------------------------------------------------------------------------- Version 6.3.7 [DEVEL] 2011-0?-?? +- added a couple of new stats objects - improved support for new v6 config system. Now also supported by - omfwd - bugfix: facility local<x> was not correctly interpreted in legacy filters @@ -322,7 +323,11 @@ expected that interfaces, even new ones, break during the initial syslog plain tcp input plugin (NOT supporting TLS!) [ported from v4] --------------------------------------------------------------------------- -Version 5.9.5 [V5-DEVEL], 20??-??-?? +Version 5.9.6 [V5-DEVEL], 20??-??-?? +- new stats counters "discarded.nf" and "discarded.full" for queue object. + Tells how many messages have been discarded due to queue full condition. +--------------------------------------------------------------------------- +Version 5.9.5 [V5-DEVEL], 2011-11-29 - enhanced module loader to not rely on PATH_MAX --------------------------------------------------------------------------- Version 5.9.4 [V5-DEVEL], 2011-11-29 @@ -114,6 +114,7 @@ #include "unicode-helper.h" #include "atomic.h" #include "ruleset.h" +#include "statsobj.h" #define NO_TIME_PROVIDED 0 /* indicate we do not provide any cached time */ @@ -129,6 +130,7 @@ DEFobjCurrIf(obj) DEFobjCurrIf(datetime) DEFobjCurrIf(module) DEFobjCurrIf(errmsg) +DEFobjCurrIf(statsobj) DEFobjCurrIf(ruleset) @@ -291,6 +293,12 @@ rsRetVal actionDestruct(action_t *pThis) qqueueDestruct(&pThis->pQueue); } + /* destroy stats object, if we have one (may not always be + * be the case, e.g. if turned off) + */ + if(pThis->statsobj != NULL) + statsobj.Destruct(&pThis->statsobj); + if(pThis->pMod != NULL) pThis->pMod->freeInstance(pThis->pModData); @@ -354,18 +362,42 @@ rsRetVal actionConstructFinalize(action_t *pThis, struct cnfparamvals *queueParams) { DEFiRet; - uchar pszQName[64]; /* friendly name of our queue */ + uchar pszAName[64]; /* friendly name of our action */ ASSERT(pThis != NULL); - /* find a name for our queue */ + /* generate a friendly name for us action stats */ if(pThis->pszName == NULL) { - snprintf((char*) pszQName, sizeof(pszQName)/sizeof(uchar), "action %d queue", iActionNbr); + snprintf((char*) pszAName, sizeof(pszAName)/sizeof(uchar), "action %d", iActionNbr); } else { - ustrncpy(pszQName, pThis->pszName, sizeof(pszQName)); - pszQName[sizeof(pszQName)-1] = '\0'; /* to be on the save side */ + ustrncpy(pszAName, pThis->pszName, sizeof(pszAName)); + pszAName[sizeof(pszAName)-1] = '\0'; /* to be on the save side */ } + /* support statistics gathering */ + CHKiRet(statsobj.Construct(&pThis->statsobj)); + CHKiRet(statsobj.SetName(pThis->statsobj, pszAName)); + + STATSCOUNTER_INIT(pThis->ctrProcessed, pThis->mutCtrProcessed); + CHKiRet(statsobj.AddCounter(pThis->statsobj, UCHAR_CONSTANT("processed"), + ctrType_IntCtr, &pThis->ctrProcessed)); + + STATSCOUNTER_INIT(pThis->ctrFail, pThis->mutCtrFail); + CHKiRet(statsobj.AddCounter(pThis->statsobj, UCHAR_CONSTANT("failed"), + ctrType_IntCtr, &pThis->ctrFail)); + + CHKiRet(statsobj.ConstructFinalize(pThis->statsobj)); + + /* create our queue */ + + /* generate a friendly name for the queue */ + if(pThis->pszName == NULL) { + snprintf((char*) pszAName, sizeof(pszAName)/sizeof(uchar), "action %d queue", + iActionNbr); + } else { + ustrncpy(pszAName, pThis->pszName, sizeof(pszAName)); + pszAName[63] = '\0'; /* to be on the save side */ + } /* now check if we can run the action in "firehose mode" during stage one of * its processing (that is before messages are enqueued into the action q). * This is only possible if some features, which require strict sequence, are @@ -408,7 +440,7 @@ actionConstructFinalize(action_t *pThis, struct cnfparamvals *queueParams) */ CHKiRet(qqueueConstruct(&pThis->pQueue, cs.ActionQueType, 1, cs.iActionQueueSize, (rsRetVal (*)(void*, batch_t*, int*))processBatchMain)); - obj.SetName((obj_t*) pThis->pQueue, pszQName); + obj.SetName((obj_t*) pThis->pQueue, pszAName); qqueueSetpUsr(pThis->pQueue, pThis); if(queueParams == NULL) { /* use legacy params? */ @@ -1124,6 +1156,7 @@ submitBatch(action_t *pAction, batch_t *pBatch, int nElem) && pBatch->pElem[i].state != BATCH_STATE_COMM ) { pBatch->pElem[i].state = BATCH_STATE_BAD; pBatch->pElem[i].bPrevWasSuspended = 1; + STATSCOUNTER_INC(pAction->ctrFail, pAction->mutCtrFail); } } bDone = 1; @@ -1313,6 +1346,7 @@ doSubmitToActionQ(action_t *pAction, msg_t *pMsg) { DEFiRet; + STATSCOUNTER_INC(pAction->ctrProcessed, pAction->mutCtrProcessed); if(pAction->pQueue->qType == QUEUETYPE_DIRECT) iRet = qqueueEnqObjDirect(pAction->pQueue, (void*) MsgAddRef(pMsg)); else @@ -1616,6 +1650,17 @@ finalize_it: RETiRet; } +static inline void +countStatsBatchEnq(action_t *pAction, batch_t *pBatch) +{ + int i; + for(i = 0 ; i < batchNumMsgs(pBatch) && !*(pBatch->pbShutdownImmediate) ; ++i) { + if(pBatch->pElem[i].bFilterOK) { + STATSCOUNTER_INC(pAction->ctrProcessed, pAction->mutCtrProcessed); + } + } +} + /* enqueue a batch in direct mode. We have put this into its own function just to avoid * cluttering the actual submit function. @@ -1652,13 +1697,16 @@ doQueueEnqObjDirectBatch(action_t *pAction, batch_t *pBatch) pBatch->pElem[i].bFilterOK = 0; bModifiedFilter = 1; } - if(pBatch->pElem[i].bFilterOK) + if(pBatch->pElem[i].bFilterOK) { + STATSCOUNTER_INC(pAction->ctrProcessed, pAction->mutCtrProcessed); bNeedSubmit = 1; + } DBGPRINTF("action %p[%d]: filterOK:%d state:%d execWhenPrev:%d prevWasSusp:%d\n", pAction, i, pBatch->pElem[i].bFilterOK, pBatch->pElem[i].state, pAction->bExecWhenPrevSusp, pBatch->pElem[i].bPrevWasSuspended); } if(bNeedSubmit) { + /* note: stats were already computed above */ iRet = qqueueEnqObjDirectBatch(pAction->pQueue, pBatch); } else { DBGPRINTF("no need to submit batch, all bFilterOK==0\n"); @@ -1673,6 +1721,8 @@ doQueueEnqObjDirectBatch(action_t *pAction, batch_t *pBatch) } } } else { + if(GatherStats) + countStatsBatchEnq(pAction, pBatch); iRet = qqueueEnqObjDirectBatch(pAction->pQueue, pBatch); } @@ -2083,6 +2133,7 @@ rsRetVal actionClassInit(void) CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(module, CORE_COMPONENT)); CHKiRet(objUse(errmsg, CORE_COMPONENT)); + CHKiRet(objUse(statsobj, CORE_COMPONENT)); CHKiRet(objUse(ruleset, CORE_COMPONENT)); CHKiRet(regCfSysLineHdlr((uchar *)"actionname", 0, eCmdHdlrGetWord, NULL, &cs.pszActionName, NULL, eConfObjAction)); @@ -89,6 +89,10 @@ struct action_s { pthread_mutex_t mutActExec; /* mutex to guard actual execution of doAction for single-threaded modules */ uchar *pszName; /* action name (for documentation) */ DEF_ATOMIC_HELPER_MUT(mutCAS); + /* for statistics subsystem */ + statsobj_t *statsobj; + STATSCOUNTER_DEF(ctrProcessed, mutCtrProcessed); + STATSCOUNTER_DEF(ctrFail, mutCtrFail); }; diff --git a/doc/impstats.html b/doc/impstats.html index cede4874..260c1aa4 100644 --- a/doc/impstats.html +++ b/doc/impstats.html @@ -18,7 +18,9 @@ prepared to change your trending scripts when you upgrade to a newer rsyslog ver output is periodic, with the interval being configurable (default is 5 minutes). Be sure that your configuration records the counter messages (default is syslog.info). <p>Note that loading this module has impact on rsyslog performance. Depending on -settings, this impact may be severe (for high-load environments). +settings, this impact may be noticable (for high-load environments). +<p>The rsyslog website has an updated overview of available +<a href="http://rsyslog.com/rsyslog-statistic-counter/">rsyslog statistic counters</a>. </p> <p><b>Configuration Directives</b>:</p> <ul> diff --git a/plugins/impstats/impstats.c b/plugins/impstats/impstats.c index c3efb330..fab4c221 100644 --- a/plugins/impstats/impstats.c +++ b/plugins/impstats/impstats.c @@ -10,7 +10,7 @@ * of the "old" message code without any modifications. However, it * helps to have things at the right place one we go to the meat of it. * - * Copyright 2010 Rainer Gerhards and Adiscon GmbH. + * Copyright 2010-2011 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c index 31f5cce9..badad949 100644 --- a/plugins/imudp/imudp.c +++ b/plugins/imudp/imudp.c @@ -51,6 +51,7 @@ #include "datetime.h" #include "prop.h" #include "ruleset.h" +#include "statsobj.h" #include "unicode-helper.h" MODULE_TYPE_INPUT @@ -67,6 +68,10 @@ DEFobjCurrIf(net) DEFobjCurrIf(datetime) DEFobjCurrIf(prop) DEFobjCurrIf(ruleset) +DEFobjCurrIf(statsobj) + +statsobj_t *modStats; +STATSCOUNTER_DEF(ctrSubmit, mutCtrSubmit) static int bDoACLCheck; /* are ACL checks neeed? Cached once immediately before listener startup */ static int iMaxLine; /* maximum UDP message size supported */ @@ -333,6 +338,7 @@ processSocket(thrdInfo_t *pThrd, int fd, struct sockaddr_storage *frominetPrev, pMsg->msgFlags |= NEEDS_ACLCHK_U; /* request ACL check after resolution */ CHKiRet(msgSetFromSockinfo(pMsg, &frominet)); CHKiRet(submitMsg(pMsg)); + STATSCOUNTER_INC(ctrSubmit, mutCtrSubmit); } } @@ -735,9 +741,12 @@ CODESTARTmodExit if(pInputName != NULL) prop.Destruct(&pInputName); + statsobj.Destruct(&modStats); + /* release what we no longer need */ objRelease(errmsg, CORE_COMPONENT); objRelease(glbl, CORE_COMPONENT); + objRelease(statsobj, CORE_COMPONENT); objRelease(datetime, CORE_COMPONENT); objRelease(prop, CORE_COMPONENT); objRelease(ruleset, CORE_COMPONENT); @@ -786,6 +795,7 @@ CODESTARTmodInit CODEmodInit_QueryRegCFSLineHdlr CHKiRet(objUse(errmsg, CORE_COMPONENT)); CHKiRet(objUse(glbl, CORE_COMPONENT)); + CHKiRet(objUse(statsobj, CORE_COMPONENT)); CHKiRet(objUse(datetime, CORE_COMPONENT)); CHKiRet(objUse(prop, CORE_COMPONENT)); CHKiRet(objUse(ruleset, CORE_COMPONENT)); @@ -811,6 +821,13 @@ CODEmodInit_QueryRegCFSLineHdlr NULL, &cs.iTimeRequery, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables, NULL, STD_LOADABLE_MODULE_ID, eConfObjGlobal)); + + /* support statistics gathering */ + CHKiRet(statsobj.Construct(&modStats)); + CHKiRet(statsobj.SetName(modStats, UCHAR_CONSTANT("imudp"))); + CHKiRet(statsobj.AddCounter(modStats, UCHAR_CONSTANT("submitted"), + ctrType_IntCtr, &ctrSubmit)); + CHKiRet(statsobj.ConstructFinalize(modStats)); ENDmodInit /* vim:set ai: */ diff --git a/runtime/msg.c b/runtime/msg.c index f4ea0cc2..7e469885 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -1663,8 +1663,6 @@ void MsgSetTAG(msg_t *pMsg, uchar* pszBuf, size_t lenBuf) uchar *pBuf; assert(pMsg != NULL); -dbgprintf("MsgSetTAG in: len %d, pszBuf: %s\n", lenBuf, pszBuf); - freeTAG(pMsg); pMsg->iLenTAG = lenBuf; @@ -1683,8 +1681,6 @@ dbgprintf("MsgSetTAG in: len %d, pszBuf: %s\n", lenBuf, pszBuf); memcpy(pBuf, pszBuf, pMsg->iLenTAG); pBuf[pMsg->iLenTAG] = '\0'; /* this also works with truncation! */ - -dbgprintf("MsgSetTAG exit: pMsg->iLenTAG %d, pMsg->TAG.szBuf: %s\n", pMsg->iLenTAG, pMsg->TAG.szBuf); } diff --git a/runtime/queue.c b/runtime/queue.c index 3876ec39..a1ac3eff 100644 --- a/runtime/queue.c +++ b/runtime/queue.c @@ -1386,6 +1386,7 @@ static int qqueueChkDiscardMsg(qqueue_t *pThis, int iQueueSize, void *pUsr) if(iRetLocal == RS_RET_OK && iSeverity >= pThis->iDiscardSeverity) { DBGOPRINT((obj_t*) pThis, "queue nearly full (%d entries), discarded severity %d message\n", iQueueSize, iSeverity); + STATSCOUNTER_INC(pThis->ctrNFDscrd, pThis->mutCtrNFDscrd); objDestruct(pUsr); ABORT_FINALIZE(RS_RET_QUEUE_FULL); } else { @@ -2066,6 +2067,13 @@ qqueueStart(qqueue_t *pThis) /* this is the ConstructionFinalizer */ CHKiRet(statsobj.AddCounter(pThis->statsobj, UCHAR_CONSTANT("full"), ctrType_IntCtr, &pThis->ctrFull)); + STATSCOUNTER_INIT(pThis->ctrFDscrd, pThis->mutCtrFDscrd); + CHKiRet(statsobj.AddCounter(pThis->statsobj, UCHAR_CONSTANT("discarded.full"), + ctrType_IntCtr, &pThis->ctrFDscrd)); + STATSCOUNTER_INIT(pThis->ctrNFDscrd, pThis->mutCtrNFDscrd); + CHKiRet(statsobj.AddCounter(pThis->statsobj, UCHAR_CONSTANT("discarded.nf"), + ctrType_IntCtr, &pThis->ctrNFDscrd)); + pThis->ctrMaxqsize = 0; CHKiRet(statsobj.AddCounter(pThis->statsobj, UCHAR_CONSTANT("maxqsize"), ctrType_Int, &pThis->ctrMaxqsize)); @@ -2419,6 +2427,7 @@ doEnqSingleObj(qqueue_t *pThis, flowControl_t flowCtlType, void *pUsr) // TODO : handle enqOnly => discard! if(pthread_cond_timedwait(&pThis->notFull, pThis->mut, &t) != 0) { DBGOPRINT((obj_t*) pThis, "enqueueMsg: cond timeout, dropping message!\n"); + STATSCOUNTER_INC(pThis->ctrFDscrd, pThis->mutCtrFDscrd); objDestruct(pUsr); ABORT_FINALIZE(RS_RET_QUEUE_FULL); } diff --git a/runtime/queue.h b/runtime/queue.h index 2b1fcfa8..2432c13f 100644 --- a/runtime/queue.h +++ b/runtime/queue.h @@ -169,6 +169,8 @@ struct queue_s { statsobj_t *statsobj; STATSCOUNTER_DEF(ctrEnqueued, mutCtrEnqueued); STATSCOUNTER_DEF(ctrFull, mutCtrFull); + STATSCOUNTER_DEF(ctrFDscrd, mutCtrFDscrd); + STATSCOUNTER_DEF(ctrNFDscrd, mutCtrNFDscrd); int ctrMaxqsize; }; |