From f6817709c05561606d930b5b2dacac20a1247620 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Wed, 11 Sep 2019 22:58:15 +0000 Subject: [PATCH 1/5] Update: added initial structure for logging core --- Makefile.am | 2 ++ include/igloo/logcore.h | 54 +++++++++++++++++++++++++++++++++++++++++ include/igloo/types.h | 2 ++ src/logcore.c | 31 +++++++++++++++++++++++ 4 files changed, 89 insertions(+) create mode 100644 include/igloo/logcore.h create mode 100644 src/logcore.c diff --git a/Makefile.am b/Makefile.am index 404e343..3ad7467 100644 --- a/Makefile.am +++ b/Makefile.am @@ -26,6 +26,7 @@ pkginclude_HEADERS = \ include/igloo/filter.h \ include/igloo/objecthandler.h \ include/igloo/logmsg.h \ + include/igloo/logcore.h \ include/igloo/buffer.h \ include/igloo/list.h \ include/igloo/error.h \ @@ -41,6 +42,7 @@ libigloo_la_SOURCES = \ src/filter.c \ src/objecthandler.c \ src/logmsg.c \ + src/logcore.c \ src/buffer.c \ src/list.c \ src/error.c \ diff --git a/include/igloo/logcore.h b/include/igloo/logcore.h new file mode 100644 index 0000000..73fe513 --- /dev/null +++ b/include/igloo/logcore.h @@ -0,0 +1,54 @@ +/* Copyright (C) 2019 Philipp "ph3-der-loewe" Schafft + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _LIBIGLOO__LOGCORE_H_ +#define _LIBIGLOO__LOGCORE_H_ +/** + * @file + * Put a good description of this file here + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "ro.h" +#include "interface.h" + +/* About thread safety: + * This set of functions is thread safe. + */ + +typedef struct { + char *id; + char *filename; + ssize_t recent_limit; + igloo_filter_t *filter; + igloo_objecthandler_t *formater; +} igloo_logcore_output_t; + +int igloo_logcore_configure(igloo_logcore_t *core, ssize_t recent_limit, ssize_t askack_limit, ssize_t output_recent_limit, const igloo_logcore_output_t *outputs, size_t outputs_len); +igloo_list_t * igloo_logcore_get_recent(igloo_logcore_t *core, const igloo_ro_type_t *type, igloo_filter_t *filter, ssize_t limit, const char *id); +igloo_list_t * igloo_logcore_get_askack(igloo_logcore_t *core, const igloo_ro_type_t *type, igloo_filter_t *filter, ssize_t limit); +int igloo_logcore_acknowledge(igloo_logcore_t *core, igloo_ro_t object); + +#ifdef __cplusplus +} +#endif + +#endif /* ! _LIBIGLOO__LOGCORE_H_ */ diff --git a/include/igloo/types.h b/include/igloo/types.h index 52b018a..9ab0dc6 100644 --- a/include/igloo/types.h +++ b/include/igloo/types.h @@ -43,6 +43,7 @@ typedef struct igloo_io_tag igloo_io_t; typedef struct igloo_filter_tag igloo_filter_t; typedef struct igloo_objecthandler_tag igloo_objecthandler_t; typedef struct igloo_logmsg_tag igloo_logmsg_t; +typedef struct igloo_logcore_tag igloo_logcore_t; typedef struct igloo_buffer_tag igloo_buffer_t; typedef struct igloo_list_tag igloo_list_t; @@ -72,6 +73,7 @@ typedef union __attribute__ ((__transparent_union__)) { igloo_RO_TYPE(igloo_filter_t) igloo_RO_TYPE(igloo_objecthandler_t) igloo_RO_TYPE(igloo_logmsg_t) + igloo_RO_TYPE(igloo_logcore_t) igloo_RO_TYPE(igloo_buffer_t) igloo_RO_TYPE(igloo_list_t) igloo_RO_TYPE(igloo_reportxml_t) diff --git a/src/logcore.c b/src/logcore.c new file mode 100644 index 0000000..ffbe93d --- /dev/null +++ b/src/logcore.c @@ -0,0 +1,31 @@ +/* Icecast + * + * This program is distributed under the GNU General Public License, version 2. + * A copy of this license is included with this source. + * + * Copyright 2019, Philipp "ph3-der-loewe" Schafft , + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include "private.h" + +struct igloo_logcore_tag { + igloo_ro_base_t __base; +}; + +static void __free(igloo_ro_t self); + +igloo_RO_PUBLIC_TYPE(igloo_logcore_t, + igloo_RO_TYPEDECL_FREE(__free), + igloo_RO_TYPEDECL_NEW_NOOP() + ); + +static void __free(igloo_ro_t self) +{ + igloo_logcore_t *core = igloo_RO_TO_TYPE(self, igloo_logcore_t); +} From 736180624c1f55d6633950a5344e4ee27318d20f Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Thu, 12 Sep 2019 09:34:15 +0000 Subject: [PATCH 2/5] Feature: Actually implemented logcore --- include/igloo/logcore.h | 5 + src/logcore.c | 353 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 357 insertions(+), 1 deletion(-) diff --git a/include/igloo/logcore.h b/include/igloo/logcore.h index 73fe513..7961cfe 100644 --- a/include/igloo/logcore.h +++ b/include/igloo/logcore.h @@ -34,6 +34,8 @@ extern "C" { * This set of functions is thread safe. */ +igloo_RO_FORWARD_TYPE(igloo_logcore_t); + typedef struct { char *id; char *filename; @@ -42,7 +44,10 @@ typedef struct { igloo_objecthandler_t *formater; } igloo_logcore_output_t; +typedef igloo_ro_t (*igloo_logcore_acknowledge_t)(igloo_logcore_t *core, igloo_ro_t object, void *userdata); + int igloo_logcore_configure(igloo_logcore_t *core, ssize_t recent_limit, ssize_t askack_limit, ssize_t output_recent_limit, const igloo_logcore_output_t *outputs, size_t outputs_len); +int igloo_logcore_set_acknowledge_cb(igloo_logcore_t *core, igloo_logcore_acknowledge_t callback, void *userdata); igloo_list_t * igloo_logcore_get_recent(igloo_logcore_t *core, const igloo_ro_type_t *type, igloo_filter_t *filter, ssize_t limit, const char *id); igloo_list_t * igloo_logcore_get_askack(igloo_logcore_t *core, const igloo_ro_type_t *type, igloo_filter_t *filter, ssize_t limit); int igloo_logcore_acknowledge(igloo_logcore_t *core, igloo_ro_t object); diff --git a/src/logcore.c b/src/logcore.c index ffbe93d..feb04fc 100644 --- a/src/logcore.c +++ b/src/logcore.c @@ -10,22 +10,373 @@ #include #endif +#include +#include + #include #include +#include +#include +#include +#include +#include #include "private.h" struct igloo_logcore_tag { igloo_ro_base_t __base; + + igloo_rwlock_t rwlock; + + igloo_list_t *global_recent; + igloo_list_t *global_askack; + size_t output_length; + igloo_logcore_output_t *output; + igloo_list_t **output_recent; + igloo_logcore_acknowledge_t acknowledge_cb; + void *acknowledge_cb_userdata; }; +static int __new(igloo_ro_t self, const igloo_ro_type_t *type, va_list ap); static void __free(igloo_ro_t self); +static igloo_ro_t __get_interface_t(igloo_ro_t self, const igloo_ro_type_t *type, const char *name, igloo_ro_t associated, igloo_ro_t instance); igloo_RO_PUBLIC_TYPE(igloo_logcore_t, igloo_RO_TYPEDECL_FREE(__free), - igloo_RO_TYPEDECL_NEW_NOOP() + igloo_RO_TYPEDECL_NEW(__new), + igloo_RO_TYPEDECL_GET_INTERFACE(__get_interface_t) ); +static int __copy_output(igloo_logcore_output_t *dst, const igloo_logcore_output_t *src) +{ + memset(dst, 0, sizeof(*dst)); + if (src->id) + dst->id = strdup(src->id); + if (src->filename) + dst->filename = strdup(src->filename); + dst->recent_limit = src->recent_limit; + igloo_ro_ref(dst->filter = src->filter); + igloo_ro_ref(dst->formater = src->formater); + + return 0; +} + +static void __free_output(igloo_logcore_output_t *output) +{ + free(output->id); + free(output->filename); + igloo_ro_unref(output->filter); + igloo_objecthandler_flush(output->formater); + igloo_ro_unref(output->formater); + memset(output, 0, sizeof(*output)); +} + +static void __free_locked(igloo_logcore_t *core) +{ + size_t i; + + igloo_ro_unref(core->global_recent); + core->global_recent = NULL; + igloo_ro_unref(core->global_askack); + core->global_askack = NULL; + + for (i = 0; i < core->output_length; i++) { + igloo_ro_unref(core->output_recent[i]); + __free_output(&(core->output[i])); + } + + free(core->output); + core->output = NULL; + free(core->output_recent); + core->output_recent = NULL; +} + +static int __new(igloo_ro_t self, const igloo_ro_type_t *type, va_list ap) +{ + igloo_logcore_t *core = igloo_RO_TO_TYPE(self, igloo_logcore_t); + + igloo_thread_rwlock_create(&(core->rwlock)); + + return 0; +} + static void __free(igloo_ro_t self) { igloo_logcore_t *core = igloo_RO_TO_TYPE(self, igloo_logcore_t); + igloo_thread_rwlock_wlock(&(core->rwlock)); + __free_locked(core); + igloo_thread_rwlock_unlock(&(core->rwlock)); + igloo_thread_rwlock_destroy(&(core->rwlock)); +} + +static igloo_filter_result_t __push_msg(igloo_logcore_t *core, igloo_ro_t msg, int allow_askack) +{ + igloo_filter_result_t ret = igloo_FILTER_RESULT_DROP; + igloo_logmsg_t *logmsg; + size_t i; + + for (i = 0; i < core->output_length; i++) { + igloo_filter_result_t push = igloo_FILTER_RESULT_PASS; + + if (core->output[i].filter) + push = igloo_filter_test(core->output[i].filter, msg); + + if (push == igloo_FILTER_RESULT_PASS) + push = igloo_objecthandler_handle(core->output[i].formater, msg); + + igloo_list_push(core->output_recent[i], msg); + + if (push == igloo_FILTER_RESULT_PASS) + ret = push; + } + + if (ret == igloo_FILTER_RESULT_PASS) + igloo_list_push(core->global_recent, msg); + + logmsg = igloo_RO_TO_TYPE(msg, igloo_logmsg_t); + if (logmsg) { + igloo_logmsg_opt_t opts = igloo_LOGMSG_OPT_NONE; + + if (igloo_logmsg_get_extra(logmsg, &opts, NULL) == 0) { + if (opts & igloo_LOGMSG_OPT_ASKACK) + igloo_list_push(core->global_askack, msg); + } + } + + return ret; +} + +int igloo_logcore_configure(igloo_logcore_t *core, ssize_t recent_limit, ssize_t askack_limit, ssize_t output_recent_limit, const igloo_logcore_output_t *outputs, size_t outputs_len) +{ + igloo_list_t *global_recent; + igloo_list_t *global_askack; + igloo_logcore_output_t *output; + igloo_list_t **output_recent; + igloo_ro_t instance; + size_t i; + + if (!igloo_RO_IS_VALID(core, igloo_logcore_t)) + return -1; + + if (outputs_len < 1 && !outputs) + return -1; + + if (recent_limit < 0) + recent_limit = 128; + + if (askack_limit < 0) + askack_limit = 128; + + if (output_recent_limit < 0) + output_recent_limit = 128; + + instance = igloo_ro_get_instance(core); + + global_recent = igloo_ro_new_ext(igloo_list_t, NULL, igloo_RO_NULL, core); + igloo_list_set_policy(global_recent, igloo_LIST_POLICY_FIXED_PIPE, recent_limit); + + global_askack = igloo_ro_new_ext(igloo_list_t, NULL, igloo_RO_NULL, core); + igloo_list_set_policy(global_askack, igloo_LIST_POLICY_FIXED_PIPE, askack_limit); + + output = calloc(outputs_len, sizeof(*output)); + output_recent = calloc(outputs_len, sizeof(*output_recent)); + + for (i = 0; i < outputs_len; i++) { + igloo_io_t *io; + + __copy_output(&(output[i]), &(outputs[i])); + + if (output[i].recent_limit < 0) + output[i].recent_limit = output_recent_limit; + + if (output[i].filename) { + io = igloo_stdio_new_file(output[i].filename, "ab", NULL, igloo_RO_NULL, instance); + if (io) { + igloo_objecthandler_set_backend(output[i].formater, io); + igloo_ro_unref(io); + } + } + + output_recent[i] = igloo_ro_new_ext(igloo_list_t, NULL, igloo_RO_NULL, core); + igloo_list_set_policy(output_recent[i], igloo_LIST_POLICY_FIXED_PIPE, output[i].recent_limit); + } + + igloo_thread_rwlock_wlock(&(core->rwlock)); + __free_locked(core); + + core->global_recent = global_recent; + core->global_askack = global_askack; + core->output_length = outputs_len; + core->output = output; + core->output_recent = output_recent; + igloo_thread_rwlock_unlock(&(core->rwlock)); + + igloo_ro_unref(instance); + + return 0; +} + +int igloo_logcore_set_acknowledge_cb(igloo_logcore_t *core, igloo_logcore_acknowledge_t callback, void *userdata) +{ + if (!igloo_RO_IS_VALID(core, igloo_logcore_t)) + return -1; + + igloo_thread_rwlock_wlock(&(core->rwlock)); + core->acknowledge_cb = callback; + core->acknowledge_cb_userdata = userdata; + igloo_thread_rwlock_unlock(&(core->rwlock)); + + return 0; +} + +static igloo_list_t *__copy_filtered_list(igloo_list_t *list, const igloo_ro_type_t *type, igloo_filter_t *filter, ssize_t limit) +{ + igloo_list_iterator_storage_t storage; + igloo_list_iterator_t *iterator; + igloo_list_t *ret; + + if (!list) + return NULL; + + iterator = igloo_list_iterator_start(list, &storage, sizeof(storage)); + ret = igloo_ro_new_ext(igloo_list_t, NULL, igloo_RO_NULL, list); + + if (iterator && ret) { + while (limit) { + igloo_ro_t element = igloo_list_iterator_next(iterator); + + if (igloo_RO_IS_NULL(element)) + break; + + if (type == NULL || igloo_RO_GET_TYPE(element) == type) { + if (filter == NULL || igloo_filter_test(filter, element) == igloo_FILTER_RESULT_PASS) { + igloo_list_push(ret, element); + } + } + + igloo_ro_unref(element); + + if (limit > 0) + limit--; + } + } + + igloo_list_iterator_end(iterator); + + return ret; +} + +igloo_list_t * igloo_logcore_get_recent(igloo_logcore_t *core, const igloo_ro_type_t *type, igloo_filter_t *filter, ssize_t limit, const char *id) +{ + igloo_list_t *list = NULL; + igloo_list_t *ret = NULL; + + if (!igloo_RO_IS_VALID(core, igloo_logcore_t)) + return NULL; + + igloo_thread_rwlock_rlock(&(core->rwlock)); + if (id) { + size_t i; + + for (i = 0; i < core->output_length; i++) { + if (core->output[i].id && strcmp(core->output[i].id, id) == 0) { + list = core->output_recent[i]; + } + } + } else { + list = core->global_recent; + } + + ret = __copy_filtered_list(list, type, filter, limit); + igloo_thread_rwlock_unlock(&(core->rwlock)); + + return ret; +} + +igloo_list_t * igloo_logcore_get_askack(igloo_logcore_t *core, const igloo_ro_type_t *type, igloo_filter_t *filter, ssize_t limit) +{ + igloo_list_t *ret = NULL; + + if (!igloo_RO_IS_VALID(core, igloo_logcore_t)) + return NULL; + + igloo_thread_rwlock_rlock(&(core->rwlock)); + ret = __copy_filtered_list(core->global_askack, type, filter, limit); + igloo_thread_rwlock_unlock(&(core->rwlock)); + + return ret; +} + +int igloo_logcore_acknowledge(igloo_logcore_t *core, igloo_ro_t object) +{ + int ret; + + if (!igloo_RO_IS_VALID(core, igloo_logcore_t)) + return -1; + + igloo_thread_rwlock_wlock(&(core->rwlock)); + ret = igloo_list_remove(core->global_askack, object); + + if (ret == 0 && core->acknowledge_cb) { + igloo_ro_t msg = core->acknowledge_cb(core, object, core->acknowledge_cb_userdata); + + if (!igloo_RO_IS_NULL(msg)) { + __push_msg(core, msg, 0); + } + } + + igloo_thread_rwlock_unlock(&(core->rwlock)); + return ret; +} + +static igloo_filter_result_t __handle(igloo_INTERFACE_BASIC_ARGS, igloo_ro_t object) +{ + igloo_logcore_t *core = igloo_RO_TO_TYPE(*backend_object, igloo_logcore_t); + igloo_filter_result_t ret; + + if (!core) + return igloo_FILTER_RESULT_ERROR; + + igloo_thread_rwlock_wlock(&(core->rwlock)); + ret = __push_msg(core, object, 1); + igloo_thread_rwlock_unlock(&(core->rwlock)); + + return ret; +} + +static int __flush(igloo_INTERFACE_BASIC_ARGS) +{ + igloo_logcore_t *core = igloo_RO_TO_TYPE(*backend_object, igloo_logcore_t); + size_t i; + + if (!core) + return -1; + + igloo_thread_rwlock_rlock(&(core->rwlock)); + for (i = 0; i < core->output_length; i++) { + igloo_objecthandler_flush(core->output[i].formater); + } + igloo_thread_rwlock_unlock(&(core->rwlock)); + + return 0; +} + +static const igloo_objecthandler_ifdesc_t igloo_logcore__igloo_objecthandler_ifdesc = { + igloo_INTERFACE_DESCRIPTION_BASE(igloo_objecthandler_ifdesc_t), + .is_thread_safe = 1, + .handle = __handle, + .flush = __flush, + .set_backend = NULL /* No, this is not possible */ +}; + +static igloo_ro_t __get_interface_t(igloo_ro_t self, const igloo_ro_type_t *type, const char *name, igloo_ro_t associated, igloo_ro_t instance) +{ + igloo_logcore_t *core = igloo_RO_TO_TYPE(self, igloo_logcore_t); + + if (!core) + return igloo_RO_NULL; + + if (type != igloo_RO_GET_TYPE_BY_SYMBOL(igloo_objecthandler_t)) + return igloo_RO_NULL; + + return (igloo_ro_t)igloo_objecthandler_new(&igloo_logcore__igloo_objecthandler_ifdesc, core, NULL, name, associated, instance); } From 6e8d127bcbd6d8a2ae4dba790190ead3310f4a33 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Sun, 15 Sep 2019 15:53:37 +0000 Subject: [PATCH 3/5] Feature: Implemented routingclass ALL, ANY, and DEFAULT --- include/igloo/logcore.h | 7 +++++++ src/logcore.c | 38 ++++++++++++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/include/igloo/logcore.h b/include/igloo/logcore.h index 7961cfe..f3ba633 100644 --- a/include/igloo/logcore.h +++ b/include/igloo/logcore.h @@ -36,9 +36,16 @@ extern "C" { igloo_RO_FORWARD_TYPE(igloo_logcore_t); +typedef enum { + igloo_LOGCORE_CLASS_ANY, + igloo_LOGCORE_CLASS_ALL, + igloo_LOGCORE_CLASS_DEFAULT +} igloo_logcore_routingclass_t; + typedef struct { char *id; char *filename; + igloo_logcore_routingclass_t routingclass; ssize_t recent_limit; igloo_filter_t *filter; igloo_objecthandler_t *formater; diff --git a/src/logcore.c b/src/logcore.c index feb04fc..cebe1a0 100644 --- a/src/logcore.c +++ b/src/logcore.c @@ -54,6 +54,7 @@ static int __copy_output(igloo_logcore_output_t *dst, const igloo_logcore_output if (src->filename) dst->filename = strdup(src->filename); dst->recent_limit = src->recent_limit; + dst->routingclass = src->routingclass; igloo_ro_ref(dst->filter = src->filter); igloo_ro_ref(dst->formater = src->formater); @@ -108,15 +109,17 @@ static void __free(igloo_ro_t self) igloo_thread_rwlock_destroy(&(core->rwlock)); } -static igloo_filter_result_t __push_msg(igloo_logcore_t *core, igloo_ro_t msg, int allow_askack) +static igloo_filter_result_t __push_msg__output(igloo_logcore_t *core, igloo_ro_t msg, igloo_logcore_routingclass_t routingclass) { igloo_filter_result_t ret = igloo_FILTER_RESULT_DROP; - igloo_logmsg_t *logmsg; size_t i; for (i = 0; i < core->output_length; i++) { igloo_filter_result_t push = igloo_FILTER_RESULT_PASS; + if (core->output[i].routingclass != routingclass) + continue; + if (core->output[i].filter) push = igloo_filter_test(core->output[i].filter, msg); @@ -125,10 +128,37 @@ static igloo_filter_result_t __push_msg(igloo_logcore_t *core, igloo_ro_t msg, i igloo_list_push(core->output_recent[i], msg); - if (push == igloo_FILTER_RESULT_PASS) - ret = push; + if (push == igloo_FILTER_RESULT_PASS) { + switch (routingclass) { + case igloo_LOGCORE_CLASS_ANY: + case igloo_LOGCORE_CLASS_DEFAULT: + return push; + break; + default: + ret = push; + break; + } + } } + return ret; +} + +static igloo_filter_result_t __push_msg(igloo_logcore_t *core, igloo_ro_t msg, int allow_askack) +{ + igloo_filter_result_t ret = igloo_FILTER_RESULT_DROP; + igloo_filter_result_t res; + igloo_logmsg_t *logmsg; + + ret = __push_msg__output(core, msg, igloo_LOGCORE_CLASS_ANY); + + if (ret != igloo_FILTER_RESULT_PASS) + ret = __push_msg__output(core, msg, igloo_LOGCORE_CLASS_DEFAULT); + + res = __push_msg__output(core, msg, igloo_LOGCORE_CLASS_ALL); + if (res == igloo_FILTER_RESULT_PASS) + ret = igloo_FILTER_RESULT_PASS; + if (ret == igloo_FILTER_RESULT_PASS) igloo_list_push(core->global_recent, msg); From 7845b4a8bf28ff878eff49c8aa053ace6b737323 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Wed, 18 Sep 2019 08:04:50 +0000 Subject: [PATCH 4/5] Update: Migrated logcore to new error API --- include/igloo/logcore.h | 6 +++--- src/logcore.c | 21 +++++++++++---------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/include/igloo/logcore.h b/include/igloo/logcore.h index f3ba633..c32687d 100644 --- a/include/igloo/logcore.h +++ b/include/igloo/logcore.h @@ -53,11 +53,11 @@ typedef struct { typedef igloo_ro_t (*igloo_logcore_acknowledge_t)(igloo_logcore_t *core, igloo_ro_t object, void *userdata); -int igloo_logcore_configure(igloo_logcore_t *core, ssize_t recent_limit, ssize_t askack_limit, ssize_t output_recent_limit, const igloo_logcore_output_t *outputs, size_t outputs_len); -int igloo_logcore_set_acknowledge_cb(igloo_logcore_t *core, igloo_logcore_acknowledge_t callback, void *userdata); +igloo_error_t igloo_logcore_configure(igloo_logcore_t *core, ssize_t recent_limit, ssize_t askack_limit, ssize_t output_recent_limit, const igloo_logcore_output_t *outputs, size_t outputs_len); +igloo_error_t igloo_logcore_set_acknowledge_cb(igloo_logcore_t *core, igloo_logcore_acknowledge_t callback, void *userdata); igloo_list_t * igloo_logcore_get_recent(igloo_logcore_t *core, const igloo_ro_type_t *type, igloo_filter_t *filter, ssize_t limit, const char *id); igloo_list_t * igloo_logcore_get_askack(igloo_logcore_t *core, const igloo_ro_type_t *type, igloo_filter_t *filter, ssize_t limit); -int igloo_logcore_acknowledge(igloo_logcore_t *core, igloo_ro_t object); +igloo_error_t igloo_logcore_acknowledge(igloo_logcore_t *core, igloo_ro_t object); #ifdef __cplusplus } diff --git a/src/logcore.c b/src/logcore.c index cebe1a0..c8e6ec0 100644 --- a/src/logcore.c +++ b/src/logcore.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "private.h" struct igloo_logcore_tag { @@ -175,7 +176,7 @@ static igloo_filter_result_t __push_msg(igloo_logcore_t *core, igloo_ro_t msg, i return ret; } -int igloo_logcore_configure(igloo_logcore_t *core, ssize_t recent_limit, ssize_t askack_limit, ssize_t output_recent_limit, const igloo_logcore_output_t *outputs, size_t outputs_len) +igloo_error_t igloo_logcore_configure(igloo_logcore_t *core, ssize_t recent_limit, ssize_t askack_limit, ssize_t output_recent_limit, const igloo_logcore_output_t *outputs, size_t outputs_len) { igloo_list_t *global_recent; igloo_list_t *global_askack; @@ -185,10 +186,10 @@ int igloo_logcore_configure(igloo_logcore_t *core, ssize_t recent_li size_t i; if (!igloo_RO_IS_VALID(core, igloo_logcore_t)) - return -1; + return igloo_ERROR_FAULT; if (outputs_len < 1 && !outputs) - return -1; + return igloo_ERROR_INVAL; if (recent_limit < 0) recent_limit = 128; @@ -242,20 +243,20 @@ int igloo_logcore_configure(igloo_logcore_t *core, ssize_t recent_li igloo_ro_unref(instance); - return 0; + return igloo_ERROR_NONE; } -int igloo_logcore_set_acknowledge_cb(igloo_logcore_t *core, igloo_logcore_acknowledge_t callback, void *userdata) +igloo_error_t igloo_logcore_set_acknowledge_cb(igloo_logcore_t *core, igloo_logcore_acknowledge_t callback, void *userdata) { if (!igloo_RO_IS_VALID(core, igloo_logcore_t)) - return -1; + return igloo_ERROR_FAULT; igloo_thread_rwlock_wlock(&(core->rwlock)); core->acknowledge_cb = callback; core->acknowledge_cb_userdata = userdata; igloo_thread_rwlock_unlock(&(core->rwlock)); - return 0; + return igloo_ERROR_NONE; } static igloo_list_t *__copy_filtered_list(igloo_list_t *list, const igloo_ro_type_t *type, igloo_filter_t *filter, ssize_t limit) @@ -336,12 +337,12 @@ igloo_list_t * igloo_logcore_get_askack(igloo_logcore_t *core, const igloo_ro_t return ret; } -int igloo_logcore_acknowledge(igloo_logcore_t *core, igloo_ro_t object) +igloo_error_t igloo_logcore_acknowledge(igloo_logcore_t *core, igloo_ro_t object) { int ret; if (!igloo_RO_IS_VALID(core, igloo_logcore_t)) - return -1; + return igloo_ERROR_FAULT; igloo_thread_rwlock_wlock(&(core->rwlock)); ret = igloo_list_remove(core->global_askack, object); @@ -355,7 +356,7 @@ int igloo_logcore_acknowledge(igloo_logcore_t *core, igloo_ro_t obje } igloo_thread_rwlock_unlock(&(core->rwlock)); - return ret; + return ret == 0 ? igloo_ERROR_NONE : igloo_ERROR_GENERIC; } static igloo_filter_result_t __handle(igloo_INTERFACE_BASIC_ARGS, igloo_ro_t object) From 6783107ce02c7b796d796a8527880d7f6b28f496 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Wed, 18 Sep 2019 08:45:34 +0000 Subject: [PATCH 5/5] Update: Added some docs --- include/igloo/logcore.h | 106 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/include/igloo/logcore.h b/include/igloo/logcore.h index c32687d..8d06fcb 100644 --- a/include/igloo/logcore.h +++ b/include/igloo/logcore.h @@ -36,27 +36,133 @@ extern "C" { igloo_RO_FORWARD_TYPE(igloo_logcore_t); +/* Routing classes allow controling the order in which messages should be routed to outputs */ typedef enum { + /* All messages are routed to outputs of the ANY class. + * However if one output accepts the message no additional ANY class outputs are tried. + */ igloo_LOGCORE_CLASS_ANY, + /* In addition to all other classes all messages are routed to all outputs of the ALL class. */ igloo_LOGCORE_CLASS_ALL, + /* The DEFAULT class is part of the ANY class. + * The only difference is that outputs of the DEFAULT class are always tried last. + */ igloo_LOGCORE_CLASS_DEFAULT } igloo_logcore_routingclass_t; +/* Configuration structure of a single output */ typedef struct { + /* Optional: An ID for the output. This can be used to later on reference the output */ char *id; + /* Optional: A filename for the output. If not NULL the file is opened and the formater is attached to it */ char *filename; + /* Required: Routing class for the output. */ igloo_logcore_routingclass_t routingclass; + /* Optional: Limit for the recent buffer of the output or -1 to use the default. */ ssize_t recent_limit; + /* Optional: A filter that the messages that are routed to this output must pass. */ igloo_filter_t *filter; + /* Required: The formater to pass the message to. */ igloo_objecthandler_t *formater; } igloo_logcore_output_t; +/* Type uses for callback called when a message is acknowledged. + * + * This callback can be used to generate a new message or trigger any action + * when another one is acknowledged. + * + * Parameters: + * core + * The core that emited the event. + * object + * The message that was acknowledged. + * userdata + * A pointer that was given on igloo_logcore_set_acknowledge_cb() + * Returns: + * A new message that will be pushed into the core or igloo_RO_NULL. + * A possible igloo_LOGMSG_OPT_ASKACK flag of the message will be ignored to avoid recursion. + */ typedef igloo_ro_t (*igloo_logcore_acknowledge_t)(igloo_logcore_t *core, igloo_ro_t object, void *userdata); + +/* Configure the core. + * + * Parameters: + * core + * The core to configure. + * recent_limit + * The limit for the recent message buffer or -1 for default. + * askack_limit + * The limit for the askack messages buffer or -1 for default. + * output_recent_limit + * The default limit for the per output recent message buffer or -1 for default. + * outputs + * The outputs to use. + * outputs_len + * The number of outputs to use. + */ igloo_error_t igloo_logcore_configure(igloo_logcore_t *core, ssize_t recent_limit, ssize_t askack_limit, ssize_t output_recent_limit, const igloo_logcore_output_t *outputs, size_t outputs_len); + + +/* Set acknowledg callback. + * + * See also igloo_logcore_acknowledge_t. + * + * Parameters: + * core + * The core to configure. + * callback + * The callback to use. + * userdata + * The userdata pointer to pass to the callback. + */ igloo_error_t igloo_logcore_set_acknowledge_cb(igloo_logcore_t *core, igloo_logcore_acknowledge_t callback, void *userdata); + + +/* Get a list of messages from the recent buffer. + * + * Parameters: + * core + * The core to access. + * type + * Filter messages to messages of this type or NULL to not filter. + * filter + * Filter messages using this filter or NULL to not filter. + * limit + * Limit messages to this amount or -1 to not limit. + * id + * Return messages from the output with this ID or NULL to return from the global buffer. + * Returns: + * Prefiltered list of messages. + */ igloo_list_t * igloo_logcore_get_recent(igloo_logcore_t *core, const igloo_ro_type_t *type, igloo_filter_t *filter, ssize_t limit, const char *id); + + +/* Get a list of messages from the askack buffer. + * + * Parameters: + * core + * The core to access. + * type + * Filter messages to messages of this type or NULL to not filter. + * filter + * Filter messages using this filter or NULL to not filter. + * limit + * Limit messages to this amount or -1 to not limit. + * Returns: + * Prefiltered list of messages. + */ igloo_list_t * igloo_logcore_get_askack(igloo_logcore_t *core, const igloo_ro_type_t *type, igloo_filter_t *filter, ssize_t limit); + + +/* Acknowledg a message in the askack buffer. + * + * Parameters: + * core + * The core to access. + * object + * The message to acknowledg. + */ igloo_error_t igloo_logcore_acknowledge(igloo_logcore_t *core, igloo_ro_t object); #ifdef __cplusplus