summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2013-10-22 17:55:35 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2013-10-22 17:55:35 +0200
commit7d39740b3d88dbd0432806e5f8da32c49cdb69f1 (patch)
tree452e5e27c13b49c5b1910f70a283e3a533ee1283
parente4e19176298d6ac76c463565fa192c2349731156 (diff)
downloadrsyslog-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.c24
-rw-r--r--grammar/rainerscript.h6
-rw-r--r--plugins/ommongodb/ommongodb.c18
-rw-r--r--runtime/msg.c66
-rw-r--r--runtime/msg.h8
-rw-r--r--runtime/rsyslog.h48
-rw-r--r--runtime/ruleset.c21
-rw-r--r--runtime/ruleset.h2
-rw-r--r--runtime/typedefs.h54
-rw-r--r--template.c77
-rw-r--r--template.h4
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:
*/
diff --git a/template.c b/template.c
index 68aaf86e..8afb01f0 100644
--- a/template.c
+++ b/template.c
@@ -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:
diff --git a/template.h b/template.h
index 5caf5e19..1f612eaf 100644
--- a/template.h
+++ b/template.h
@@ -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;