diff options
author | Miloslav Trmač <mitr@redhat.com> | 2012-08-11 09:19:09 +0200 |
---|---|---|
committer | Miloslav Trmač <mitr@redhat.com> | 2012-08-28 10:26:42 +0200 |
commit | f2068e080718f28b98034233ea08b50f3d2ab220 (patch) | |
tree | 0c0b875dfcbf09fe963b26054bf5d11d959e2edf /runtime/msg.c | |
parent | ee8e701cddaac8e786f388beff89b57f84a1a346 (diff) | |
download | rsyslog-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/msg.c')
-rw-r--r-- | runtime/msg.c | 73 |
1 files changed, 73 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. |