summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorMiloslav Trmač <mitr@redhat.com>2012-08-11 09:19:09 +0200
committerMiloslav Trmač <mitr@redhat.com>2012-08-28 10:26:42 +0200
commitf2068e080718f28b98034233ea08b50f3d2ab220 (patch)
tree0c0b875dfcbf09fe963b26054bf5d11d959e2edf /runtime
parentee8e701cddaac8e786f388beff89b57f84a1a346 (diff)
downloadrsyslog-f2068e080718f28b98034233ea08b50f3d2ab220.tar.gz
rsyslog-f2068e080718f28b98034233ea08b50f3d2ab220.tar.xz
rsyslog-f2068e080718f28b98034233ea08b50f3d2ab220.zip
Handle $!all-json in field templates
Let msg.c handle appending fields, which also allows it to append more than one field per replaced property. The result allows supplementing CEE data with other (non-constant) properties, but will currently result in duplicates if $!all-json and the template contain fields with the same names. Signed-off-by: Miloslav Trmač <mitr@redhat.com>
Diffstat (limited to 'runtime')
-rw-r--r--runtime/msg.c73
-rw-r--r--runtime/msg.h8
2 files changed, 81 insertions, 0 deletions
diff --git a/runtime/msg.c b/runtime/msg.c
index 6725203c..0d01f5e1 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -3445,6 +3445,79 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
return(pRes);
}
+rsRetVal FBSensureSpace(struct fieldBuildingState *state)
+{
+ DEFiRet;
+
+ if(state->nextField == state->allocatedFields) {
+ struct templateField *p;
+ size_t newSize;
+
+ newSize = state->allocatedFields * 2 + 4;
+ CHKmalloc(p = realloc(state->fields,
+ newSize * sizeof(*state->fields)));
+ state->fields = p;
+ state->allocatedFields = newSize;
+ }
+
+finalize_it:
+ RETiRet;
+}
+
+/* Append fields designated by PROPID to (pFields, pAllocatedFields,
+ pNextField) */
+rsRetVal MsgAppendFields(msg_t *pMsg, struct templateEntry *pTpe,
+ struct fieldBuildingState *state)
+{
+ DEFiRet;
+ struct templateField *dst;
+ uchar *pVal;
+ size_t propLen;
+ unsigned short bMustBeFreed;
+ struct ee_fieldbucket_listnode *node;
+ struct ee_field *src;
+
+ if(pTpe->data.field.propid == PROP_CEE_ALL_JSON) { /* Special case - multiple fields */
+ if(pMsg->event != NULL && pMsg->event->fields != NULL) {
+ /* FIXME: should there be an libee API allowing enumeration
+ instead of these direct accesses? */
+ for (node = pMsg->event->fields->root; node != NULL;
+ node = node->next) {
+ CHKiRet(FBSensureSpace(state));
+
+ src = node->field;
+ dst = state->fields + state->nextField;
+ dst->fieldName = src->name;
+ if (src->nVals == 0) {
+ CHKmalloc(dst->value = (uchar*)strdup(""));
+ } else {
+ /* FIXME: are there other types to consider? */
+ assert(src->val->valtype == ee_valtype_str);
+ /* FIXME: This corrupts embedded NULs - can we do better? The only current user to consider is mongodb */
+ CHKmalloc(dst->value = (uchar *)es_str2cstr(src->val->val.str, NULL));
+ }
+ state->nextField++;
+ }
+ }
+ } else {
+ CHKiRet(FBSensureSpace(state));
+
+ dst = state->fields + state->nextField;
+ dst->fieldName = pTpe->data.field.fieldName;
+ pVal = MsgGetProp(pMsg, pTpe, pTpe->data.field.propid,
+ pTpe->data.field.propName, &propLen,
+ &bMustBeFreed);
+ if(bMustBeFreed) { /* if it must be freed, it is our own private copy... */
+ dst->value = pVal; /* ... so we can use it! */
+ } else {
+ CHKmalloc(dst->value = (uchar*)strdup((char*)pVal));
+ }
+ state->nextField++;
+ }
+finalize_it:
+ RETiRet;
+}
+
/* The function returns a cee variable suitable for use with RainerScript.
* Note: caller must free the returned string.
diff --git a/runtime/msg.h b/runtime/msg.h
index f6b54a77..345f2a9e 100644
--- a/runtime/msg.h
+++ b/runtime/msg.h
@@ -140,6 +140,11 @@ struct msg {
#define NEEDS_ACLCHK_U 0x080 /* check UDP ACLs after DNS resolution has been done in main queue consumer */
#define NO_PRI_IN_RAW 0x100 /* rawmsg does not include a PRI (Solaris!), but PRI is already set correctly in the msg object */
+struct fieldBuildingState {
+ struct templateField *fields;
+ size_t allocatedFields;
+ size_t nextField;
+};
/* function prototypes
*/
@@ -173,6 +178,9 @@ rsRetVal MsgReplaceMSG(msg_t *pThis, uchar* pszMSG, int lenMSG);
uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe,
propid_t propid, es_str_t *propName,
size_t *pPropLen, unsigned short *pbMustBeFreed);
+rsRetVal FBSensureSpace(struct fieldBuildingState *state);
+rsRetVal MsgAppendFields(msg_t *pMsg, struct templateEntry *pTpe,
+ struct fieldBuildingState *state);
char *textpri(char *pRes, size_t pResLen, int pri);
rsRetVal msgGetMsgVar(msg_t *pThis, cstr_t *pstrPropName, var_t **ppVar);
es_str_t* msgGetMsgVarNew(msg_t *pThis, uchar *name);