|
Packit |
1422b7 |
/**
|
|
Packit |
1422b7 |
* @file annot.c
|
|
Packit |
1422b7 |
* @brief Implementation of the annotation set object.
|
|
Packit |
1422b7 |
* @class ln_annot annot.h
|
|
Packit |
1422b7 |
*//*
|
|
Packit |
1422b7 |
* Copyright 2011 by Rainer Gerhards and Adiscon GmbH.
|
|
Packit |
1422b7 |
*
|
|
Packit |
1422b7 |
* Modified by Pavel Levshin (pavel@levshin.spb.ru) in 2013
|
|
Packit |
1422b7 |
*
|
|
Packit |
1422b7 |
* This file is part of liblognorm.
|
|
Packit |
1422b7 |
*
|
|
Packit |
1422b7 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
1422b7 |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
1422b7 |
* License as published by the Free Software Foundation; either
|
|
Packit |
1422b7 |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
1422b7 |
*
|
|
Packit |
1422b7 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
1422b7 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
1422b7 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
1422b7 |
* Lesser General Public License for more details.
|
|
Packit |
1422b7 |
*
|
|
Packit |
1422b7 |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
1422b7 |
* License along with this library; if not, write to the Free Software
|
|
Packit |
1422b7 |
* Foundation, Inc., 51 Franklin Sannott, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
1422b7 |
*
|
|
Packit |
1422b7 |
* A copy of the LGPL v2.1 can be found in the file "COPYING" in this distribution.
|
|
Packit |
1422b7 |
*/
|
|
Packit |
1422b7 |
#include "config.h"
|
|
Packit |
1422b7 |
#include <stdlib.h>
|
|
Packit |
1422b7 |
#include <stdio.h>
|
|
Packit |
1422b7 |
#include <stdarg.h>
|
|
Packit |
1422b7 |
#include <string.h>
|
|
Packit |
1422b7 |
#include <assert.h>
|
|
Packit |
1422b7 |
#include <ctype.h>
|
|
Packit |
1422b7 |
#include <libestr.h>
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
#include "lognorm.h"
|
|
Packit |
1422b7 |
#include "samp.h"
|
|
Packit |
1422b7 |
#include "annot.h"
|
|
Packit |
1422b7 |
#include "internal.h"
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
ln_annotSet*
|
|
Packit |
1422b7 |
ln_newAnnotSet(ln_ctx ctx)
|
|
Packit |
1422b7 |
{
|
|
Packit |
1422b7 |
ln_annotSet *as;
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
if((as = calloc(1, sizeof(struct ln_annotSet_s))) == NULL)
|
|
Packit |
1422b7 |
goto done;
|
|
Packit |
1422b7 |
as->ctx = ctx;
|
|
Packit |
1422b7 |
done: return as;
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
void
|
|
Packit |
1422b7 |
ln_deleteAnnotSet(ln_annotSet *as)
|
|
Packit |
1422b7 |
{
|
|
Packit |
1422b7 |
ln_annot *node, *nextnode;
|
|
Packit |
1422b7 |
if(as == NULL)
|
|
Packit |
1422b7 |
goto done;
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
for(node = as->aroot; node != NULL; node = nextnode) {
|
|
Packit |
1422b7 |
nextnode = node->next;
|
|
Packit |
1422b7 |
ln_deleteAnnot(node);
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
free(as);
|
|
Packit |
1422b7 |
done: return;
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
ln_annot*
|
|
Packit |
1422b7 |
ln_findAnnot(ln_annotSet *as, es_str_t *tag)
|
|
Packit |
1422b7 |
{
|
|
Packit |
1422b7 |
ln_annot *annot;
|
|
Packit |
1422b7 |
if(as == NULL) {
|
|
Packit |
1422b7 |
annot = NULL;
|
|
Packit |
1422b7 |
goto done;
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
for( annot = as->aroot
|
|
Packit |
1422b7 |
; annot != NULL && es_strcmp(annot->tag, tag)
|
|
Packit |
1422b7 |
; annot = annot->next) {
|
|
Packit |
1422b7 |
; /* do nothing, just search... */
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
done: return annot;
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
/**
|
|
Packit |
1422b7 |
* Combine two annotations.
|
|
Packit |
1422b7 |
* @param[in] annot currently existing and surviving annotation
|
|
Packit |
1422b7 |
* @param[in] add annotation to be added. This will be destructed
|
|
Packit |
1422b7 |
* as part of the process.
|
|
Packit |
1422b7 |
* @returns 0 if ok, something else otherwise
|
|
Packit |
1422b7 |
*/
|
|
Packit |
1422b7 |
static int
|
|
Packit |
1422b7 |
ln_combineAnnot(ln_annot *annot, ln_annot *add)
|
|
Packit |
1422b7 |
{
|
|
Packit |
1422b7 |
int r = 0;
|
|
Packit |
1422b7 |
ln_annot_op *op, *nextop;
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
for(op = add->oproot; op != NULL; op = nextop) {
|
|
Packit |
1422b7 |
CHKR(ln_addAnnotOp(annot, op->opc, op->name, op->value));
|
|
Packit |
1422b7 |
nextop = op->next;
|
|
Packit |
1422b7 |
free(op);
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
es_deleteStr(add->tag);
|
|
Packit |
1422b7 |
free(add);
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
done: return r;
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
int
|
|
Packit |
1422b7 |
ln_addAnnotToSet(ln_annotSet *as, ln_annot *annot)
|
|
Packit |
1422b7 |
{
|
|
Packit |
1422b7 |
int r = 0;
|
|
Packit |
1422b7 |
ln_annot *aexist;
|
|
Packit |
1422b7 |
assert(annot->tag != NULL);
|
|
Packit |
1422b7 |
aexist = ln_findAnnot(as, annot->tag);
|
|
Packit |
1422b7 |
if(aexist == NULL) {
|
|
Packit |
1422b7 |
/* does not yet exist, simply store new annot */
|
|
Packit |
1422b7 |
annot->next = as->aroot;
|
|
Packit |
1422b7 |
as->aroot = annot;
|
|
Packit |
1422b7 |
} else { /* annotation already exists, combine */
|
|
Packit |
1422b7 |
r = ln_combineAnnot(aexist, annot);
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
return r;
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
ln_annot*
|
|
Packit |
1422b7 |
ln_newAnnot(es_str_t *tag)
|
|
Packit |
1422b7 |
{
|
|
Packit |
1422b7 |
ln_annot *annot;
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
if((annot = calloc(1, sizeof(struct ln_annot_s))) == NULL)
|
|
Packit |
1422b7 |
goto done;
|
|
Packit |
1422b7 |
annot->tag = tag;
|
|
Packit |
1422b7 |
done: return annot;
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
void
|
|
Packit |
1422b7 |
ln_deleteAnnot(ln_annot *annot)
|
|
Packit |
1422b7 |
{
|
|
Packit |
1422b7 |
ln_annot_op *op, *nextop;
|
|
Packit |
1422b7 |
if(annot == NULL)
|
|
Packit |
1422b7 |
goto done;
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
es_deleteStr(annot->tag);
|
|
Packit |
1422b7 |
for(op = annot->oproot; op != NULL; op = nextop) {
|
|
Packit |
1422b7 |
es_deleteStr(op->name);
|
|
Packit |
1422b7 |
if(op->value != NULL)
|
|
Packit |
1422b7 |
es_deleteStr(op->value);
|
|
Packit |
1422b7 |
nextop = op->next;
|
|
Packit |
1422b7 |
free(op);
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
free(annot);
|
|
Packit |
1422b7 |
done: return;
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
int
|
|
Packit |
1422b7 |
ln_addAnnotOp(ln_annot *annot, ln_annot_opcode opc, es_str_t *name, es_str_t *value)
|
|
Packit |
1422b7 |
{
|
|
Packit |
1422b7 |
int r = -1;
|
|
Packit |
1422b7 |
ln_annot_op *node;
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
if((node = calloc(1, sizeof(struct ln_annot_op_s))) == NULL)
|
|
Packit |
1422b7 |
goto done;
|
|
Packit |
1422b7 |
node->opc = opc;
|
|
Packit |
1422b7 |
node->name = name;
|
|
Packit |
1422b7 |
node->value = value;
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
if(annot->oproot != NULL) {
|
|
Packit |
1422b7 |
node->next = annot->oproot;
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
annot->oproot = node;
|
|
Packit |
1422b7 |
r = 0;
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
done: return r;
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
/* annotate the event with a specific tag. helper to keep code
|
|
Packit |
1422b7 |
* small and easy to follow.
|
|
Packit |
1422b7 |
*/
|
|
Packit |
1422b7 |
static inline int
|
|
Packit |
1422b7 |
ln_annotateEventWithTag(ln_ctx ctx, struct json_object *json, es_str_t *tag)
|
|
Packit |
1422b7 |
{
|
|
Packit |
1422b7 |
int r=0;
|
|
Packit |
1422b7 |
ln_annot *annot;
|
|
Packit |
1422b7 |
ln_annot_op *op;
|
|
Packit |
1422b7 |
struct json_object *field;
|
|
Packit |
1422b7 |
char *cstr;
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
if (NULL == (annot = ln_findAnnot(ctx->pas, tag)))
|
|
Packit |
1422b7 |
goto done;
|
|
Packit |
1422b7 |
for(op = annot->oproot ; op != NULL ; op = op->next) {
|
|
Packit |
1422b7 |
if(op->opc == ln_annot_ADD) {
|
|
Packit |
1422b7 |
CHKN(cstr = ln_es_str2cstr(&op->value));
|
|
Packit |
1422b7 |
CHKN(field = json_object_new_string(cstr));
|
|
Packit |
1422b7 |
CHKN(cstr = ln_es_str2cstr(&op->name));
|
|
Packit |
1422b7 |
json_object_object_add(json, cstr, field);
|
|
Packit |
1422b7 |
} else {
|
|
Packit |
1422b7 |
// TODO: implement
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
done: return r;
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
int
|
|
Packit |
1422b7 |
ln_annotate(ln_ctx ctx, struct json_object *json, struct json_object *tagbucket)
|
|
Packit |
1422b7 |
{
|
|
Packit |
1422b7 |
int r = 0;
|
|
Packit |
1422b7 |
es_str_t *tag;
|
|
Packit |
1422b7 |
struct json_object *tagObj;
|
|
Packit |
1422b7 |
const char *tagCstr;
|
|
Packit |
1422b7 |
int i;
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
ln_dbgprintf(ctx, "ln_annotate called [aroot=%p]", ctx->pas->aroot);
|
|
Packit |
1422b7 |
/* shortcut: terminate immediately if nothing to do... */
|
|
Packit |
1422b7 |
if(ctx->pas->aroot == NULL)
|
|
Packit |
1422b7 |
goto done;
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
/* iterate over tagbucket */
|
|
Packit |
1422b7 |
for (i = json_object_array_length(tagbucket) - 1; i >= 0; i--) {
|
|
Packit |
1422b7 |
CHKN(tagObj = json_object_array_get_idx(tagbucket, i));
|
|
Packit |
1422b7 |
CHKN(tagCstr = json_object_get_string(tagObj));
|
|
Packit |
1422b7 |
ln_dbgprintf(ctx, "ln_annotate, current tag %d, cstr %s", i, tagCstr);
|
|
Packit |
1422b7 |
CHKN(tag = es_newStrFromCStr(tagCstr, strlen(tagCstr)));
|
|
Packit |
1422b7 |
CHKR(ln_annotateEventWithTag(ctx, json, tag));
|
|
Packit |
1422b7 |
es_deleteStr(tag);
|
|
Packit |
1422b7 |
}
|
|
Packit |
1422b7 |
|
|
Packit |
1422b7 |
done: return r;
|
|
Packit |
1422b7 |
}
|