summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/collection/collection.h3
-rw-r--r--common/elapi/Makefile.am7
-rw-r--r--common/elapi/configure.ac2
-rw-r--r--common/elapi/elapi_event.c2
-rw-r--r--common/elapi/elapi_event.h1
-rw-r--r--common/elapi/elapi_internal.c513
-rw-r--r--common/elapi/elapi_log.c159
-rw-r--r--common/elapi/elapi_log.h40
-rw-r--r--common/elapi/elapi_priv.h110
-rw-r--r--common/elapi/elapi_test/Makefile.am38
-rw-r--r--common/elapi/elapi_test/configure.ac26
-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.conf97
-rw-r--r--common/elapi/elapi_test/m4/.dir0
-rw-r--r--common/elapi/elapi_ut.conf6
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