Blame src/enc_syslog.c

Packit 1422b7
/**
Packit 1422b7
 * @file enc_syslog.c
Packit 1422b7
 * Encoder for syslog format.
Packit 1422b7
 * This file contains code from all related objects that is required in
Packit 1422b7
 * order to encode syslog format. The core idea of putting all of this into
Packit 1422b7
 * a single file is that this makes it very straightforward to write
Packit 1422b7
 * encoders for different encodings, as all is in one place.
Packit 1422b7
 */
Packit 1422b7
/*
Packit 1422b7
 * liblognorm - a fast samples-based log normalization library
Packit 1422b7
 * Copyright 2010-2016 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 Street, 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 <assert.h>
Packit 1422b7
#include <string.h>
Packit 1422b7
Packit 1422b7
#include <libestr.h>
Packit 1422b7
Packit 1422b7
#include "internal.h"
Packit 1422b7
#include "liblognorm.h"
Packit 1422b7
#include "enc.h"
Packit 1422b7
Packit 1422b7
static int
Packit 1422b7
ln_addValue_Syslog(const char *value, es_str_t **str)
Packit 1422b7
{
Packit 1422b7
	int r;
Packit 1422b7
	es_size_t i;
Packit 1422b7
Packit 1422b7
	assert(str != NULL);
Packit 1422b7
	assert(*str != NULL);
Packit 1422b7
	assert(value != NULL);
Packit 1422b7
Packit 1422b7
	for(i = 0; i < strlen(value); i++) {
Packit 1422b7
		switch(value[i]) {
Packit 1422b7
		case '\0':
Packit 1422b7
			es_addChar(str, '\\');
Packit 1422b7
			es_addChar(str, '0');
Packit 1422b7
			break;
Packit 1422b7
		case '\n':
Packit 1422b7
			es_addChar(str, '\\');
Packit 1422b7
			es_addChar(str, 'n');
Packit 1422b7
			break;
Packit 1422b7
		/* TODO : add rest of control characters here... */
Packit 1422b7
		case ',': /* comma is CEE-reserved for lists */
Packit 1422b7
			es_addChar(str, '\\');
Packit 1422b7
			es_addChar(str, ',');
Packit 1422b7
			break;
Packit 1422b7
#if 0 /* alternative encoding for discussion */
Packit 1422b7
		case '^': /* CEE-reserved for lists */
Packit 1422b7
			es_addChar(str, '\\');
Packit 1422b7
			es_addChar(str, '^');
Packit 1422b7
			break;
Packit 1422b7
#endif
Packit 1422b7
		/* at this layer ... do we need to think about transport
Packit 1422b7
		 * encoding at all? Or simply leave it to the transport agent?
Packit 1422b7
		 */
Packit 1422b7
		case '\\': /* RFC5424 reserved */
Packit 1422b7
			es_addChar(str, '\\');
Packit 1422b7
			es_addChar(str, '\\');
Packit 1422b7
			break;
Packit 1422b7
		case ']': /* RFC5424 reserved */
Packit 1422b7
			es_addChar(str, '\\');
Packit 1422b7
			es_addChar(str, ']');
Packit 1422b7
			break;
Packit 1422b7
		case '\"': /* RFC5424 reserved */
Packit 1422b7
			es_addChar(str, '\\');
Packit 1422b7
			es_addChar(str, '\"');
Packit 1422b7
			break;
Packit 1422b7
		default:
Packit 1422b7
			es_addChar(str, value[i]);
Packit 1422b7
			break;
Packit 1422b7
		}
Packit 1422b7
	}
Packit 1422b7
	r = 0;
Packit 1422b7
Packit 1422b7
	return r;
Packit 1422b7
}
Packit 1422b7
Packit 1422b7
Packit 1422b7
static int
Packit 1422b7
ln_addField_Syslog(char *name, struct json_object *field, es_str_t **str)
Packit 1422b7
{
Packit 1422b7
	int r;
Packit 1422b7
	const char *value;
Packit 1422b7
	int needComma = 0;
Packit 1422b7
	struct json_object *obj;
Packit 1422b7
	int i;
Packit 1422b7
Packit 1422b7
	assert(field != NULL);
Packit 1422b7
	assert(str != NULL);
Packit 1422b7
	assert(*str != NULL);
Packit 1422b7
Packit 1422b7
	CHKR(es_addBuf(str, name, strlen(name)));
Packit 1422b7
	CHKR(es_addBuf(str, "=\"", 2));
Packit 1422b7
	switch(json_object_get_type(field)) {
Packit 1422b7
	case json_type_array:
Packit 1422b7
		for (i = json_object_array_length(field) - 1; i >= 0; i--) {
Packit 1422b7
			if(needComma)
Packit 1422b7
				es_addChar(str, ',');
Packit 1422b7
			else
Packit 1422b7
				needComma = 1;
Packit 1422b7
			CHKN(obj = json_object_array_get_idx(field, i));
Packit 1422b7
			CHKN(value = json_object_get_string(obj));
Packit 1422b7
			CHKR(ln_addValue_Syslog(value, str));
Packit 1422b7
		}
Packit 1422b7
		break;
Packit 1422b7
	case json_type_string:
Packit 1422b7
	case json_type_int:
Packit 1422b7
		CHKN(value = json_object_get_string(field));
Packit 1422b7
		CHKR(ln_addValue_Syslog(value, str));
Packit 1422b7
		break;
Packit 1422b7
	case json_type_null:
Packit 1422b7
	case json_type_boolean:
Packit 1422b7
	case json_type_double:
Packit 1422b7
	case json_type_object:
Packit 1422b7
		CHKR(es_addBuf(str, "***unsupported type***", sizeof("***unsupported type***")-1));
Packit 1422b7
		break;
Packit 1422b7
	default:
Packit 1422b7
		CHKR(es_addBuf(str, "***OBJECT***", sizeof("***OBJECT***")-1));
Packit 1422b7
	}
Packit 1422b7
	CHKR(es_addChar(str, '\"'));
Packit 1422b7
	r = 0;
Packit 1422b7
Packit 1422b7
done:
Packit 1422b7
	return r;
Packit 1422b7
}
Packit 1422b7
Packit 1422b7
Packit 1422b7
static inline int
Packit 1422b7
ln_addTags_Syslog(struct json_object *taglist, es_str_t **str)
Packit 1422b7
{
Packit 1422b7
	int r = 0;
Packit 1422b7
	struct json_object *tagObj;
Packit 1422b7
	int needComma = 0;
Packit 1422b7
	const char *tagCstr;
Packit 1422b7
	int i;
Packit 1422b7
Packit 1422b7
	assert(json_object_is_type(taglist, json_type_array));
Packit 1422b7
Packit 1422b7
	CHKR(es_addBuf(str, " event.tags=\"", 13));
Packit 1422b7
	for (i = json_object_array_length(taglist) - 1; i >= 0; i--) {
Packit 1422b7
		if(needComma)
Packit 1422b7
			es_addChar(str, ',');
Packit 1422b7
		else
Packit 1422b7
			needComma = 1;
Packit 1422b7
		CHKN(tagObj = json_object_array_get_idx(taglist, i));
Packit 1422b7
		CHKN(tagCstr = json_object_get_string(tagObj));
Packit 1422b7
		CHKR(es_addBuf(str, (char*)tagCstr, strlen(tagCstr)));
Packit 1422b7
	}
Packit 1422b7
	es_addChar(str, '"');
Packit 1422b7
Packit 1422b7
done:	return r;
Packit 1422b7
}
Packit 1422b7
Packit 1422b7
Packit 1422b7
int
Packit 1422b7
ln_fmtEventToRFC5424(struct json_object *json, es_str_t **str)
Packit 1422b7
{
Packit 1422b7
	int r = -1;
Packit 1422b7
	struct json_object *tags;
Packit 1422b7
Packit 1422b7
	assert(json != NULL);
Packit 1422b7
	assert(json_object_is_type(json, json_type_object));
Packit 1422b7
	if((*str = es_newStr(256)) == NULL)
Packit 1422b7
		goto done;
Packit 1422b7
Packit 1422b7
	es_addBuf(str, "[cee@115", 8);
Packit 1422b7
Packit 1422b7
	if(json_object_object_get_ex(json, "event.tags", &tags)) {
Packit 1422b7
		CHKR(ln_addTags_Syslog(tags, str));
Packit 1422b7
	}
Packit 1422b7
	struct json_object_iterator it = json_object_iter_begin(json);
Packit 1422b7
	struct json_object_iterator itEnd = json_object_iter_end(json);
Packit 1422b7
	while (!json_object_iter_equal(&it, &itEnd)) {
Packit 1422b7
		char *const name = (char*)json_object_iter_peek_name(&it);
Packit 1422b7
		if (strcmp(name, "event.tags")) {
Packit 1422b7
			es_addChar(str, ' ');
Packit 1422b7
			ln_addField_Syslog(name, json_object_iter_peek_value(&it), str);
Packit 1422b7
		}
Packit 1422b7
		json_object_iter_next(&it);
Packit 1422b7
	}
Packit 1422b7
	es_addChar(str, ']');
Packit 1422b7
Packit 1422b7
done:
Packit 1422b7
	return r;
Packit 1422b7
}