diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2013-10-22 17:55:35 +0200 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2013-10-22 17:55:35 +0200 |
commit | 7d39740b3d88dbd0432806e5f8da32c49cdb69f1 (patch) | |
tree | 452e5e27c13b49c5b1910f70a283e3a533ee1283 | |
parent | e4e19176298d6ac76c463565fa192c2349731156 (diff) | |
download | rsyslog-7d39740b3d88dbd0432806e5f8da32c49cdb69f1.tar.gz rsyslog-7d39740b3d88dbd0432806e5f8da32c49cdb69f1.tar.bz2 rsyslog-7d39740b3d88dbd0432806e5f8da32c49cdb69f1.zip |
refactor: use common code for message property description processing
in all cases except script var access -- this comes next...
-rw-r--r-- | grammar/rainerscript.c | 24 | ||||
-rw-r--r-- | grammar/rainerscript.h | 6 | ||||
-rw-r--r-- | plugins/ommongodb/ommongodb.c | 18 | ||||
-rw-r--r-- | runtime/msg.c | 66 | ||||
-rw-r--r-- | runtime/msg.h | 8 | ||||
-rw-r--r-- | runtime/rsyslog.h | 48 | ||||
-rw-r--r-- | runtime/ruleset.c | 21 | ||||
-rw-r--r-- | runtime/ruleset.h | 2 | ||||
-rw-r--r-- | runtime/typedefs.h | 54 | ||||
-rw-r--r-- | template.c | 77 | ||||
-rw-r--r-- | template.h | 4 |
11 files changed, 170 insertions, 158 deletions
diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c index b74ff346..3caa585c 100644 --- a/grammar/rainerscript.c +++ b/grammar/rainerscript.c @@ -47,6 +47,7 @@ #include "obj.h" #include "modules.h" #include "ruleset.h" +#include "msg.h" #include "unicode-helper.h" DEFobjCurrIf(obj) @@ -177,18 +178,8 @@ DecodePropFilter(uchar *pline, struct cnfstmt *stmt) rsParsDestruct(pPars); ABORT_FINALIZE(iRet); } - iRet = propNameToID(cstrGetSzStrNoNULL(pCSPropName), &stmt->d.s_propfilt.propID); - if(iRet != RS_RET_OK) { - parser_errmsg("invalid property name '%s' in filter", - cstrGetSzStrNoNULL(pCSPropName)); - rsParsDestruct(pPars); - ABORT_FINALIZE(iRet); - } - if(stmt->d.s_propfilt.propID == PROP_CEE) { - /* in CEE case, we need to preserve the actual property name */ - stmt->d.s_propfilt.propName = ustrdup(cstrGetSzStrNoNULL(pCSPropName+2)); - stmt->d.s_propfilt.propNameLen = cstrLen(pCSPropName)-2; - } + CHKiRet(msgPropDescrFill(&stmt->d.s_propfilt.prop, cstrGetSzStrNoNULL(pCSPropName), + cstrLen(pCSPropName))); /* read operation */ iRet = parsDelimCStr(pPars, &pCSCompOp, ',', 1, 1, 1); @@ -2442,10 +2433,10 @@ cnfstmtPrintOnly(struct cnfstmt *stmt, int indent, sbool subtree) case S_PROPFILT: doIndent(indent); dbgprintf("PROPFILT\n"); doIndent(indent); dbgprintf("\tProperty.: '%s'\n", - propIDToName(stmt->d.s_propfilt.propID)); - if(stmt->d.s_propfilt.propName != NULL) { + propIDToName(stmt->d.s_propfilt.prop.id)); + if(stmt->d.s_propfilt.prop.name != NULL) { doIndent(indent); - dbgprintf("\tCEE-Prop.: '%s'\n", stmt->d.s_propfilt.propName); + dbgprintf("\tCEE-Prop.: '%s'\n", stmt->d.s_propfilt.prop.name); } doIndent(indent); dbgprintf("\tOperation: "); if(stmt->d.s_propfilt.isNegated) @@ -2605,7 +2596,7 @@ cnfstmtDestruct(struct cnfstmt *stmt) cnfstmtDestructLst(stmt->d.s_prifilt.t_else); break; case S_PROPFILT: - free(stmt->d.s_propfilt.propName); + msgPropDescrDestruct(&stmt->d.s_propfilt.prop); if(stmt->d.s_propfilt.regex_cache != NULL) rsCStrRegexDestruct(&stmt->d.s_propfilt.regex_cache); if(stmt->d.s_propfilt.pCSCompValue != NULL) @@ -2690,7 +2681,6 @@ cnfstmtNewPROPFILT(char *propfilt, struct cnfstmt *t_then) if((cnfstmt = cnfstmtNew(S_PROPFILT)) != NULL) { cnfstmt->printable = (uchar*)propfilt; cnfstmt->d.s_propfilt.t_then = t_then; - cnfstmt->d.s_propfilt.propName = NULL; cnfstmt->d.s_propfilt.regex_cache = NULL; cnfstmt->d.s_propfilt.pCSCompValue = NULL; if(DecodePropFilter((uchar*)propfilt, cnfstmt) != RS_RET_OK) { diff --git a/grammar/rainerscript.h b/grammar/rainerscript.h index 7bbd7456..7a4f1ac9 100644 --- a/grammar/rainerscript.h +++ b/grammar/rainerscript.h @@ -6,7 +6,6 @@ #include <sys/types.h> #include <regex.h> - #define LOG_NFACILITIES 24 /* current number of syslog facilities */ #define CNFFUNC_MAX_ARGS 32 /**< maximum number of arguments that any function can have (among @@ -182,10 +181,7 @@ struct cnfstmt { regex_t *regex_cache;/* cache for compiled REs, if used */ struct cstr_s *pCSCompValue;/* value to "compare" against */ sbool isNegated; - uintTiny propID;/* ID of the requested property */ - //es_str_t *propName;/* name of property for CEE-based filters */ - uchar *propName; - int propNameLen; + msgPropDescr_t prop; /* requested property */ struct cnfstmt *t_then; struct cnfstmt *t_else; } s_propfilt; diff --git a/plugins/ommongodb/ommongodb.c b/plugins/ommongodb/ommongodb.c index 85f09d1b..78781c08 100644 --- a/plugins/ommongodb/ommongodb.c +++ b/plugins/ommongodb/ommongodb.c @@ -235,12 +235,18 @@ getDefaultBSON(msg_t *pMsg) int severity, facil; gint64 ts_gen, ts_rcv; /* timestamps: generated, received */ int secfrac; - - procid = MsgGetProp(pMsg, NULL, PROP_PROGRAMNAME, NULL, 0, &procid_len, &procid_free, NULL); - tag = MsgGetProp(pMsg, NULL, PROP_SYSLOGTAG, NULL, 0, &tag_len, &tag_free, NULL); - pid = MsgGetProp(pMsg, NULL, PROP_PROCID, NULL, 0, &pid_len, &pid_free, NULL); - sys = MsgGetProp(pMsg, NULL, PROP_HOSTNAME, NULL, 0, &sys_len, &sys_free, NULL); - msg = MsgGetProp(pMsg, NULL, PROP_MSG, NULL, 0, &msg_len, &msg_free, NULL); + msgPropDescr_t cProp; /* we use internal implementation knowledge... */ + + cProp.id = PROP_PROGRAMNAME; + procid = MsgGetProp(pMsg, NULL, &cProp, &procid_len, &procid_free, NULL); + cProp.id = PROP_SYSLOGTAG; + tag = MsgGetProp(pMsg, NULL, &cProp, &tag_len, &tag_free, NULL); + cProp.id = PROP_PROCID; + pid = MsgGetProp(pMsg, NULL, &cProp, &pid_len, &pid_free, NULL); + cProp.id = PROP_HOSTNAME; + sys = MsgGetProp(pMsg, NULL, &cProp, &sys_len, &sys_free, NULL); + cProp.id = PROP_MSG; + msg = MsgGetProp(pMsg, NULL, &cProp, &msg_len, &msg_free, NULL); // TODO: move to datetime? Refactor in any case! rgerhards, 2012-03-30 ts_gen = (gint64) datetime.syslogTime2time_t(&pMsg->tTIMESTAMP) * 1000; /* ms! */ diff --git a/runtime/msg.c b/runtime/msg.c index 4ff0bbb5..b1b912a4 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -540,8 +540,6 @@ propNameToID(uchar *pName, propid_t *pPropID) *pPropID = PROP_CEE; } else if(!strncmp((char*) pName, "$.", 2) || pName[0] == '.') { *pPropID = PROP_LOCAL_VAR; - } else if(!strncmp((char*) pName, "$/", 2) || pName[0] == '/') { - *pPropID = PROP_GLOBAL_VAR; } else { DBGPRINTF("PROP_INVALID for name '%s'\n", pName); *pPropID = PROP_INVALID; @@ -624,8 +622,6 @@ uchar *propIDToName(propid_t propID) return UCHAR_CONSTANT("*CEE-based property*"); case PROP_LOCAL_VAR: return UCHAR_CONSTANT("*LOCAL_VARIABLE*"); - case PROP_GLOBAL_VAR: - return UCHAR_CONSTANT("*GLOBAL_VARIABLE*"); case PROP_CEE_ALL_JSON: return UCHAR_CONSTANT("$!all-json"); case PROP_SYS_BOM: @@ -2831,7 +2827,7 @@ finalize_it: *pPropLen = sizeof("**OUT OF MEMORY**") - 1; \ return(UCHAR_CONSTANT("**OUT OF MEMORY**"));} uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, - propid_t propid, uchar *propName, int propNameLen, rs_size_t *pPropLen, + msgPropDescr_t *pProp, rs_size_t *pPropLen, unsigned short *pbMustBeFreed, struct syslogTime *ttNow) { uchar *pRes; /* result pointer */ @@ -2854,7 +2850,7 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, *pbMustBeFreed = 0; - switch(propid) { + switch(pProp->id) { case PROP_MSG: pRes = getMSG(pMsg); bufLen = getMSGLen(pMsg); @@ -3026,13 +3022,10 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, } break; case PROP_CEE: - getCEEPropVal(pMsg, propName, propNameLen, &pRes, &bufLen, pbMustBeFreed); + getCEEPropVal(pMsg, pProp->name, pProp->nameLen, &pRes, &bufLen, pbMustBeFreed); break; case PROP_LOCAL_VAR: - getLocalVarPropVal(pMsg, propName, propNameLen, &pRes, &bufLen, pbMustBeFreed); - break; - case PROP_GLOBAL_VAR: - getGlobalVarPropVal(propName, propNameLen, &pRes, &bufLen, pbMustBeFreed); + getLocalVarPropVal(pMsg, pProp->name, pProp->nameLen, &pRes, &bufLen, pbMustBeFreed); break; case PROP_SYS_BOM: if(*pbMustBeFreed == 1) @@ -3093,7 +3086,7 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, /* there is no point in continuing, we may even otherwise render the * error message unreadable. rgerhards, 2007-07-10 */ - dbgprintf("invalid property id: '%d'\n", propid); + dbgprintf("invalid property id: '%d'\n", pProp->id); *pbMustBeFreed = 0; *pPropLen = sizeof("**INVALID PROPERTY NAME**") - 1; return UCHAR_CONSTANT("**INVALID PROPERTY NAME**"); @@ -3753,8 +3746,8 @@ msgGetMsgVarNew(msg_t *pThis, uchar *name) { rs_size_t propLen; uchar *pszProp = NULL; - propid_t propid; unsigned short bMustBeFreed = 0; + msgPropDescr_t mProp; es_str_t *estr; ISOBJ_TYPE_assert(pThis, msg); @@ -3762,8 +3755,8 @@ msgGetMsgVarNew(msg_t *pThis, uchar *name) /* always call MsgGetProp() without a template specifier */ /* TODO: optimize propNameToID() call -- rgerhards, 2009-06-26 */ #warning remove strlen() ? - propNameToID(name, &propid); - pszProp = (uchar*) MsgGetProp(pThis, NULL, propid, name, ustrlen(name), &propLen, &bMustBeFreed, NULL); + msgPropDescrFill(&mProp, name, ustrlen(name)); + pszProp = (uchar*) MsgGetProp(pThis, NULL, &mProp, &propLen, &bMustBeFreed, NULL); estr = es_newStrFromCStr((char*)pszProp, propLen); if(bMustBeFreed) @@ -3882,6 +3875,7 @@ jsonPathGetLeaf(uchar *name, int lenName) if(name[i] == '!') break; } +dbgprintf("DDDD: jsonPAthGetLeaf: name '%s', lenNAme %d, i %d\n", name, lenName, i); if(name[i] == '!' || name[i] == '.' || name[i] == '/') ++i; return name + i; @@ -4197,6 +4191,48 @@ finalize_it: } +/* Fill a message propert description. Space must already be alloced + * by the caller. This is for efficiency, as we expect this to happen + * as part of a larger structure alloc. + * Note that CEE/LOCAL_VAR properties can come in either as + * "$!xx"/"$.xx" or "!xx"/".xx" - we will unify them here. + */ +rsRetVal +msgPropDescrFill(msgPropDescr_t *pProp, uchar *name, int nameLen) +{ + propid_t id; + int offs; + DEFiRet; + if(propNameToID(name, &id) != RS_RET_OK) { +#warning enable error messages + //errmsg.LogError(0, RS_RET_TPL_INVLD_PROP, "invalid property '%s'", + //pTpl->pszName, cstrGetSzStrNoNULL(pStrProp)); + ABORT_FINALIZE(RS_RET_INVLD_PROP); + } + if(id == PROP_CEE || id == PROP_LOCAL_VAR) { + /* in these cases, we need the field name for later processing */ + /* normalize name: remove $ if present */ + offs = (name[0] == '$') ? 1 : 0; + pProp->name = ustrdup(name + offs); + pProp->nameLen = nameLen - offs; + /* we patch the root name, so that support functions do not need to + * check for different root chars. */ + pProp->name[0] = '!'; +dbgprintf("DDDD: setting porpname '%s' (offs %d)\n", pProp->name, offs); + } + pProp->id = id; +finalize_it: + RETiRet; +} + +void +msgPropDescrDestruct(msgPropDescr_t *pProp) +{ + if(pProp != NULL) { + free(pProp->name); + } +} + /* dummy */ rsRetVal msgQueryInterface(void) { return RS_RET_NOT_IMPLEMENTED; } diff --git a/runtime/msg.h b/runtime/msg.h index 8c5e7bfe..4dcc0579 100644 --- a/runtime/msg.h +++ b/runtime/msg.h @@ -3,7 +3,7 @@ * * File begun on 2007-07-13 by RGerhards (extracted from syslogd.c) * - * Copyright 2007-2012 Rainer Gerhards and Adiscon GmbH. + * Copyright 2007-2013 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * @@ -183,8 +183,7 @@ void MsgSetMSGoffs(msg_t *pMsg, short offs); void MsgSetRawMsgWOSize(msg_t *pMsg, char* pszRawMsg); void MsgSetRawMsg(msg_t *pMsg, char* pszRawMsg, size_t lenMsg); rsRetVal MsgReplaceMSG(msg_t *pThis, uchar* pszMSG, int lenMSG); -uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, - propid_t propid, uchar *propName, int propNameLen, +uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, msgPropDescr_t *pProp, rs_size_t *pPropLen, unsigned short *pbMustBeFreed, struct syslogTime *ttNow); rsRetVal msgGetMsgVar(msg_t *pThis, cstr_t *pstrPropName, var_t **ppVar); es_str_t* msgGetMsgVarNew(msg_t *pThis, uchar *name); @@ -223,6 +222,9 @@ rsRetVal msgSetJSONFromVar(msg_t *pMsg, uchar *varname, struct var *var); rsRetVal msgDelJSON(msg_t *pMsg, uchar *varname); rsRetVal jsonFind(struct json_object *jroot, uchar *propName, int propNameLen, struct json_object **jsonres); +rsRetVal msgPropDescrFill(msgPropDescr_t *pProp, uchar *name, int nameLen); +void msgPropDescrDestruct(msgPropDescr_t *pProp); + static inline rsRetVal msgUnsetJSON(msg_t *pMsg, uchar *varname) { return msgDelJSON(pMsg, varname+1); diff --git a/runtime/rsyslog.h b/runtime/rsyslog.h index 71849bec..5f0401df 100644 --- a/runtime/rsyslog.h +++ b/runtime/rsyslog.h @@ -102,52 +102,6 @@ #define _PATH_CONSOLE "/dev/console" #endif -/* properties are now encoded as (tiny) integers. I do not use an enum as I would like - * to keep the memory footprint small (and thus cache hits high). - * rgerhards, 2009-06-26 - */ -typedef uintTiny propid_t; -#define PROP_INVALID 0 -#define PROP_MSG 1 -#define PROP_TIMESTAMP 2 -#define PROP_HOSTNAME 3 -#define PROP_SYSLOGTAG 4 -#define PROP_RAWMSG 5 -#define PROP_INPUTNAME 6 -#define PROP_FROMHOST 7 -#define PROP_FROMHOST_IP 8 -#define PROP_PRI 9 -#define PROP_PRI_TEXT 10 -#define PROP_IUT 11 -#define PROP_SYSLOGFACILITY 12 -#define PROP_SYSLOGFACILITY_TEXT 13 -#define PROP_SYSLOGSEVERITY 14 -#define PROP_SYSLOGSEVERITY_TEXT 15 -#define PROP_TIMEGENERATED 16 -#define PROP_PROGRAMNAME 17 -#define PROP_PROTOCOL_VERSION 18 -#define PROP_STRUCTURED_DATA 19 -#define PROP_APP_NAME 20 -#define PROP_PROCID 21 -#define PROP_MSGID 22 -#define PROP_PARSESUCCESS 23 -#define PROP_SYS_NOW 150 -#define PROP_SYS_YEAR 151 -#define PROP_SYS_MONTH 152 -#define PROP_SYS_DAY 153 -#define PROP_SYS_HOUR 154 -#define PROP_SYS_HHOUR 155 -#define PROP_SYS_QHOUR 156 -#define PROP_SYS_MINUTE 157 -#define PROP_SYS_MYHOSTNAME 158 -#define PROP_SYS_BOM 159 -#define PROP_SYS_UPTIME 160 -#define PROP_UUID 161 -#define PROP_CEE 200 -#define PROP_CEE_ALL_JSON 201 -#define PROP_LOCAL_VAR 202 -#define PROP_GLOBAL_VAR 203 - /* The error codes below are orginally "borrowed" from * liblogging. As such, we reserve values up to -2999 @@ -401,7 +355,7 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth RS_RET_RULESET_EXISTS = -2306,/**< ruleset already exists */ RS_RET_DEPRECATED = -2307,/**< deprecated functionality is used */ RS_RET_DS_PROP_SEQ_ERR = -2308,/**< property sequence error deserializing object */ - RS_RET_TPL_INVLD_PROP = -2309,/**< property name error in template (unknown name) */ + RS_RET_INVLD_PROP = -2309,/**< property name error (unknown name) */ RS_RET_NO_RULEBASE = -2310,/**< mmnormalize: rulebase can not be found or otherwise invalid */ RS_RET_INVLD_MODE = -2311,/**< invalid mode specified in configuration */ RS_RET_INVLD_ANON_BITS = -2312,/**< mmanon: invalid number of bits to anonymize specified */ diff --git a/runtime/ruleset.c b/runtime/ruleset.c index 9c7550c6..b7055eac 100644 --- a/runtime/ruleset.c +++ b/runtime/ruleset.c @@ -392,11 +392,10 @@ evalPROPFILT(struct cnfstmt *stmt, msg_t *pMsg) int bRet = 0; rs_size_t propLen; - if(stmt->d.s_propfilt.propID == PROP_INVALID) + if(stmt->d.s_propfilt.prop.id == PROP_INVALID) goto done; - pszPropVal = MsgGetProp(pMsg, NULL, stmt->d.s_propfilt.propID, - stmt->d.s_propfilt.propName, stmt->d.s_propfilt.propNameLen, + pszPropVal = MsgGetProp(pMsg, NULL, &stmt->d.s_propfilt.prop, &propLen, &pbMustBeFreed, NULL); /* Now do the compares (short list currently ;)) */ @@ -441,18 +440,18 @@ evalPROPFILT(struct cnfstmt *stmt, msg_t *pMsg) bRet = (bRet == 1) ? 0 : 1; if(Debug) { - if(stmt->d.s_propfilt.propID == PROP_CEE) { + if(stmt->d.s_propfilt.prop.id == PROP_CEE) { DBGPRINTF("Filter: check for CEE property '%s' (value '%s') ", - stmt->d.s_propfilt.propName, pszPropVal); - } else if(stmt->d.s_propfilt.propID == PROP_LOCAL_VAR) { + stmt->d.s_propfilt.prop.name, pszPropVal); + } else if(stmt->d.s_propfilt.prop.id == PROP_LOCAL_VAR) { DBGPRINTF("Filter: check for local var '%s' (value '%s') ", - stmt->d.s_propfilt.propName, pszPropVal); - } else if(stmt->d.s_propfilt.propID == PROP_GLOBAL_VAR) { - DBGPRINTF("Filter: check for global var '%s' (value '%s') ", - stmt->d.s_propfilt.propName, pszPropVal); + stmt->d.s_propfilt.prop.name, pszPropVal); + //} else if(stmt->d.s_propfilt.propID == PROP_GLOBAL_VAR) { + //DBGPRINTF("Filter: check for global var '%s' (value '%s') ", + //stmt->d.s_propfilt.propName, pszPropVal); } else { DBGPRINTF("Filter: check for property '%s' (value '%s') ", - propIDToName(stmt->d.s_propfilt.propID), pszPropVal); + propIDToName(stmt->d.s_propfilt.prop.id), pszPropVal); } if(stmt->d.s_propfilt.isNegated) DBGPRINTF("NOT "); diff --git a/runtime/ruleset.h b/runtime/ruleset.h index cbf8243b..8bfd4920 100644 --- a/runtime/ruleset.h +++ b/runtime/ruleset.h @@ -2,7 +2,7 @@ * * This implements rulesets within rsyslog. * - * Copyright 2009-2012 Rainer Gerhards and Adiscon GmbH. + * Copyright 2009-2013 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * diff --git a/runtime/typedefs.h b/runtime/typedefs.h index a929b30c..22fc23d8 100644 --- a/runtime/typedefs.h +++ b/runtime/typedefs.h @@ -64,6 +64,7 @@ typedef struct nsdsel_ptcp_s nsdsel_ptcp_t; typedef struct nsdsel_gtls_s nsdsel_gtls_t; typedef struct nsdpoll_ptcp_s nsdpoll_ptcp_t; typedef struct wti_s wti_t; +typedef struct msgPropDescr_s msgPropDescr_t; typedef struct msg msg_t; typedef struct queue_s qqueue_t; typedef struct prop_s prop_t; @@ -163,6 +164,52 @@ typedef enum { typedef off_t off64_t; #endif + +/* properties are now encoded as (tiny) integers. I do not use an enum as I would like + * to keep the memory footprint small (and thus cache hits high). + * rgerhards, 2009-06-26 + */ +typedef uintTiny propid_t; +#define PROP_INVALID 0 +#define PROP_MSG 1 +#define PROP_TIMESTAMP 2 +#define PROP_HOSTNAME 3 +#define PROP_SYSLOGTAG 4 +#define PROP_RAWMSG 5 +#define PROP_INPUTNAME 6 +#define PROP_FROMHOST 7 +#define PROP_FROMHOST_IP 8 +#define PROP_PRI 9 +#define PROP_PRI_TEXT 10 +#define PROP_IUT 11 +#define PROP_SYSLOGFACILITY 12 +#define PROP_SYSLOGFACILITY_TEXT 13 +#define PROP_SYSLOGSEVERITY 14 +#define PROP_SYSLOGSEVERITY_TEXT 15 +#define PROP_TIMEGENERATED 16 +#define PROP_PROGRAMNAME 17 +#define PROP_PROTOCOL_VERSION 18 +#define PROP_STRUCTURED_DATA 19 +#define PROP_APP_NAME 20 +#define PROP_PROCID 21 +#define PROP_MSGID 22 +#define PROP_PARSESUCCESS 23 +#define PROP_SYS_NOW 150 +#define PROP_SYS_YEAR 151 +#define PROP_SYS_MONTH 152 +#define PROP_SYS_DAY 153 +#define PROP_SYS_HOUR 154 +#define PROP_SYS_HHOUR 155 +#define PROP_SYS_QHOUR 156 +#define PROP_SYS_MINUTE 157 +#define PROP_SYS_MYHOSTNAME 158 +#define PROP_SYS_BOM 159 +#define PROP_SYS_UPTIME 160 +#define PROP_UUID 161 +#define PROP_CEE 200 +#define PROP_CEE_ALL_JSON 201 +#define PROP_LOCAL_VAR 202 + /* types of configuration handlers */ typedef enum cslCmdHdlrType { @@ -213,6 +260,13 @@ struct multi_submit_s { msg_t **ppMsgs; }; +/* the following structure is a helper to describe a message property */ +struct msgPropDescr_s { + propid_t id; + uchar *name; /* name and lenName are only set for dynamic */ + int nameLen; /* properties (JSON) */ +}; + #endif /* multi-include protection */ /* vim:set ai: */ @@ -1,7 +1,7 @@ /* This is the template processing code of rsyslog. * begun 2004-11-17 rgerhards * - * Copyright 2004-2012 Rainer Gerhards and Adiscon + * Copyright 2004-2013 Rainer Gerhards and Adiscon * * This file is part of rsyslog. * @@ -193,8 +193,7 @@ tplToString(struct template *pTpl, msg_t *pMsg, uchar **ppBuf, size_t *pLenBuf, iLenVal = pTpe->data.constant.iLenConstant; bMustBeFreed = 0; } else if(pTpe->eEntryType == FIELD) { - pVal = (uchar*) MsgGetProp(pMsg, pTpe, pTpe->data.field.propid, - pTpe->data.field.propName, pTpe->data.field.propNameLen, + pVal = (uchar*) MsgGetProp(pMsg, pTpe, &pTpe->data.field.msgProp, &iLenVal, &bMustBeFreed, ttNow); /* we now need to check if we should use SQL option. In this case, * we must go over the generated string and escape '\'' characters. @@ -290,8 +289,7 @@ tplToArray(struct template *pTpl, msg_t *pMsg, uchar*** ppArr, struct syslogTime if(pTpe->eEntryType == CONSTANT) { CHKmalloc(pArr[iArr] = (uchar*)strdup((char*) pTpe->data.constant.pConstant)); } else if(pTpe->eEntryType == FIELD) { - pVal = (uchar*) MsgGetProp(pMsg, pTpe, pTpe->data.field.propid, - pTpe->data.field.propName, pTpe->data.field.propNameLen, + pVal = (uchar*) MsgGetProp(pMsg, pTpe, &pTpe->data.field.msgProp, &propLen, &bMustBeFreed, ttNow); if(bMustBeFreed) { /* if it must be freed, it is our own private copy... */ pArr[iArr] = pVal; /* ... so we can use it! */ @@ -345,8 +343,8 @@ tplToJSON(struct template *pTpl, msg_t *pMsg, struct json_object **pjson, struct jsonf = json_object_new_string((char*) pTpe->data.constant.pConstant); json_object_object_add(json, (char*)pTpe->fieldName, jsonf); } else if(pTpe->eEntryType == FIELD) { - if(pTpe->data.field.propid == PROP_CEE) { - localRet = msgGetCEEPropJSON(pMsg, pTpe->data.field.propName, pTpe->data.field.propNameLen, &jsonf); + if(pTpe->data.field.msgProp.id == PROP_CEE) { + localRet = msgGetCEEPropJSON(pMsg, pTpe->data.field.msgProp.name, pTpe->data.field.msgProp.nameLen, &jsonf); if(localRet == RS_RET_OK) { json_object_object_add(json, (char*)pTpe->fieldName, json_object_get(jsonf)); } else { @@ -356,8 +354,8 @@ tplToJSON(struct template *pTpl, msg_t *pMsg, struct json_object **pjson, struct json_object_object_add(json, (char*)pTpe->fieldName, NULL); } } - } else if(pTpe->data.field.propid == PROP_LOCAL_VAR) { - localRet = msgGetLocalVarJSON(pMsg, pTpe->data.field.propName, pTpe->data.field.propNameLen, &jsonf); + } else if(pTpe->data.field.msgProp.id == PROP_LOCAL_VAR) { + localRet = msgGetLocalVarJSON(pMsg, pTpe->data.field.msgProp.name, pTpe->data.field.msgProp.nameLen, &jsonf); if(localRet == RS_RET_OK) { json_object_object_add(json, (char*)pTpe->fieldName, json_object_get(jsonf)); } else { @@ -367,8 +365,9 @@ tplToJSON(struct template *pTpl, msg_t *pMsg, struct json_object **pjson, struct json_object_object_add(json, (char*)pTpe->fieldName, NULL); } } - } else if(pTpe->data.field.propid == PROP_GLOBAL_VAR) { - localRet = msgGetGlobalVarJSON(pTpe->data.field.propName, pTpe->data.field.propNameLen, &jsonf); +#if 0 /* do not remove this code *for the moment* -- rgerhards, 2013-10-22 */ + } else if(pTpe->data.field.msgProp.id == PROP_GLOBAL_VAR) { + localRet = msgGetGlobalVarJSON(pTpe->data.field.msgProp.name, pTpe->data.field.msgProp.nameLen, &jsonf); if(localRet == RS_RET_OK) { json_object_object_add(json, (char*)pTpe->fieldName, json_object_get(jsonf)); } else { @@ -378,11 +377,10 @@ tplToJSON(struct template *pTpl, msg_t *pMsg, struct json_object **pjson, struct json_object_object_add(json, (char*)pTpe->fieldName, NULL); } } +#endif } else { - pVal = (uchar*) MsgGetProp(pMsg, pTpe, pTpe->data.field.propid, - pTpe->data.field.propName, - pTpe->data.field.propNameLen, &propLen, - &bMustBeFreed, ttNow); + pVal = (uchar*) MsgGetProp(pMsg, pTpe, &pTpe->data.field.msgProp, + &propLen, &bMustBeFreed, ttNow); if(pTpe->data.field.options.bMandatory || propLen > 0) { jsonf = json_object_new_string_len((char*)pVal, propLen); json_object_object_add(json, (char*)pTpe->fieldName, jsonf); @@ -809,21 +807,8 @@ do_Parameter(uchar **pp, struct template *pTpl) /* got the name */ cstrFinalize(pStrProp); - if(propNameToID(cstrGetSzStrNoNULL(pStrProp), &pTpe->data.field.propid) != RS_RET_OK) { - errmsg.LogError(0, RS_RET_TPL_INVLD_PROP, "template '%s': invalid parameter '%s'", - pTpl->pszName, cstrGetSzStrNoNULL(pStrProp)); - cstrDestruct(&pStrProp); - ABORT_FINALIZE(RS_RET_TPL_INVLD_PROP); - } - if(pTpe->data.field.propid == PROP_CEE || - pTpe->data.field.propid == PROP_LOCAL_VAR || - pTpe->data.field.propid == PROP_GLOBAL_VAR) { - /* in these cases, we need the field name for later processing */ - pTpe->data.field.propName = ustrdup(cstrGetSzStrNoNULL(pStrProp)+1); - pTpe->data.field.propNameLen = cstrLen(pStrProp)-1; - pTpe->data.field.propName[0] = '!'; /* patch root name */ -#warning do we really need to patch root name? - } + CHKiRet(msgPropDescrFill(&pTpe->data.field.msgProp, cstrGetSzStrNoNULL(pStrProp), + cstrLen(pStrProp))); /* Check frompos, if it has an R, then topos should be a regex */ if(*p == ':') { @@ -1120,8 +1105,7 @@ do_Parameter(uchar **pp, struct template *pTpl) /* save field name - if none was given, use the property name instead */ if(pStrField == NULL) { - if(pTpe->data.field.propid == PROP_CEE || pTpe->data.field.propid == PROP_LOCAL_VAR || - pTpe->data.field.propid == PROP_GLOBAL_VAR) { + if(pTpe->data.field.msgProp.id == PROP_CEE || pTpe->data.field.msgProp.id == PROP_LOCAL_VAR) { /* in CEE case, we remove "$!"/"$." from the fieldname - it's just our indicator */ pTpe->fieldName = ustrdup(cstrGetSzStrNoNULL(pStrProp)+2); pTpe->lenFieldName = cstrLen(pStrProp)-2; @@ -1602,15 +1586,8 @@ createPropertyTpe(struct template *pTpl, struct cnfobj *o) /* apply */ CHKmalloc(pTpe = tpeConstruct(pTpl)); pTpe->eEntryType = FIELD; - CHKiRet(propNameToID(cstrGetSzStrNoNULL(name), &pTpe->data.field.propid)); - if(pTpe->data.field.propid == PROP_CEE || - pTpe->data.field.propid == PROP_LOCAL_VAR || - pTpe->data.field.propid == PROP_GLOBAL_VAR) { - /* in these cases, we need the fieldname for later processing */ - pTpe->data.field.propName = ustrdup(cstrGetSzStrNoNULL(name)+1); - pTpe->data.field.propNameLen = cstrLen(name)-1; - pTpe->data.field.propName[0] = '!'; /* patch root name */ - } + CHKiRet(msgPropDescrFill(&pTpe->data.field.msgProp, cstrGetSzStrNoNULL(name), + cstrLen(name))); pTpe->data.field.options.bDropLastLF = droplastlf; pTpe->data.field.options.bSPIffNo1stSP = spifno1stsp; pTpe->data.field.options.bMandatory = mandatory; @@ -1997,8 +1974,8 @@ void tplDeleteAll(rsconf_t *conf) regexp.regfree(&(pTpeDel->data.field.re)); } } - free(pTpeDel->data.field.propName); #endif + msgPropDescrDestruct(&pTpeDel->data.field.msgProp); break; } free(pTpeDel->fieldName); @@ -2055,8 +2032,8 @@ void tplDeleteNew(rsconf_t *conf) regexp.regfree(&(pTpeDel->data.field.re)); } } - free(pTpeDel->data.field.propName); #endif + msgPropDescrDestruct(&pTpeDel->data.field.msgProp); break; } /*dbgprintf("\n");*/ @@ -2107,13 +2084,13 @@ void tplPrintList(rsconf_t *conf) pTpe->data.constant.pConstant); break; case FIELD: - dbgprintf("(FIELD), value: '%d' ", pTpe->data.field.propid); - if(pTpe->data.field.propid == PROP_CEE) { - dbgprintf("[EE-Property: '%s'] ", pTpe->data.field.propName); - } else if(pTpe->data.field.propid == PROP_LOCAL_VAR) { - dbgprintf("[Local Var: '%s'] ", pTpe->data.field.propName); - } else if(pTpe->data.field.propid == PROP_GLOBAL_VAR) { - dbgprintf("[Global Var: '%s'] ", pTpe->data.field.propName); + dbgprintf("(FIELD), value: '%d' ", pTpe->data.field.msgProp.id); + if(pTpe->data.field.msgProp.id == PROP_CEE) { + dbgprintf("[EE-Property: '%s'] ", pTpe->data.field.msgProp.name); + } else if(pTpe->data.field.msgProp.id == PROP_LOCAL_VAR) { + dbgprintf("[Local Var: '%s'] ", pTpe->data.field.msgProp.name); + //} else if(pTpe->data.field.propid == PROP_GLOBAL_VAR) { + // dbgprintf("[Global Var: '%s'] ", pTpe->data.field.propName); } switch(pTpe->data.field.eDateFormat) { case tplFmtDefault: @@ -80,7 +80,7 @@ struct templateEntry { int iLenConstant; /* its length */ } constant; struct { - propid_t propid; /* property to be used */ + msgPropDescr_t msgProp; /* property to be used */ unsigned iFromPos; /* for partial strings only chars from this position ... */ unsigned iToPos; /* up to that one... */ unsigned iFieldNr; /* for field extraction: field to extract */ @@ -104,8 +104,6 @@ struct templateEntry { int field_expand; /* use multiple instances of the field delimiter as a single one? */ #endif - uchar *propName; - int propNameLen; enum tplFormatTypes eDateFormat; enum tplFormatCaseConvTypes eCaseConv; |