mirror of
https://github.com/rsyslog/rsyslog.git
synced 2025-12-20 05:00:42 +01:00
If the parameter "log.file" is specified, impstats writes its own log file. However, HUP is not handled for this file, which makes the functionality unusable with log rotation. It is also counter- intuitive for users. This patch enables correct HUP processing. As a sideline, it also introduces a generic HUP processing framework for non-action type of loadable modules. closes https://github.com/rsyslog/rsyslog/issues/1662 closes https://github.com/rsyslog/rsyslog/issues/1663
632 lines
18 KiB
C
632 lines
18 KiB
C
/* impstats.c
|
|
* A module to periodically output statistics gathered by rsyslog.
|
|
*
|
|
* Copyright 2010-2017 Adiscon GmbH.
|
|
*
|
|
* This file is part of rsyslog.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
* -or-
|
|
* see COPYING.ASL20 in the source distribution
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#include "config.h"
|
|
#include "rsyslog.h"
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <signal.h>
|
|
#include <string.h>
|
|
#include <pthread.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <sys/uio.h>
|
|
#if defined(__FreeBSD__)
|
|
#include <sys/stat.h>
|
|
#endif
|
|
#include <errno.h>
|
|
#include <sys/time.h>
|
|
#include <sys/resource.h>
|
|
#ifdef OS_LINUX
|
|
#include <sys/types.h>
|
|
#include <dirent.h>
|
|
#endif
|
|
|
|
#include "dirty.h"
|
|
#include "cfsysline.h"
|
|
#include "module-template.h"
|
|
#include "errmsg.h"
|
|
#include "msg.h"
|
|
#include "srUtils.h"
|
|
#include "unicode-helper.h"
|
|
#include "glbl.h"
|
|
#include "statsobj.h"
|
|
#include "prop.h"
|
|
#include "ruleset.h"
|
|
|
|
|
|
MODULE_TYPE_INPUT
|
|
MODULE_TYPE_NOKEEP
|
|
MODULE_CNFNAME("impstats")
|
|
|
|
/* defines */
|
|
#define DEFAULT_STATS_PERIOD (5 * 60)
|
|
#define DEFAULT_FACILITY 5 /* syslog */
|
|
#define DEFAULT_SEVERITY 6 /* info */
|
|
|
|
/* Module static data */
|
|
DEF_IMOD_STATIC_DATA
|
|
DEFobjCurrIf(glbl)
|
|
DEFobjCurrIf(prop)
|
|
DEFobjCurrIf(statsobj)
|
|
DEFobjCurrIf(errmsg)
|
|
DEFobjCurrIf(ruleset)
|
|
|
|
typedef struct configSettings_s {
|
|
int iStatsInterval;
|
|
int iFacility;
|
|
int iSeverity;
|
|
int bJSON;
|
|
int bCEE;
|
|
} configSettings_t;
|
|
|
|
struct modConfData_s {
|
|
rsconf_t *pConf; /* our overall config object */
|
|
int iStatsInterval;
|
|
int iFacility;
|
|
int iSeverity;
|
|
int logfd; /* fd if logging to file, or -1 if closed */
|
|
ruleset_t *pBindRuleset; /* ruleset to bind listener to (use system default if unspecified) */
|
|
statsFmtType_t statsFmt;
|
|
sbool bLogToSyslog;
|
|
sbool bResetCtrs;
|
|
sbool bBracketing;
|
|
char *logfile;
|
|
sbool configSetViaV2Method;
|
|
uchar *pszBindRuleset; /* name of ruleset to bind to */
|
|
};
|
|
static modConfData_t *loadModConf = NULL;/* modConf ptr to use for the current load process */
|
|
static modConfData_t *runModConf = NULL;/* modConf ptr to use for the current load process */
|
|
|
|
static configSettings_t cs;
|
|
static int bLegacyCnfModGlobalsPermitted;/* are legacy module-global config parameters permitted? */
|
|
static prop_t *pInputName = NULL;
|
|
|
|
/* module-global parameters */
|
|
static struct cnfparamdescr modpdescr[] = {
|
|
{ "interval", eCmdHdlrInt, 0 },
|
|
{ "facility", eCmdHdlrInt, 0 },
|
|
{ "severity", eCmdHdlrInt, 0 },
|
|
{ "bracketing", eCmdHdlrBinary, 0 },
|
|
{ "log.syslog", eCmdHdlrBinary, 0 },
|
|
{ "resetcounters", eCmdHdlrBinary, 0 },
|
|
{ "log.file", eCmdHdlrGetWord, 0 },
|
|
{ "format", eCmdHdlrGetWord, 0 },
|
|
{ "ruleset", eCmdHdlrString, 0 }
|
|
};
|
|
static struct cnfparamblk modpblk =
|
|
{ CNFPARAMBLK_VERSION,
|
|
sizeof(modpdescr)/sizeof(struct cnfparamdescr),
|
|
modpdescr
|
|
};
|
|
|
|
|
|
/* resource use stats counters */
|
|
#ifdef OS_LINUX
|
|
static int st_openfiles;
|
|
#endif
|
|
static intctr_t st_ru_utime;
|
|
static intctr_t st_ru_stime;
|
|
static int st_ru_maxrss;
|
|
static int st_ru_minflt;
|
|
static int st_ru_majflt;
|
|
static int st_ru_inblock;
|
|
static int st_ru_oublock;
|
|
static int st_ru_nvcsw;
|
|
static int st_ru_nivcsw;
|
|
static statsobj_t *statsobj_resources;
|
|
|
|
static pthread_mutex_t hup_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|
|
|
BEGINmodExit
|
|
CODESTARTmodExit
|
|
prop.Destruct(&pInputName);
|
|
/* release objects we used */
|
|
objRelease(glbl, CORE_COMPONENT);
|
|
objRelease(prop, CORE_COMPONENT);
|
|
objRelease(errmsg, CORE_COMPONENT);
|
|
objRelease(statsobj, CORE_COMPONENT);
|
|
objRelease(ruleset, CORE_COMPONENT);
|
|
ENDmodExit
|
|
|
|
|
|
BEGINisCompatibleWithFeature
|
|
CODESTARTisCompatibleWithFeature
|
|
if(eFeat == sFEATURENonCancelInputTermination)
|
|
iRet = RS_RET_OK;
|
|
ENDisCompatibleWithFeature
|
|
|
|
|
|
#ifdef OS_LINUX
|
|
/* count number of open files (linux specific) */
|
|
static void
|
|
countOpenFiles(void)
|
|
{
|
|
char proc_path[MAXFNAME];
|
|
DIR *dp;
|
|
struct dirent *files;
|
|
|
|
st_openfiles = 0;
|
|
snprintf(proc_path, sizeof(proc_path), "/proc/%d/fd", glblGetOurPid());
|
|
if((dp = opendir(proc_path)) == NULL) {
|
|
LogError(errno, RS_RET_ERR, "impstats: error reading %s\n", proc_path);
|
|
goto done;
|
|
}
|
|
while((files=readdir(dp)) != NULL) {
|
|
if(!strcmp(files->d_name, ".") || !strcmp(files->d_name, ".."))
|
|
continue;
|
|
st_openfiles++;
|
|
}
|
|
closedir(dp);
|
|
|
|
done:
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
|
|
static void
|
|
initConfigSettings(void)
|
|
{
|
|
cs.iStatsInterval = DEFAULT_STATS_PERIOD;
|
|
cs.iFacility = DEFAULT_FACILITY;
|
|
cs.iSeverity = DEFAULT_SEVERITY;
|
|
cs.bJSON = 0;
|
|
cs.bCEE = 0;
|
|
}
|
|
|
|
|
|
/* actually submit a message to the rsyslog core
|
|
*/
|
|
static void
|
|
doSubmitMsg(uchar *line)
|
|
{
|
|
smsg_t *pMsg;
|
|
|
|
if(msgConstruct(&pMsg) != RS_RET_OK)
|
|
goto finalize_it;
|
|
MsgSetInputName(pMsg, pInputName);
|
|
MsgSetRawMsgWOSize(pMsg, (char*)line);
|
|
MsgSetHOSTNAME(pMsg, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName()));
|
|
MsgSetRcvFrom(pMsg, glbl.GetLocalHostNameProp());
|
|
MsgSetRcvFromIP(pMsg, glbl.GetLocalHostIP());
|
|
MsgSetMSGoffs(pMsg, 0);
|
|
MsgSetRuleset(pMsg, runModConf->pBindRuleset);
|
|
MsgSetTAG(pMsg, UCHAR_CONSTANT("rsyslogd-pstats:"), sizeof("rsyslogd-pstats:") - 1);
|
|
pMsg->iFacility = runModConf->iFacility;
|
|
pMsg->iSeverity = runModConf->iSeverity;
|
|
pMsg->msgFlags = 0;
|
|
|
|
/* we do not use rate-limiting, as the stats message always need to be emitted */
|
|
submitMsg2(pMsg);
|
|
DBGPRINTF("impstats: submit [%d,%d] msg '%s'\n", runModConf->iFacility,
|
|
runModConf->iSeverity, line);
|
|
|
|
finalize_it:
|
|
return;
|
|
}
|
|
|
|
|
|
/* log stats message to file; limited error handling done */
|
|
static void
|
|
doLogToFile(const char *ln, const size_t lenLn)
|
|
{
|
|
struct iovec iov[4];
|
|
ssize_t nwritten;
|
|
ssize_t nexpect;
|
|
time_t t;
|
|
char timebuf[32];
|
|
|
|
pthread_mutex_lock(&hup_mutex);
|
|
|
|
if(lenLn == 0)
|
|
goto done;
|
|
|
|
if(runModConf->logfd == -1) {
|
|
runModConf->logfd = open(runModConf->logfile, O_WRONLY|O_CREAT|O_APPEND|O_CLOEXEC, S_IRUSR|S_IWUSR);
|
|
if(runModConf->logfd == -1) {
|
|
DBGPRINTF("impstats: error opening stats file %s\n",
|
|
runModConf->logfile);
|
|
goto done;
|
|
} else {
|
|
DBGPRINTF("impstats: opened stats file %s\n",
|
|
runModConf->logfile);
|
|
}
|
|
}
|
|
|
|
time(&t);
|
|
iov[0].iov_base = ctime_r(&t, timebuf);
|
|
iov[0].iov_len = nexpect = strlen(iov[0].iov_base) - 1; /* -1: strip \n */
|
|
iov[1].iov_base = (void*)": ";
|
|
iov[1].iov_len = 2;
|
|
nexpect += 2;
|
|
iov[2].iov_base = (void*)ln;
|
|
iov[2].iov_len = lenLn;
|
|
nexpect += lenLn;
|
|
iov[3].iov_base = (void*)"\n";
|
|
iov[3].iov_len = 1;
|
|
nexpect++;
|
|
nwritten = writev(runModConf->logfd, iov, 4);
|
|
|
|
if(nwritten != nexpect) {
|
|
dbgprintf("error writing stats file %s, nwritten %lld, expected %lld\n",
|
|
runModConf->logfile, (long long) nwritten, (long long) nexpect);
|
|
}
|
|
done:
|
|
pthread_mutex_unlock(&hup_mutex);
|
|
return;
|
|
}
|
|
|
|
|
|
/* submit a line to our log destinations. Line must be fully formatted as
|
|
* required (but may be a simple verb like "BEGIN" and "END".
|
|
*/
|
|
static rsRetVal
|
|
submitLine(const char *const ln, const size_t lenLn)
|
|
{
|
|
DEFiRet;
|
|
if(runModConf->bLogToSyslog)
|
|
doSubmitMsg((uchar*)ln);
|
|
if(runModConf->logfile != NULL)
|
|
doLogToFile(ln, lenLn);
|
|
RETiRet;
|
|
}
|
|
|
|
/* callback for statsobj
|
|
* Note: usrptr exists only to satisfy requirements of statsobj callback interface!
|
|
*/
|
|
static rsRetVal
|
|
doStatsLine(void __attribute__((unused)) *usrptr, const char *const str)
|
|
{
|
|
DEFiRet;
|
|
iRet = submitLine(str, strlen(str));
|
|
RETiRet;
|
|
}
|
|
|
|
|
|
/* the function to generate the actual statistics messages
|
|
* rgerhards, 2010-09-09
|
|
*/
|
|
static void
|
|
generateStatsMsgs(void)
|
|
{
|
|
struct rusage ru;
|
|
int r;
|
|
r = getrusage(RUSAGE_SELF, &ru);
|
|
if(r != 0) {
|
|
dbgprintf("impstats: getrusage() failed with error %d, zeroing out\n", errno);
|
|
memset(&ru, 0, sizeof(ru));
|
|
}
|
|
# ifdef OS_LINUX
|
|
countOpenFiles();
|
|
# endif
|
|
st_ru_utime = ru.ru_utime.tv_sec * 1000000 + ru.ru_utime.tv_usec;
|
|
st_ru_stime = ru.ru_stime.tv_sec * 1000000 + ru.ru_stime.tv_usec;
|
|
st_ru_maxrss = ru.ru_maxrss;
|
|
st_ru_minflt = ru.ru_minflt;
|
|
st_ru_majflt = ru.ru_majflt;
|
|
st_ru_inblock = ru.ru_inblock;
|
|
st_ru_oublock = ru.ru_oublock;
|
|
st_ru_nvcsw = ru.ru_nvcsw;
|
|
st_ru_nivcsw = ru.ru_nivcsw;
|
|
statsobj.GetAllStatsLines(doStatsLine, NULL, runModConf->statsFmt, runModConf->bResetCtrs);
|
|
}
|
|
|
|
|
|
BEGINbeginCnfLoad
|
|
CODESTARTbeginCnfLoad
|
|
loadModConf = pModConf;
|
|
pModConf->pConf = pConf;
|
|
/* init our settings */
|
|
loadModConf->configSetViaV2Method = 0;
|
|
loadModConf->iStatsInterval = DEFAULT_STATS_PERIOD;
|
|
loadModConf->iFacility = DEFAULT_FACILITY;
|
|
loadModConf->iSeverity = DEFAULT_SEVERITY;
|
|
loadModConf->statsFmt = statsFmt_Legacy;
|
|
loadModConf->logfd = -1;
|
|
loadModConf->logfile = NULL;
|
|
loadModConf->pszBindRuleset = NULL;
|
|
loadModConf->bLogToSyslog = 1;
|
|
loadModConf->bBracketing = 0;
|
|
loadModConf->bResetCtrs = 0;
|
|
bLegacyCnfModGlobalsPermitted = 1;
|
|
/* init legacy config vars */
|
|
initConfigSettings();
|
|
ENDbeginCnfLoad
|
|
|
|
|
|
BEGINsetModCnf
|
|
struct cnfparamvals *pvals = NULL;
|
|
char *mode;
|
|
int i;
|
|
CODESTARTsetModCnf
|
|
pvals = nvlstGetParams(lst, &modpblk, NULL);
|
|
if(pvals == NULL) {
|
|
errmsg.LogError(0, RS_RET_MISSING_CNFPARAMS, "error processing module "
|
|
"config parameters [module(...)]");
|
|
ABORT_FINALIZE(RS_RET_MISSING_CNFPARAMS);
|
|
}
|
|
|
|
if(Debug) {
|
|
dbgprintf("module (global) param blk for impstats:\n");
|
|
cnfparamsPrint(&modpblk, pvals);
|
|
}
|
|
|
|
for(i = 0 ; i < modpblk.nParams ; ++i) {
|
|
if(!pvals[i].bUsed)
|
|
continue;
|
|
if(!strcmp(modpblk.descr[i].name, "interval")) {
|
|
loadModConf->iStatsInterval = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "facility")) {
|
|
loadModConf->iFacility = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "severity")) {
|
|
loadModConf->iSeverity = (int) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "bracketing")) {
|
|
loadModConf->bBracketing = (sbool) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "log.syslog")) {
|
|
loadModConf->bLogToSyslog = (sbool) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "resetcounters")) {
|
|
loadModConf->bResetCtrs = (sbool) pvals[i].val.d.n;
|
|
} else if(!strcmp(modpblk.descr[i].name, "log.file")) {
|
|
loadModConf->logfile = es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
} else if(!strcmp(modpblk.descr[i].name, "format")) {
|
|
mode = es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
if(!strcasecmp(mode, "json")) {
|
|
loadModConf->statsFmt = statsFmt_JSON;
|
|
} else if(!strcasecmp(mode, "json-elasticsearch")) {
|
|
loadModConf->statsFmt = statsFmt_JSON_ES;
|
|
} else if(!strcasecmp(mode, "cee")) {
|
|
loadModConf->statsFmt = statsFmt_CEE;
|
|
} else if(!strcasecmp(mode, "legacy")) {
|
|
loadModConf->statsFmt = statsFmt_Legacy;
|
|
} else {
|
|
errmsg.LogError(0, RS_RET_ERR, "impstats: invalid format %s",
|
|
mode);
|
|
}
|
|
free(mode);
|
|
} else if(!strcmp(modpblk.descr[i].name, "ruleset")) {
|
|
loadModConf->pszBindRuleset = (uchar*)es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
} else {
|
|
dbgprintf("impstats: program error, non-handled "
|
|
"param '%s' in beginCnfLoad\n", modpblk.descr[i].name);
|
|
}
|
|
}
|
|
|
|
loadModConf->configSetViaV2Method = 1;
|
|
bLegacyCnfModGlobalsPermitted = 0;
|
|
|
|
finalize_it:
|
|
if(pvals != NULL)
|
|
cnfparamvalsDestruct(pvals, &modpblk);
|
|
ENDsetModCnf
|
|
|
|
|
|
BEGINendCnfLoad
|
|
CODESTARTendCnfLoad
|
|
if(!loadModConf->configSetViaV2Method) {
|
|
/* persist module-specific settings from legacy config system */
|
|
loadModConf->iStatsInterval = cs.iStatsInterval;
|
|
loadModConf->iFacility = cs.iFacility;
|
|
loadModConf->iSeverity = cs.iSeverity;
|
|
if (cs.bCEE == 1) {
|
|
loadModConf->statsFmt = statsFmt_CEE;
|
|
} else if (cs.bJSON == 1) {
|
|
loadModConf->statsFmt = statsFmt_JSON;
|
|
} else {
|
|
loadModConf->statsFmt = statsFmt_Legacy;
|
|
}
|
|
}
|
|
ENDendCnfLoad
|
|
|
|
|
|
/* we need our special version of checkRuleset(), as we do not have any instances */
|
|
static rsRetVal
|
|
checkRuleset(modConfData_t *modConf)
|
|
{
|
|
ruleset_t *pRuleset;
|
|
rsRetVal localRet;
|
|
DEFiRet;
|
|
|
|
modConf->pBindRuleset = NULL; /* assume default ruleset */
|
|
|
|
if(modConf->pszBindRuleset == NULL)
|
|
FINALIZE;
|
|
|
|
localRet = ruleset.GetRuleset(modConf->pConf, &pRuleset, modConf->pszBindRuleset);
|
|
if(localRet == RS_RET_NOT_FOUND) {
|
|
errmsg.LogError(0, NO_ERRCODE, "impstats: ruleset '%s' not found - "
|
|
"using default ruleset instead", modConf->pszBindRuleset);
|
|
}
|
|
CHKiRet(localRet);
|
|
modConf->pBindRuleset = pRuleset;
|
|
finalize_it:
|
|
RETiRet;
|
|
}
|
|
|
|
|
|
/* to use HUP, we need to have an instanceData type, as this was
|
|
* originally designed for actions. However, we do not, and cannot,
|
|
* use the content. The core will always provide a NULL pointer.
|
|
*/
|
|
typedef struct _instanceData {
|
|
int dummy;
|
|
} instanceData;
|
|
BEGINdoHUP
|
|
CODESTARTdoHUP
|
|
DBGPRINTF("impstats: received HUP\n")
|
|
pthread_mutex_lock(&hup_mutex);
|
|
if(runModConf->logfd != -1) {
|
|
DBGPRINTF("impstats: closing log file due to HUP\n");
|
|
close(runModConf->logfd);
|
|
runModConf->logfd = -1;
|
|
}
|
|
pthread_mutex_unlock(&hup_mutex);
|
|
ENDdoHUP
|
|
|
|
|
|
BEGINcheckCnf
|
|
CODESTARTcheckCnf
|
|
if(pModConf->iStatsInterval == 0) {
|
|
errmsg.LogError(0, NO_ERRCODE, "impstats: stats interval zero not permitted, using "
|
|
"default of %d seconds", DEFAULT_STATS_PERIOD);
|
|
pModConf->iStatsInterval = DEFAULT_STATS_PERIOD;
|
|
}
|
|
iRet = checkRuleset(pModConf);
|
|
ENDcheckCnf
|
|
|
|
|
|
BEGINactivateCnf
|
|
rsRetVal localRet;
|
|
CODESTARTactivateCnf
|
|
runModConf = pModConf;
|
|
DBGPRINTF("impstats: stats interval %d seconds, reset %d, logToSyslog %d, logFile %s\n",
|
|
runModConf->iStatsInterval, runModConf->bResetCtrs, runModConf->bLogToSyslog,
|
|
runModConf->logfile == NULL ? "deactivated" : (char*)runModConf->logfile);
|
|
localRet = statsobj.EnableStats();
|
|
if(localRet != RS_RET_OK) {
|
|
errmsg.LogError(0, localRet, "impstats: error enabling statistics gathering");
|
|
ABORT_FINALIZE(RS_RET_NO_RUN);
|
|
}
|
|
/* initialize our own counters */
|
|
CHKiRet(statsobj.Construct(&statsobj_resources));
|
|
CHKiRet(statsobj.SetName(statsobj_resources, (uchar*)"resource-usage"));
|
|
CHKiRet(statsobj.SetOrigin(statsobj_resources, (uchar*)"impstats"));
|
|
CHKiRet(statsobj.AddCounter(statsobj_resources, UCHAR_CONSTANT("utime"),
|
|
ctrType_IntCtr, CTR_FLAG_NONE, &st_ru_utime));
|
|
CHKiRet(statsobj.AddCounter(statsobj_resources, UCHAR_CONSTANT("stime"),
|
|
ctrType_IntCtr, CTR_FLAG_NONE, &st_ru_stime));
|
|
CHKiRet(statsobj.AddCounter(statsobj_resources, UCHAR_CONSTANT("maxrss"),
|
|
ctrType_Int, CTR_FLAG_NONE, &st_ru_maxrss));
|
|
CHKiRet(statsobj.AddCounter(statsobj_resources, UCHAR_CONSTANT("minflt"),
|
|
ctrType_Int, CTR_FLAG_NONE, &st_ru_minflt));
|
|
CHKiRet(statsobj.AddCounter(statsobj_resources, UCHAR_CONSTANT("majflt"),
|
|
ctrType_Int, CTR_FLAG_NONE, &st_ru_majflt));
|
|
CHKiRet(statsobj.AddCounter(statsobj_resources, UCHAR_CONSTANT("inblock"),
|
|
ctrType_Int, CTR_FLAG_NONE, &st_ru_inblock));
|
|
CHKiRet(statsobj.AddCounter(statsobj_resources, UCHAR_CONSTANT("oublock"),
|
|
ctrType_Int, CTR_FLAG_NONE, &st_ru_oublock));
|
|
CHKiRet(statsobj.AddCounter(statsobj_resources, UCHAR_CONSTANT("nvcsw"),
|
|
ctrType_Int, CTR_FLAG_NONE, &st_ru_nvcsw));
|
|
CHKiRet(statsobj.AddCounter(statsobj_resources, UCHAR_CONSTANT("nivcsw"),
|
|
ctrType_Int, CTR_FLAG_NONE, &st_ru_nivcsw));
|
|
# ifdef OS_LINUX
|
|
CHKiRet(statsobj.AddCounter(statsobj_resources, UCHAR_CONSTANT("openfiles"),
|
|
ctrType_Int, CTR_FLAG_NONE, &st_openfiles));
|
|
# endif
|
|
CHKiRet(statsobj.ConstructFinalize(statsobj_resources));
|
|
finalize_it:
|
|
if(iRet != RS_RET_OK) {
|
|
errmsg.LogError(0, iRet, "impstats: error activating module");
|
|
iRet = RS_RET_NO_RUN;
|
|
}
|
|
ENDactivateCnf
|
|
|
|
|
|
BEGINfreeCnf
|
|
CODESTARTfreeCnf
|
|
if(runModConf->logfd != -1)
|
|
close(runModConf->logfd);
|
|
free(runModConf->logfile);
|
|
free(runModConf->pszBindRuleset);
|
|
ENDfreeCnf
|
|
|
|
|
|
BEGINrunInput
|
|
CODESTARTrunInput
|
|
/* this is an endless loop - it is terminated when the thread is
|
|
* signalled to do so. This, however, is handled by the framework,
|
|
* right into the sleep below. Note that we DELIBERATLY output
|
|
* final set of stats counters on termination request. Depending
|
|
* on configuration, they may not make it to the final destination...
|
|
*/
|
|
while(glbl.GetGlobalInputTermState() == 0) {
|
|
srSleep(runModConf->iStatsInterval, 0); /* seconds, micro seconds */
|
|
DBGPRINTF("impstats: woke up, generating messages\n");
|
|
if(runModConf->bBracketing)
|
|
submitLine("BEGIN", sizeof("BEGIN")-1);
|
|
generateStatsMsgs();
|
|
if(runModConf->bBracketing)
|
|
submitLine("END", sizeof("END")-1);
|
|
}
|
|
ENDrunInput
|
|
|
|
|
|
BEGINwillRun
|
|
CODESTARTwillRun
|
|
ENDwillRun
|
|
|
|
|
|
BEGINafterRun
|
|
CODESTARTafterRun
|
|
ENDafterRun
|
|
|
|
|
|
BEGINqueryEtryPt
|
|
CODESTARTqueryEtryPt
|
|
CODEqueryEtryPt_STD_IMOD_QUERIES
|
|
CODEqueryEtryPt_STD_CONF2_QUERIES
|
|
CODEqueryEtryPt_STD_CONF2_setModCnf_QUERIES
|
|
CODEqueryEtryPt_IsCompatibleWithFeature_IF_OMOD_QUERIES
|
|
CODEqueryEtryPt_doHUP
|
|
ENDqueryEtryPt
|
|
|
|
static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal)
|
|
{
|
|
initConfigSettings();
|
|
return RS_RET_OK;
|
|
}
|
|
|
|
|
|
BEGINmodInit()
|
|
CODESTARTmodInit
|
|
*ipIFVersProvided = CURR_MOD_IF_VERSION; /* we only support the current interface specification */
|
|
CODEmodInit_QueryRegCFSLineHdlr
|
|
DBGPRINTF("impstats version %s loading\n", VERSION);
|
|
initConfigSettings();
|
|
CHKiRet(objUse(glbl, CORE_COMPONENT));
|
|
CHKiRet(objUse(prop, CORE_COMPONENT));
|
|
CHKiRet(objUse(errmsg, CORE_COMPONENT));
|
|
CHKiRet(objUse(statsobj, CORE_COMPONENT));
|
|
CHKiRet(objUse(ruleset, CORE_COMPONENT));
|
|
/* the pstatsinverval is an alias to support a previous screwed-up syntax... */
|
|
CHKiRet(regCfSysLineHdlr2((uchar *)"pstatsinterval", 0, eCmdHdlrInt, NULL, &cs.iStatsInterval,
|
|
STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2((uchar *)"pstatinterval", 0, eCmdHdlrInt, NULL, &cs.iStatsInterval,
|
|
STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2((uchar *)"pstatfacility", 0, eCmdHdlrInt, NULL, &cs.iFacility,
|
|
STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2((uchar *)"pstatseverity", 0, eCmdHdlrInt, NULL, &cs.iSeverity,
|
|
STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2((uchar *)"pstatjson", 0, eCmdHdlrBinary, NULL, &cs.bJSON,
|
|
STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(regCfSysLineHdlr2((uchar *)"pstatcee", 0, eCmdHdlrBinary, NULL, &cs.bCEE,
|
|
STD_LOADABLE_MODULE_ID, &bLegacyCnfModGlobalsPermitted));
|
|
CHKiRet(omsdRegCFSLineHdlr((uchar *)"resetconfigvariables", 1, eCmdHdlrCustomHandler, resetConfigVariables,
|
|
NULL, STD_LOADABLE_MODULE_ID));
|
|
|
|
CHKiRet(prop.Construct(&pInputName));
|
|
CHKiRet(prop.SetString(pInputName, UCHAR_CONSTANT("impstats"), sizeof("impstats") - 1));
|
|
CHKiRet(prop.ConstructFinalize(pInputName));
|
|
ENDmodInit
|
|
/* vi:set ai:
|
|
*/
|