diff options
-rw-r--r-- | common/collection/collection.h | 3 | ||||
-rw-r--r-- | common/elapi/Makefile.am | 7 | ||||
-rw-r--r-- | common/elapi/configure.ac | 2 | ||||
-rw-r--r-- | common/elapi/elapi_event.c | 2 | ||||
-rw-r--r-- | common/elapi/elapi_event.h | 1 | ||||
-rw-r--r-- | common/elapi/elapi_internal.c | 513 | ||||
-rw-r--r-- | common/elapi/elapi_log.c | 159 | ||||
-rw-r--r-- | common/elapi/elapi_log.h | 40 | ||||
-rw-r--r-- | common/elapi/elapi_priv.h | 110 | ||||
-rw-r--r-- | common/elapi/elapi_test/Makefile.am | 38 | ||||
-rw-r--r-- | common/elapi/elapi_test/configure.ac | 26 | ||||
-rw-r--r-- | common/elapi/elapi_test/elapi_ut.c (renamed from common/elapi/elapi_ut.c) | 57 | ||||
-rw-r--r-- | common/elapi/elapi_test/elapi_ut.conf | 97 | ||||
-rw-r--r-- | common/elapi/elapi_test/m4/.dir | 0 | ||||
-rw-r--r-- | common/elapi/elapi_ut.conf | 6 |
15 files changed, 899 insertions, 162 deletions
diff --git a/common/collection/collection.h b/common/collection/collection.h index 6868cb6e8..e9533a456 100644 --- a/common/collection/collection.h +++ b/common/collection/collection.h @@ -443,6 +443,9 @@ int col_get_item_and_do(struct collection_item *ci, /* A collection of items */ * while the pointer to its data is in use. * Working with the internals of the collection item structure directly * may cause problems in future if the internal implementation changes. + * The caller needs to be aware that function does not return + * error if item is not found. The caller needs to check if + * item is not NULL to determine whether something was found. */ int col_get_item(struct collection_item *ci, /* Collection to find things in */ const char *property_to_find, /* Name to match */ diff --git a/common/elapi/Makefile.am b/common/elapi/Makefile.am index 922744291..2ebf9e833 100644 --- a/common/elapi/Makefile.am +++ b/common/elapi/Makefile.am @@ -4,6 +4,8 @@ DEFAULT_CONF_APP_DIR=@elapiconfappdir@ APP_NAME=@appname@ APP_NAME_SIZE=@appnamesize@ +SUBDIRS = elapi_test + topdir=$(srcdir)/.. AM_CFLAGS = -DELAPI_DEFAULT_CONFIG_DIR=\"$(DEFAULT_CONF_DIR)\" \ @@ -37,8 +39,3 @@ libelapi_la_SOURCES = \ elapi_log.h \ elapi_async.h \ elapi.h - -# Build unit test -noinst_PROGRAMS = elapi_ut -elapi_ut_SOURCES = elapi_ut.c -elapi_ut_LDADD = libelapi.la ../ini/libini_config.la ../collection/libcollection.la diff --git a/common/elapi/configure.ac b/common/elapi/configure.ac index 2ebf0d086..a4db41915 100644 --- a/common/elapi/configure.ac +++ b/common/elapi/configure.ac @@ -28,5 +28,7 @@ WITH_CONFIG_APP_DIR WITH_APP_NAME WITH_APP_NAME_SIZE +AC_CONFIG_SUBDIRS([elapi_test]) + AC_CONFIG_FILES([Makefile elapi.pc]) AC_OUTPUT diff --git a/common/elapi/elapi_event.c b/common/elapi/elapi_event.c index 97cb2a13b..9ca2c7381 100644 --- a/common/elapi/elapi_event.c +++ b/common/elapi/elapi_event.c @@ -209,7 +209,7 @@ static int add_host_identity(struct collection_item *tpl, unsigned base) TRACE_INFO_NUMBER("gai_ret_host:", gai_ret_host); TRACE_INFO_STRING("host:", host); TRACE_INFO_STRING("address:", address); - TRACE_INFO_STRING("they are:", strncasecmp(host, address, sizeof(address)) == 0 ? "same" : "different"); + TRACE_INFO_STRING("they are:", ((strcasecmp(host, address) != 0) ? "different" : "same")); /* Do we have a host meaningful host name? */ if ((gai_ret_host != EOK) || diff --git a/common/elapi/elapi_event.h b/common/elapi/elapi_event.h index f18333962..27c297b18 100644 --- a/common/elapi/elapi_event.h +++ b/common/elapi/elapi_event.h @@ -68,6 +68,7 @@ #define E_BASE_HOSTEXT ( E_HAVE_HOSTALIAS | E_HAVE_HOSTIPS ) #define E_BASE_DEFV1 ( E_BASE_TIME | E_BASE_HOST | E_BASE_APP | E_HAVE_SEVERITY ) + /* The default time stamp format */ #define E_TIMESTAMP_FORMAT "%F" diff --git a/common/elapi/elapi_internal.c b/common/elapi/elapi_internal.c index 2e93a355c..c5ec12474 100644 --- a/common/elapi/elapi_internal.c +++ b/common/elapi/elapi_internal.c @@ -20,6 +20,7 @@ #define _GNU_SOURCE #include <errno.h> /* for errors */ #include <stdio.h> /* for printf() - temporarily */ +#include <stdlib.h> /* for malloc() */ #include "elapi_priv.h" #include "elapi_event.h" @@ -38,7 +39,74 @@ */ #define ELAPI_DEFAULT_ERROR_FILE "elapiconf.err" -/* Handler for logging through the sinks */ +/* Handler for logging through the targets */ +int elapi_internal_target_handler(const char *target, + int target_len, + int type, + void *data, + int length, + void *passed_data, + int *stop) +{ + struct elapi_target_pass_in_data *target_data; + struct elapi_target_context *context; + + TRACE_FLOW_STRING("elapi_internal_target_handler", "Entry."); + + /* Skip header */ + if (type == COL_TYPE_COLLECTION) { + TRACE_FLOW_STRING("elapi_internal_target_handler - skip header", "Exit."); + return EOK; + } + + target_data = (struct elapi_target_pass_in_data *)(passed_data); + context = *((struct elapi_target_context **)(data)); + + /* Check if we need to log this event into this target */ + TRACE_INFO_NUMBER("EVENT IS LOGGED INTO:", target_data->target_mask); + TRACE_INFO_NUMBER("TARGET VALUE IS:", context->target_value); + + if ((target_data->target_mask & context->target_value) == 0) { + TRACE_INFO_STRING("Current event will NOT be logged into the target:", target); + return EOK; + } + + TRACE_INFO_STRING("Current event will be logged into the target:", target); + + /* FIXME THIS IS A PLACEHOLDER FUNCTION FOR NOW */ + + printf("\n\n\nPROCESSING EVENT:\n"); + col_debug_collection(target_data->event, COL_TRAVERSE_DEFAULT); + + TRACE_FLOW_STRING("elapi_internal_target_handler", "Exit."); + return EOK; +} + +/* Internal target cleanup function */ +int elapi_internal_target_cleanup_handler(const char *target, + int target_len, + int type, + void *data, + int length, + void *passed_data, + int *stop) +{ + TRACE_FLOW_STRING("elapi_internal_target_cleanup_handler", "Entry."); + + /* Skip header */ + if (type == COL_TYPE_COLLECTION) { + TRACE_FLOW_STRING("elapi_internal_target_cleanup_handler - skip header", "Exit."); + return EOK; + } + + elapi_internal_destroy_target(*((struct elapi_target_context **)(data))); + + TRACE_FLOW_STRING("elapi_internal_target_cleanup_handler", "Exit."); + return EOK; +} + + + int elapi_internal_sink_handler(const char *sink, int sink_len, int type, @@ -47,18 +115,17 @@ int elapi_internal_sink_handler(const char *sink, void *passed_data, int *stop) { - struct elapi_sink_context *sink_env; TRACE_FLOW_STRING("elapi_internal_sink_handler", "Entry."); /* FIXME THIS IS A PLACEHOLDER FUNCTION FOR NOW */ - sink_env = (struct elapi_sink_context *)(passed_data); - + /* Skip header */ if (type == COL_TYPE_COLLECTION) { - printf("\n\n\nPROCESSING EVENT:\n"); - col_debug_collection(sink_env->event, COL_TRAVERSE_DEFAULT); + TRACE_FLOW_STRING("elapi_internal_sink_handler - skip header", "Exit."); + return EOK; } - else printf("Sink: %s\n", sink); + + printf("Sink: %s\n", sink); TRACE_FLOW_STRING("elapi_internal_sink_handler", "Exit."); return EOK; @@ -77,74 +144,268 @@ int elapi_internal_sink_cleanup_handler(const char *sink, /* FIXME THIS IS A PLACEHOLDER FUNCTION FOR NOW */ - if (type != COL_TYPE_COLLECTION) printf("Cleaning Sink: %s\n", sink); + printf("Cleaning Sink: %s\n", sink); TRACE_FLOW_STRING("elapi_internal_sink_cleanup_handler", "Exit."); return EOK; } /* Function to add a sink to the collection */ -int elapi_internal_add_sink_to_collection(struct collection_item *sink_list, - char *sink, - char *appname) +/* FIXME - other arguments might be added later */ +int elapi_internal_add_sink(struct collection_item **sink_ref, + char *sink, + struct elapi_dispatcher *handle) { int error = EOK; - int found = 0; - struct sink_descriptor sink_data; - - TRACE_FLOW_STRING("elapi_internal_add_sink_to_collection", "Entry"); - error = col_is_item_in_collection(sink_list, - sink, - COL_TYPE_ANY, - COL_TRAVERSE_DEFAULT, - &found); + struct elapi_sink_context sink_context; + struct collection_item *provider_cfg_item = NULL; + + TRACE_FLOW_STRING("elapi_internal_add_sink", "Entry"); + + TRACE_INFO_STRING("Evaluating sink:", sink); + TRACE_INFO_NUMBER("Sink reference before call:", *sink_ref); + + /* Get the sink from the list */ + error = col_get_item(handle->sink_list, + sink, + COL_TYPE_ANY, + COL_TRAVERSE_DEFAULT, + sink_ref); + + TRACE_INFO_NUMBER("Sink evaluation returned", error); + TRACE_INFO_NUMBER("Sink reference after call:", *sink_ref); + if (error) { TRACE_ERROR_NUMBER("Search returned error", error); return error; } - /* Check if it was found */ - if (found) { - TRACE_ERROR_NUMBER("Attempt to add an exiting sink.", ""); - return EINVAL; + if (!(*sink_ref)) { + TRACE_FLOW_STRING("No such sink yet, adding new sink:", sink); + + /* First check if this sink is properly configured and get its provider */ + error = get_config_item(sink, + ELAPI_SINK_PROVIDER, + handle->ini_config, + &provider_cfg_item); + if (error) { + TRACE_ERROR_NUMBER("Attempt to read provider attribute returned error", error); + return error; + } + + /* Do we have provider? */ + if (provider_cfg_item == NULL) { + /* There is no provider - return error */ + TRACE_ERROR_STRING("Required key is missing in the configuration.", "Fatal Error!"); + return ENOKEY; + } + + + /* FIXME: PLACEHOLDER + * This is the area where the actual sink is loaded. + * CODE WILL BE ADDED HERE... + */ + sink_context.async_mode = 0; + sink_context.in_queue = NULL; + sink_context.pending = NULL; + + /* We got a valid sink so add it to the collection */ + error = col_add_binary_property_with_ref(handle->sink_list, + NULL, + sink, + (void *)(&sink_context), + sizeof(struct elapi_sink_context), + sink_ref); + if (error != 0) { + TRACE_ERROR_NUMBER("Failed to add sink data as property", error); + return error; + } } - /* Save the pointer to application name into the sink's data block */ - sink_data.dblock.appname = appname; - TRACE_INFO_STRING("add_sink_to_list - saving appname:", sink_data.dblock.appname); + TRACE_FLOW_NUMBER("elapi_internal_add_sink returning", error); + return error; +} + +/* Destroy target object */ +void elapi_internal_destroy_target(struct elapi_target_context *context) +{ + TRACE_FLOW_STRING("elapi_internal_destroy_target", "Entry."); - /* Try to load the sink library */ + TRACE_INFO_NUMBER("Target address in cleanup:", context); - /* FIXME - we need to have at least one sink implemented to enable this code. - * It is a placeholder for now. - error = load_sink(&sink_data, sink); - if (error != 0) { - DEBUG_NUMBER("Failed to load sink", error); + if (context) { + TRACE_INFO_STRING("Deleting the list of references to sinks", ""); + col_destroy_collection(context->sink_ref_list); + /* FIXME - add other cleanup for other things that will be a part + * of the target context. + */ + free(context); + } + + TRACE_FLOW_STRING("elapi_internal_destroy_target", "Exit."); + +} + +/* Allocate target context and load sinks to it */ +int elapi_internal_create_target(struct elapi_target_context **context, + char *target, + struct elapi_dispatcher *handle) +{ + int error = EOK; + struct collection_item *sink_cfg_item = NULL; + struct collection_item *value_cfg_item = NULL; + struct elapi_target_context *target_context; + char **sinks; + char **current_sink; + struct collection_item *sink_ref; + + TRACE_FLOW_STRING("elapi_internal_create_target", "Entry."); + + /* Get list of sinks for this target from config */ + error = get_config_item(target, + ELAPI_SINKS, + handle->ini_config, + &sink_cfg_item); + if (error) { + TRACE_ERROR_NUMBER("Attempt to read configuration returned error", error); return error; } - */ + /* Do we have sinks? */ + if (sink_cfg_item == NULL) { + /* There is no list of targets this is bad configuration - return error */ + TRACE_ERROR_STRING("Required key is missing in the configuration.", "Fatal Error!"); + return ENOKEY; + } + + /* Allocate context */ + target_context = (struct elapi_target_context *)malloc(sizeof(struct elapi_target_context)); + if (target_context == NULL) { + TRACE_ERROR_NUMBER("Memory allocation failed. Error", target_context); + return ENOMEM; + } + + /* Initialize the allocatable items so that we can call destroy function + * in case of error. + * FIXME - add initialization here for other elements as they are added. + */ + + target_context->sink_ref_list = NULL; - /* We got a valid sink so add it to the collection */ - error = col_add_binary_property(sink_list, NULL, - sink, (void *)(&sink_data), - sizeof(struct sink_descriptor)); + /* Assign target's value */ + error = get_config_item(target, + ELAPI_TARGET_VALUE, + handle->ini_config, + &value_cfg_item); + if (error) { + TRACE_ERROR_NUMBER("Attempt to read configuration returned error", error); + elapi_internal_destroy_target(target_context); + return error; + } + + /* Do we have value? */ + if (value_cfg_item == NULL) { + TRACE_INFO_STRING("Value for target is not defined.", "Assume ANY."); + target_context->target_value = ELAPI_TARGET_ALL; + } + else { + target_context->target_value = (uint32_t)get_unsigned_config_value(value_cfg_item, + 1, + ELAPI_TARGET_ALL, + &error); + /* NOTE: I will check and fail here on error rather than do a best effort + * for now. We can switch to less rigorous checking when the INI + * validation library/utility becomes available. + */ + if (error) { + TRACE_ERROR_NUMBER("Failed to convert value form INI file", error); + elapi_internal_destroy_target(target_context); + return error; + } + } + + TRACE_INFO_NUMBER("Value for target is:", target_context->target_value); + + + /* Allocate collection to store sink references for this target */ + error = col_create_collection(&(target_context->sink_ref_list), + ELAPI_SINK_REFS, + COL_CLASS_ELAPI_SINK_REF); if (error != 0) { - TRACE_ERROR_NUMBER("Failed to add sink data as property", error); + TRACE_ERROR_NUMBER("Failed to create sink collection. Error", error); + elapi_internal_destroy_target(target_context); return error; } - TRACE_FLOW_NUMBER("elapi_internal_add_sink_to_collection returning", error); - return error; + /* Get list of sinks from config. Make sure we free it later */ + sinks = get_string_config_array(sink_cfg_item, NULL, NULL, NULL); + + /* For each sink in the list create sink context object and load sink */ + current_sink = sinks; + while (*current_sink != NULL) { + + TRACE_INFO_STRING("Current sink", *current_sink); + + /* Load sink if it is not loaded yet */ + sink_ref = NULL; + error = elapi_internal_add_sink(&sink_ref, + *current_sink, + handle); + if (error) { + /* NOTE - we might decide to lax some of the checks + * like this later and be satisfied with at least one + * sink in the list. Subject for discussion... + */ + TRACE_ERROR_NUMBER("Failed to add sink", error); + elapi_internal_destroy_target(target_context); + free_string_config_array(sinks); + return error; + } + + /* Add reference to it into the target object */ + error = col_add_binary_property(target_context->sink_ref_list, NULL, + *current_sink, (void *)(&sink_ref), + sizeof(struct collection_item *)); + if (error != 0) { + TRACE_ERROR_NUMBER("Failed to add sink reference", error); + elapi_internal_destroy_target(target_context); + free_string_config_array(sinks); + return error; + } + + current_sink++; + } + + free_string_config_array(sinks); + + *context = target_context; + + TRACE_FLOW_STRING("elapi_internal_create_target", "Exit."); + return EOK; } -/* Function to create a list of sinks */ -int elapi_internal_construct_sink_list(struct elapi_dispatcher *handle) + +/* Function to create a list of targets */ +int elapi_internal_construct_target_list(struct elapi_dispatcher *handle) { int error = EOK; - char **current_sink; + char **current_target; + struct elapi_target_context *context; - TRACE_FLOW_STRING("elapi_internal_construct_sink_list", "Entry"); + + TRACE_FLOW_STRING("elapi_internal_construct_target_list", "Entry"); + + /* Allocate collection to store target */ + error = col_create_collection(&(handle->target_list), + ELAPI_TARGETS, + COL_CLASS_ELAPI_TARGET); + if (error != 0) { + TRACE_ERROR_NUMBER("Failed to create target collection. Error", error); + /* No cleanup here. + * The calling function will call a cleanup + * of the dispatcher as a whole.*/ + return error; + } /* Allocate collection to store sinks */ error = col_create_collection(&(handle->sink_list), @@ -158,41 +419,53 @@ int elapi_internal_construct_sink_list(struct elapi_dispatcher *handle) return error; } - current_sink = handle->sinks; - handle->sink_counter = 0; + current_target = handle->targets; + handle->target_counter = 0; - /* Add sinks as properties to the sink collection */ - while (*current_sink != NULL) { + /* Add targets as properties to the target collection */ + while (*current_target != NULL) { - TRACE_INFO_STRING("Current sink", *current_sink); - TRACE_INFO_STRING("Will use appname:", handle->appname); + TRACE_INFO_STRING("Current target", *current_target); - /* Load sink */ - error = elapi_internal_add_sink_to_collection(handle->sink_list, - *current_sink, - handle->appname); - if ((error != 0) && (error != ELIBACC)) { - TRACE_ERROR_NUMBER("Failed to add sink", error); - /* No cleanup here. */ + /* Allocate target context and load sinks to it */ + context = NULL; + error = elapi_internal_create_target(&context, + *current_target, + handle); + if (error) { + TRACE_ERROR_NUMBER("Failed to create target", error); return error; } - handle->sink_counter++; - current_sink++; + TRACE_INFO_NUMBER("Target address:", context); + + /* Add created target to the list of targets */ + error = col_add_binary_property(handle->target_list, NULL, + *current_target, (void *)(&context), + sizeof(struct elapi_target_context *)); + if (error != 0) { + TRACE_ERROR_NUMBER("Failed to add sink data as property", error); + /* Need to clean allocated context here if we failed to add it */ + elapi_internal_destroy_target(context); + return error; + } + + handle->target_counter++; + current_target++; } - /* Check if we have any sinks available */ - if (handle->sink_counter == 0) { - TRACE_ERROR_NUMBER("No sinks", ELIBACC); - /* No cleanup here. */ - /* Return "Cannot access a needed shared library" */ - return ELIBACC; + /* Check if we have any targets available */ + if (handle->target_counter == 0) { + TRACE_ERROR_STRING("No targets", ""); + return ENOKEY; } - TRACE_FLOW_STRING("elapi_internal_construct_sink_list", "Returning success"); + TRACE_FLOW_STRING("elapi_internal_construct_target_list", "Returning success"); return EOK; } + + /* If we failed to read configuration record this in the local file */ void elapi_internal_dump_errors_to_file(struct collection_item *error_list) { @@ -229,3 +502,109 @@ void elapi_internal_dump_errors_to_file(struct collection_item *error_list) fclose(efile); TRACE_FLOW_STRING("elapi_internal_dump_errors_to_file", "Exit"); } + + +/* Handler for printing target internals */ +static int elapi_internal_sink_ref_debug_handler(const char *sink, + int sink_len, + int type, + void *data, + int length, + void *passed_data, + int *stop) +{ + struct collection_item *sink_item; + struct elapi_sink_context *sink_context; + + /* Skip header */ + if (type == COL_TYPE_COLLECTION) { + return EOK; + } + + sink_item = *((struct collection_item **)(data)); + + printf("\nReferenced sink name is: %s\n", col_get_item_property(sink_item, NULL)); + + sink_context = (struct elapi_sink_context *)(col_get_item_data(sink_item)); + + printf("Mode: %s\n", sink_context->async_mode ? "true" : "false"); + if (sink_context->in_queue) col_print_collection(sink_context->in_queue); + else printf("Queue is not initialized.\n"); + + if (sink_context->pending) col_print_collection(sink_context->pending); + else printf("Pending list is not initialized.\n"); + + return EOK; +} + + + +/* Handler for printing target internals */ +static int elapi_internal_target_debug_handler(const char *target, + int target_len, + int type, + void *data, + int length, + void *passed_data, + int *stop) +{ + struct elapi_target_context *context; + + /* Skip header */ + if (type == COL_TYPE_COLLECTION) { + return EOK; + } + + context = *((struct elapi_target_context **)(data)); + + printf("\nTarget value for target \"%s\" is %d\n", target, context->target_value); + printf("\nReferenced sinks:\n\n"); + + (void)col_traverse_collection(context->sink_ref_list, + COL_TRAVERSE_ONELEVEL, + elapi_internal_sink_ref_debug_handler, + NULL); + + return EOK; +} + + +/* Internal function to print dispatcher internals - useful for testing */ +void elapi_internal_print_dispatcher(struct elapi_dispatcher *handle) +{ + char **current_target; + + printf("\nPRINTING DISPATCHER INTERNALS\n\n"); + + printf("Application name: %s\n", handle->appname != NULL ? handle->appname : "(null)"); + printf("List of target names:\n"); + + current_target = handle->targets; + while (*current_target != NULL) { + printf(" %s\n",*current_target); + current_target++; + } + + printf("Target counter: %d\n", handle->target_counter); + printf("\n\nTarget collection:\n\n"); + if (handle->target_list) col_debug_collection(handle->target_list, COL_TRAVERSE_DEFAULT); + + + printf("\n\nSink collection:\n\n"); + if (handle->sink_list) col_debug_collection(handle->sink_list, COL_TRAVERSE_DEFAULT); + printf("\n\nConfig collection:\n\n"); + if (handle->ini_config) col_debug_collection(handle->ini_config, COL_TRAVERSE_DEFAULT); + printf("\nDefault template:\n\n"); + if (handle->default_template) col_debug_collection(handle->default_template, COL_TRAVERSE_DEFAULT); + + printf("\n\nDeep target inspection:\n\n"); + if (handle->target_list) { + (void)col_traverse_collection(handle->target_list, + COL_TRAVERSE_ONELEVEL, + elapi_internal_target_debug_handler, + NULL); + } + /* FIXME: Async data... */ + + printf("DISPATCHER END\n\n"); +} diff --git a/common/elapi/elapi_log.c b/common/elapi/elapi_log.c index 7c0d72abc..122506e5a 100644 --- a/common/elapi/elapi_log.c +++ b/common/elapi/elapi_log.c @@ -71,7 +71,8 @@ static int elapi_close_registered = 0; /* Internal function to log message using args */ -static int elapi_dsp_msg_with_vargs(struct elapi_dispatcher *dispatcher, +static int elapi_dsp_msg_with_vargs(uint32_t target, + struct elapi_dispatcher *dispatcher, struct collection_item *template, va_list args) { @@ -98,7 +99,7 @@ static int elapi_dsp_msg_with_vargs(struct elapi_dispatcher *dispatcher, } /* Now log event */ - error = elapi_dsp_log(dispatcher, event); + error = elapi_dsp_log(target, dispatcher, event); /* Destroy event */ elapi_destroy_event(event); @@ -150,10 +151,10 @@ int elapi_create_dispatcher_adv(struct elapi_dispatcher **dispatcher, } /* Check that all the async data is present */ - if (!add_fd_add_fn) prm_cnt++; - if (!add_fd_rem_fn) prm_cnt++; - if (!add_timer_fn) prm_cnt++; - if (!callers_data) prm_cnt++; + if (add_fd_add_fn) prm_cnt++; + if (add_fd_rem_fn) prm_cnt++; + if (add_timer_fn) prm_cnt++; + if (callers_data) prm_cnt++; if ((prm_cnt > 0) && (prm_cnt < 4)) { /* We got a mixture of NULLs and not NULLs. @@ -213,10 +214,10 @@ int elapi_create_dispatcher_adv(struct elapi_dispatcher **dispatcher, */ memset(handle, 0, sizeof(struct elapi_dispatcher *)); handle->ini_config = NULL; + handle->target_list = NULL; handle->sink_list = NULL; - handle->sinks = NULL; + handle->targets = NULL; handle->default_template = NULL; - handle->need_to_free = 0; /* Save application name in the handle */ if (appname != NULL) handle->appname = strdup(appname); @@ -248,12 +249,13 @@ int elapi_create_dispatcher_adv(struct elapi_dispatcher **dispatcher, } return error; } + /* Have to clean error set anyways */ free_ini_config_errors(error_set); - /* Get sink list from configuration */ + /* Get target list from configuration */ error = get_config_item(ELAPI_DISPATCHER, - ELAPI_SINKS, + ELAPI_TARGETS, handle->ini_config, &item); if (error) { @@ -262,14 +264,23 @@ int elapi_create_dispatcher_adv(struct elapi_dispatcher **dispatcher, return error; } - if (!item) { - /* There is no list of sinks - use default list */ - handle->sinks = default_sinks; + /* Do we have targets? */ + if (item == NULL) { + /* There is no list of targets this is bad configuration - return error */ + TRACE_ERROR_STRING("No targets in the config file.", "Fatal error!"); + elapi_destroy_dispatcher(handle); + return ENOKEY; } - else { - /* Get one from config but make sure we free it later */ - handle->sinks = get_string_config_array(item, NULL, NULL, NULL); - handle->need_to_free = 1; + + /* Get one from config but make sure we free it later */ + handle->targets = get_string_config_array(item, NULL, NULL, NULL); + + /* Create the list of targets */ + error = elapi_internal_construct_target_list(handle); + if (error != EOK) { + TRACE_ERROR_NUMBER("Failed to create target list. Error", error); + elapi_destroy_dispatcher(handle); + return error; } /* Populate async processing data if any */ @@ -282,14 +293,6 @@ int elapi_create_dispatcher_adv(struct elapi_dispatcher **dispatcher, handle->async_mode = 1; } - /* Create the list of sinks */ - error = elapi_internal_construct_sink_list(handle); - if (error != EOK) { - TRACE_ERROR_NUMBER("Failed to create sink list. Error", error); - elapi_destroy_dispatcher(handle); - return error; - } - *dispatcher = handle; TRACE_FLOW_STRING("elapi_create_dispatcher_adv", "Returning Success."); @@ -328,19 +331,34 @@ void elapi_destroy_dispatcher(struct elapi_dispatcher *dispatcher) if (dispatcher) { TRACE_INFO_STRING("Deleting template if any...", ""); col_destroy_collection(dispatcher->default_template); - TRACE_INFO_STRING("Closing sink handler.", ""); - (void)col_traverse_collection(dispatcher->sink_list, - COL_TRAVERSE_ONELEVEL, - elapi_internal_sink_cleanup_handler, - NULL); - TRACE_INFO_STRING("Deleting sink list.", ""); - col_destroy_collection(dispatcher->sink_list); + + if (dispatcher->target_list) { + TRACE_INFO_STRING("Closing target list.", ""); + (void)col_traverse_collection(dispatcher->target_list, + COL_TRAVERSE_ONELEVEL, + elapi_internal_target_cleanup_handler, + NULL); + + TRACE_INFO_STRING("Deleting target list.", ""); + col_destroy_collection(dispatcher->target_list); + } + + if (dispatcher->sink_list) { + TRACE_INFO_STRING("Closing sink list.", ""); + (void)col_traverse_collection(dispatcher->sink_list, + COL_TRAVERSE_ONELEVEL, + elapi_internal_sink_cleanup_handler, + NULL); + TRACE_INFO_STRING("Deleting target list.", ""); + col_destroy_collection(dispatcher->sink_list); + } + TRACE_INFO_STRING("Freeing application name.", ""); free(dispatcher->appname); TRACE_INFO_STRING("Freeing config.", ""); free_ini_config(dispatcher->ini_config); - TRACE_INFO_STRING("Deleting sink name array.", ""); - if (dispatcher->need_to_free) free_string_config_array(dispatcher->sinks); + TRACE_INFO_STRING("Deleting targets name array.", ""); + free_string_config_array(dispatcher->targets); TRACE_INFO_STRING("Freeing dispatcher.", ""); free(dispatcher); } @@ -349,10 +367,12 @@ void elapi_destroy_dispatcher(struct elapi_dispatcher *dispatcher) } /* Function to log an event */ -int elapi_dsp_log(struct elapi_dispatcher *dispatcher, struct collection_item *event) +int elapi_dsp_log(uint32_t target, + struct elapi_dispatcher *dispatcher, + struct collection_item *event) { int error = EOK; - struct elapi_sink_context sink_env; + struct elapi_target_pass_in_data target_data; TRACE_FLOW_STRING("elapi_dsp_log", "Entry"); @@ -362,14 +382,18 @@ int elapi_dsp_log(struct elapi_dispatcher *dispatcher, struct collection_item *e return EINVAL; } - sink_env.handle = dispatcher; - sink_env.event = event; + /* Wrap parameters into one argument and pass on */ + target_data.handle = dispatcher; + target_data.event = event; + target_data.target_mask = target; + + TRACE_INFO_NUMBER("Target mask is:", target_data.target_mask); - /* Logging an event is just iterating through the sinks and calling the sink_handler */ - error = col_traverse_collection(dispatcher->sink_list, + /* Logging an event is just iterating through the targets and calling the sink_handler */ + error = col_traverse_collection(dispatcher->target_list, COL_TRAVERSE_ONELEVEL, - elapi_internal_sink_handler, - (void *)(&sink_env)); + elapi_internal_target_handler, + (void *)(&target_data)); TRACE_FLOW_NUMBER("elapi_dsp_log Exit. Returning", error); return error; @@ -384,7 +408,13 @@ int elapi_set_default_template(unsigned base, ...) TRACE_FLOW_STRING("elapi_set_default_template", "Entry"); - if (global_dispatcher == NULL) elapi_init(NULL, NULL); + if (global_dispatcher == NULL) { + error = elapi_init(NULL, NULL); + if (error) { + TRACE_ERROR_NUMBER("Failed to init ELAPI", error); + return error; + } + } /* Clean previous instance of the default template */ elapi_destroy_event_template(global_dispatcher->default_template); @@ -436,7 +466,8 @@ int elapi_get_default_template(struct collection_item **template) /* Function to log raw key value pairs without creating an event */ -int elapi_dsp_msg(struct elapi_dispatcher *dispatcher, +int elapi_dsp_msg(uint32_t target, + struct elapi_dispatcher *dispatcher, struct collection_item *template, ...) { @@ -447,7 +478,7 @@ int elapi_dsp_msg(struct elapi_dispatcher *dispatcher, va_start(args, template); - error = elapi_dsp_msg_with_vargs(dispatcher, template, args); + error = elapi_dsp_msg_with_vargs(target, dispatcher, template, args); va_end(args); @@ -459,6 +490,7 @@ int elapi_dsp_msg(struct elapi_dispatcher *dispatcher, /* Managing the sink collection */ int elapi_alter_dispatcher(struct elapi_dispatcher *dispatcher, + const char *target, const char *sink, int action) { @@ -468,7 +500,7 @@ int elapi_alter_dispatcher(struct elapi_dispatcher *dispatcher, } /* Get sink list */ -char **elapi_get_sink_list(struct elapi_dispatcher *dispatcher) +char **elapi_get_sink_list(struct elapi_dispatcher *dispatcher, char *target) { /* FIXME: FUNCTION IS NOT IMPLEMENTED YET */ @@ -483,6 +515,22 @@ void elapi_free_sink_list(char **sink_list) } +/* Get target list */ +char **elapi_get_target_list(struct elapi_dispatcher *dispatcher) +{ + + /* FIXME: FUNCTION IS NOT IMPLEMENTED YET */ + return NULL; +} + +/* Free target list */ +void elapi_free_target_list(char **target_list) +{ + + /* FIXME: FUNCTION IS NOT IMPLEMENTED YET */ + +} + /******************** High level interface ************************************/ /* This interface is not thread safe but hides the dispatcher. */ @@ -536,7 +584,7 @@ int elapi_create_simple_event(struct collection_item **event, ...) } /* Log key value pairs */ -int elapi_msg(struct collection_item *template, ...) +int elapi_msg(uint32_t target, struct collection_item *template, ...) { int error = EOK; va_list args; @@ -556,7 +604,10 @@ int elapi_msg(struct collection_item *template, ...) va_start(args, template); - error = elapi_dsp_msg_with_vargs(global_dispatcher, use_template, args); + error = elapi_dsp_msg_with_vargs(target, + global_dispatcher, + use_template, + args); va_end(args); @@ -565,15 +616,21 @@ int elapi_msg(struct collection_item *template, ...) } /* Log event */ -int elapi_log(struct collection_item *event) +int elapi_log(uint32_t target, struct collection_item *event) { int error; TRACE_FLOW_STRING("elapi_log", "Entry"); /* If dispatcher was not initialized do it automatically */ - if (global_dispatcher == NULL) elapi_init(NULL, NULL); - error = elapi_dsp_log(global_dispatcher, event); + if (global_dispatcher == NULL) { + error = elapi_init(NULL, NULL); + if (error) { + TRACE_ERROR_NUMBER("Failed to init ELAPI", error); + return error; + } + } + error = elapi_dsp_log(target, global_dispatcher, event); TRACE_FLOW_NUMBER("elapi_log Exit:", error); return error; diff --git a/common/elapi/elapi_log.h b/common/elapi/elapi_log.h index 6fff82b64..7d8a3b7d2 100644 --- a/common/elapi/elapi_log.h +++ b/common/elapi/elapi_log.h @@ -20,8 +20,18 @@ #ifndef ELAPI_LOG_H #define ELAPI_LOG_H +#include <stdint.h> + #include "elapi_async.h" +/* Default values for targets - + * these constants match values in the default configuration. + */ +#define E_TARGET_DEBUG 0x00000001 +#define E_TARGET_AUDIT 0x00000002 +#define E_TARGET_LOG 0x00000004 + + /* Opaque dispatcher structure */ struct elapi_dispatcher; @@ -51,10 +61,13 @@ int elapi_create_dispatcher_adv(struct elapi_dispatcher **dispatcher, /* Handle void elapi_destroy_dispatcher(struct elapi_dispatcher *dispatcher); /* Function to log an event */ -int elapi_dsp_log(struct elapi_dispatcher *dispatcher, struct collection_item *event); +int elapi_dsp_log(uint32_t target, + struct elapi_dispatcher *dispatcher, + struct collection_item *event); /* Function to log raw key value pairs without creating an event */ -int elapi_dsp_msg(struct elapi_dispatcher *dispatcher, +int elapi_dsp_msg(uint32_t target, + struct elapi_dispatcher *dispatcher, struct collection_item *template, ...); @@ -62,11 +75,18 @@ int elapi_dsp_msg(struct elapi_dispatcher *dispatcher, /* Managing the sink collection */ int elapi_alter_dispatcher(struct elapi_dispatcher *dispatcher, /* Dispatcher */ + const char *target, /* Target to look for */ const char *sink, /* Sink to change */ int action); /* Action to perform for sink */ +/* Get target list */ +char **elapi_get_target_list(struct elapi_dispatcher *dispatcher); + +/* Free target list */ +void elapi_free_target_list(char **target_list); + /* Get sink list */ -char **elapi_get_sink_list(struct elapi_dispatcher *dispatcher); +char **elapi_get_sink_list(struct elapi_dispatcher *dispatcher, char *target); /* Free sink list */ void elapi_free_sink_list(char **sink_list); @@ -102,13 +122,19 @@ void elapi_free_sink_list(char **sink_list); int elapi_init(const char *appname, const char *config_path); /* Log key value pairs */ -int elapi_msg(struct collection_item *template, ...); - +int elapi_msg(uint32_t target, + struct collection_item *template, ...); /* Log event */ -int elapi_log(struct collection_item *event); +int elapi_log(uint32_t target, + struct collection_item *event); + +/* Corresponding wrapping macroses */ +#define ELAPI_EVT_DEBUG(event) elapi_log(E_TARGET_DEBUG, event) +#define ELAPI_EVT_LOG(event) elapi_log(E_TARGET_LOG, event) +#define ELAPI_EVT_AUDIT(event) elapi_log(E_TARGET_AUDIT, event) -/* Get dispatcher if you want to add sink to a default dispatcher or do some advanced operations */ +/* Get dispatcher if you want to do some advanced operations */ struct elapi_dispatcher *elapi_get_dispatcher(void); /* Close audit */ diff --git a/common/elapi/elapi_priv.h b/common/elapi/elapi_priv.h index c536f4ecf..0fa01b406 100644 --- a/common/elapi/elapi_priv.h +++ b/common/elapi/elapi_priv.h @@ -20,6 +20,8 @@ #ifndef ELAPI_PRIV_H #define ELAPI_PRIV_H +#include <stdint.h> + #include "collection.h" #include "elapi_async.h" /* Classes of the collections used by ELAPI internally */ @@ -27,22 +29,37 @@ #define COL_CLASS_ELAPI_EVENT COL_CLASS_ELAPI_BASE + 0 #define COL_CLASS_ELAPI_TEMPLATE COL_CLASS_ELAPI_BASE + 1 #define COL_CLASS_ELAPI_SINK COL_CLASS_ELAPI_BASE + 2 +#define COL_CLASS_ELAPI_TARGET COL_CLASS_ELAPI_BASE + 3 +#define COL_CLASS_ELAPI_SINK_REF COL_CLASS_ELAPI_BASE + 4 /* Names for the collections */ #define E_TEMPLATE_NAME "template" #define E_EVENT_NAME "event" - +/* Constants used in INI file and in + * the internal collection objects. + */ #define ELAPI_DISPATCHER "dispatcher" #define ELAPI_SINKS "sinks" +#define ELAPI_TARGETS "targets" +#define ELAPI_SINK_REFS "srefs" +#define ELAPI_TARGET_VALUE "value" +#define ELAPI_SINK_PROVIDER "provider" + +#define ELAPI_TARGET_ALL 0xFFFF /* 65k targets should be enough */ struct elapi_dispatcher { - char **sinks; - int need_to_free; + /* Application name */ char *appname; - /*event_router_fn router; - FIXME - not defined yet */ + /* List of target names and chars */ + char **targets; + /* Collection of targets */ + struct collection_item *target_list; + /* Counter of the targets */ + int target_counter; + /* Collection of sinks */ struct collection_item *sink_list; - int sink_counter; + /* Configuration */ struct collection_item *ini_config; /* Default event template */ struct collection_item *default_template; @@ -51,16 +68,47 @@ struct elapi_dispatcher { elapi_rem_fd add_fd_rem_fn; elapi_add_timer add_timer_fn; void *callers_data; - int async_mode; + uint32_t async_mode; }; -/* Structure to pass data from logging function to sinks */ -struct elapi_sink_context { +/* Structure to pass data from logging function to targets */ +struct elapi_target_pass_in_data { struct collection_item *event; struct elapi_dispatcher *handle; - char *format; - char *previous; - int previous_status; + uint32_t target_mask; +}; + +/* This is a structure that holds the information + * about the target. + */ +struct elapi_target_context { + /* Value associted with the + * target in the config file. + */ + uint32_t target_value; + /* Collection of pointers to sink objects */ + struct collection_item *sink_ref_list; + /* FIXME - other things that belong here are: + * state of the chain + * reference to the current sink + * reference to the preferred sink + * etc. + */ +}; + +/* The structure that describes the sink in the dispatcher */ +struct elapi_sink_context { + /* Inpit queue of a sink */ + struct collection_item *in_queue; + /* Pending list */ + struct collection_item *pending; + /* FIXME: add: + * sink's error status + * sink's common config data (common between all sinks) + * sink personal specific config data (config data specific to this sink) + */ + /* Is this a sink or async sink */ + uint32_t async_mode; }; /* The structure to hold a command and a result of the command execution */ @@ -102,13 +150,45 @@ int elapi_internal_sink_cleanup_handler(const char *sink, /* Create list of the sinks */ int elapi_internal_construct_sink_list(struct elapi_dispatcher *handle); -/* Function to add a sink to the collection */ -int elapi_internal_add_sink_to_collection(struct collection_item *sink_list, - char *sink, - char *appname); +/* Function to add a sink based on configuration */ +int elapi_internal_add_sink(struct collection_item **sink_ref, + char *sink, + struct elapi_dispatcher *handle); + +/* Create target object */ +int elapi_internal_create_target(struct elapi_target_context **context, + char *target, + struct elapi_dispatcher *handle); + +/* Destroy target object */ +void elapi_internal_destroy_target(struct elapi_target_context *context); + +/* Internal target cleanup function */ +int elapi_internal_target_cleanup_handler(const char *sink, + int sink_len, + int type, + void *data, + int length, + void *passed_data, + int *stop); + +/* Handler for logging through the targets */ +int elapi_internal_target_handler(const char *target, + int target_len, + int type, + void *data, + int length, + void *passed_data, + int *stop); + +/* Create list of targets for a dispatcher */ +int elapi_internal_construct_target_list(struct elapi_dispatcher *handle); /* Send ELAPI config errors into a file */ void elapi_internal_dump_errors_to_file(struct collection_item *error_list); +/* Print dispatcher internals for testing and debugin purposes */ +void elapi_internal_print_dispatcher(struct elapi_dispatcher *handle); + #endif diff --git a/common/elapi/elapi_test/Makefile.am b/common/elapi/elapi_test/Makefile.am new file mode 100644 index 000000000..b16102c83 --- /dev/null +++ b/common/elapi/elapi_test/Makefile.am @@ -0,0 +1,38 @@ +TRACE_LEVEL=@TRACE_VAR@ + +topdir=$(srcdir)/../.. + +AM_CFLAGS = -DELAPI_DEFAULT_CONFIG_DIR=\"$(srcdir)\" \ + -DELAPI_DEFAULT_CONFIG_APP_DIR=\"$(srcdir)\" \ + -DELAPI_DEFAULT_APP_NAME=\"elapi_ut\" \ + -DELAPI_DEFAULT_APP_NAME_SIZE=127 + +if HAVE_GCC + AM_CFLAGS += \ + -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual \ + -Wcast-align -Wwrite-strings +endif + +AM_CPPFLAGS = -I$(topdir) -I$(topdir)/ini -I$(topdir)/trace -I$(topdir)/collection -I$(topdir)/elapi $(TRACE_LEVEL) + +ACLOCAL_AMFLAGS = -I m4 + +# Build library +noinst_LTLIBRARIES = libelapi_test.la +libelapi_test_la_SOURCES = \ + ../elapi_event.c \ + ../elapi_log.c \ + ../elapi_internal.c \ + ../elapi_event.h \ + ../elapi_priv.h \ + ../elapi_sink.h \ + ../elapi_log.h \ + ../elapi_async.h \ + ../elapi.h + +# Build unit test +check_PROGRAMS = elapi_ut +elapi_ut_SOURCES = elapi_ut.c +elapi_ut_LDADD = libelapi_test.la ../../ini/libini_config.la ../../collection/libcollection.la + +TESTS = elapi_ut diff --git a/common/elapi/elapi_test/configure.ac b/common/elapi/elapi_test/configure.ac new file mode 100644 index 000000000..f2431bd38 --- /dev/null +++ b/common/elapi/elapi_test/configure.ac @@ -0,0 +1,26 @@ +AC_INIT([elapi],[0.0.1],[freeipa-devel@redhat.com]) +AC_CONFIG_SRCDIR([elapi_ut.c]) +AC_CONFIG_AUX_DIR([build]) +AM_INIT_AUTOMAKE([-Wall -Werror foreign]) +AC_PROG_CC +AC_PROG_LIBTOOL +AC_CONFIG_MACRO_DIR([m4]) +AC_PROG_INSTALL + +AM_CONDITIONAL([HAVE_GCC], [test "$ac_cv_prog_gcc" = yes]) + +m4_pattern_allow([AM_SILENT_RULES]) +AM_SILENT_RULES + +AC_CONFIG_HEADERS([config.h]) + +# Enable trace build +AC_ARG_ENABLE([trace], + [AS_HELP_STRING([--enable-trace[=LEVEL]],[build with low level tracing enabled])], + [trace_level="$enableval"], + [trace_level="0"]) +AS_IF([test ["$trace_level" -gt "0"] -a ["$trace_level" -lt "8"] ],[AC_SUBST([TRACE_VAR],["-DTRACE_LEVEL=$trace_level"])]) + + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/common/elapi/elapi_ut.c b/common/elapi/elapi_test/elapi_ut.c index 2866411f6..ed4342212 100644 --- a/common/elapi/elapi_ut.c +++ b/common/elapi/elapi_test/elapi_ut.c @@ -18,11 +18,15 @@ */ #include <stdio.h> +#include <stdarg.h> #define TRACE_HOME #include "trace.h" #include "elapi.h" #include "collection_tools.h" +/* THIS IS A PRIVATE HEADER - included for debugging purposes only! */ +#include "elapi_priv.h" + int simple_event_test(void) { int error = 0; @@ -64,25 +68,55 @@ int simple_event_test(void) E_EOARG); if (error) { - printf("Failed to set create event! %d\n", error); + printf("Failed to create simple event! %d\n", error); + return error; + } + + error = ELAPI_EVT_DEBUG(event); + if (error) { + printf("Failed to log event to debug ! %d\n", error); + elapi_destroy_event(event); return error; } - error = elapi_log(event); + error = ELAPI_EVT_LOG(event); + if (error) { + printf("Failed to log event to log ! %d\n", error); + elapi_destroy_event(event); + return error; + } + + error = ELAPI_EVT_AUDIT(event); + + if (error) { + printf("Failed to log event to audit ! %d\n", error); + elapi_destroy_event(event); + return error; + } elapi_destroy_event(event); + error = elapi_msg(E_TARGET_DEBUG, NULL, "a", "b", "c", "d", E_EOARG); if (error) { - printf("Failed to log event! %d\n", error); + printf("Failed to log \"debug\" event! %d\n", error); return error; } - error = elapi_msg(NULL, "a", "b", "c", "d", E_EOARG); + error = elapi_msg(E_TARGET_LOG, NULL, "a", "b", "c", "d", E_EOARG); if (error) { - printf("Failed to log event! %d\n", error); + printf("Failed to log \"log\" event! %d\n", error); return error; } + error = elapi_msg(E_TARGET_AUDIT, NULL, "a", "b", "c", "d", E_EOARG); + if (error) { + printf("Failed to log \"audit\" event! %d\n", error); + return error; + } + + /* Internal function to print dispatcher guts */ + elapi_internal_print_dispatcher(elapi_get_dispatcher()); + printf("Simple test success!\n"); return error; @@ -137,7 +171,7 @@ int complex_event_test(void) col_debug_collection(template, COL_TRAVERSE_FLAT); col_debug_collection(event, COL_TRAVERSE_FLAT); - error = elapi_log(event); + error = elapi_log(E_TARGET_DEBUG, event); elapi_destroy_event(event); @@ -245,7 +279,7 @@ int complex_event_test(void) return error; } - error = elapi_dsp_log(dispatcher, event); + error = elapi_dsp_log(E_TARGET_DEBUG, dispatcher, event); elapi_destroy_event(event); @@ -256,7 +290,7 @@ int complex_event_test(void) return error; } - error = elapi_dsp_log(dispatcher, event_copy); + error = elapi_dsp_log(E_TARGET_DEBUG, dispatcher, event_copy); elapi_destroy_event(event_copy); @@ -266,14 +300,14 @@ int complex_event_test(void) return error; } - error = elapi_dsp_msg(dispatcher, template, "a", "b", "c", "d", E_EOARG); + error = elapi_dsp_msg(E_TARGET_DEBUG, dispatcher, template, "a", "b", "c", "d", E_EOARG); if (error) { elapi_destroy_event_template(template); printf("Failed to log event! %d\n", error); return error; } - error = elapi_dsp_msg(dispatcher, NULL, "a", "b", "c", "d", E_EOARG); + error = elapi_dsp_msg(E_TARGET_DEBUG, dispatcher, NULL, "a", "b", "c", "d", E_EOARG); if (error) { elapi_destroy_event_template(template); printf("Failed to log event! %d\n", error); @@ -281,6 +315,9 @@ int complex_event_test(void) } elapi_destroy_event_template(template); + + elapi_internal_print_dispatcher(dispatcher); + elapi_destroy_dispatcher(dispatcher); return error; diff --git a/common/elapi/elapi_test/elapi_ut.conf b/common/elapi/elapi_test/elapi_ut.conf new file mode 100644 index 000000000..d15a4550d --- /dev/null +++ b/common/elapi/elapi_test/elapi_ut.conf @@ -0,0 +1,97 @@ +; This is a sample configuration file for ELAPI + +; The dispatcher section defines general configuration +; for the ELAPI. It has following configuration parameters: +; +; targets - (required) +; Defines possible logical destinations where message can be sent. +; It is one of the arguments of the calling interface. It is numeric. +; It is done this way for performance reasons so it is faster to compare. +; But in the configuration it is easier to deal with targets as strings. +; To overcome this issue each target is assigned a number in the INI file. +; The ELAPI convention is to have three default targets: +; "debug", "audit" and "log" but application developers can add others as needed. +; The default value for debug target is 1, for audit 2 and log is 4. +; Changing the value defined for debug to be 7 ( logical OR of 1, 2 and 4) +; will result in all messages sent into debug log. +; This might be convenient during troubleshooting and would allow seeing all +; events emitted by the application in one place. +; If you want the event to be sent into two targets at the same time +; add a target with different name but same value. +; For example if the log events need to go to local and remote files +; in parallel you would create another target: logremote +; and give it same value as log (which by convention is 4) + + + +[dispatcher] +targets=debug, audit, log + +; Inside section for each target the following parameters can be defined: +; +; value - (optional) +; Stores the value associated with this target. +; If the bit-wise AND of this value and the value provided by caller +; of the interface is greater than 0 the event is logged into the +; target destination. If omitted all events are sent to this target. +; sinks - (required) +; Defines the list of the sink names that need to be loaded +; each will have its own section. +; Only one of the sinks is active - first in the list. +; The list contains sinks in the fail over order. +; + +[debug] +value = 1 +sinks = debugfile, stderr + +[audit] +value = 2 +sinks = auditfile, syslog + +[log] +value = 4 +sinks = logfile, syslog + +; Each sink needs to have it's own section. +; +; COMMON FOR EVERY SINK +; +; provider - (required) +; Defines the name of the sink or the special reserved word to +; indecate that it is a sink provided natively by ELAPI library. +; +; Special sinks provided natively by ELAPI are: +; file +; stderr +; syslog +; +; Example: +; provider=file +; +; this would mean the destination for this sink is a file. +; +; If the sink is provided as an external plugin +; the syntax should be the following: +; +; provider=custom_audit +; +; In this case the ELAPI will try to load shared library with the name +; constructed using specified value. In the given example +; ELAPI will try to load libelapi_sink_custom_audit.so library. +; The general pattern is: libelapi_sink_<source>.so + +[debugfile] +provider=file + +[logfile] +provider=file + +[auditfile] +provider=file + +[stderr] +provider=stderr + +[syslog] +provider=syslog diff --git a/common/elapi/elapi_test/m4/.dir b/common/elapi/elapi_test/m4/.dir new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/common/elapi/elapi_test/m4/.dir diff --git a/common/elapi/elapi_ut.conf b/common/elapi/elapi_ut.conf deleted file mode 100644 index 19cbeb719..000000000 --- a/common/elapi/elapi_ut.conf +++ /dev/null @@ -1,6 +0,0 @@ -[dispatcher] -sinks = foo, bar, baz - - - -; test |