summaryrefslogtreecommitdiffstats
path: root/runtime/msg.c
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/msg.c
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/msg.c')
-rw-r--r--runtime/msg.c73
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.