Blame src/annot.c

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
}