diff options
| author | Dmitri Pal <dpal@dpal.csb> | 2009-02-23 10:38:06 -0500 |
|---|---|---|
| committer | Dmitri Pal <dpal@dpal.csb> | 2009-02-23 10:38:06 -0500 |
| commit | d986aeb99fa33967374290bf7ce75eab76c6d446 (patch) | |
| tree | e85af838cd95b43c4f1be5bc2203a1a3474ba589 /sinks/syslog | |
| download | elapi_draft-d986aeb99fa33967374290bf7ce75eab76c6d446.tar.gz elapi_draft-d986aeb99fa33967374290bf7ce75eab76c6d446.tar.xz elapi_draft-d986aeb99fa33967374290bf7ce75eab76c6d446.zip | |
Initial commit.
Diffstat (limited to 'sinks/syslog')
| -rw-r--r-- | sinks/syslog/elapi_sink_syslog.c | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/sinks/syslog/elapi_sink_syslog.c b/sinks/syslog/elapi_sink_syslog.c new file mode 100644 index 0000000..d3a669d --- /dev/null +++ b/sinks/syslog/elapi_sink_syslog.c @@ -0,0 +1,287 @@ +/* Copyright */ + +#include <stdio.h> +#include <errno.h> +#include <malloc.h> +#include "elapi_sink.h" +#include "elapi_collection.h" +#include "elapi_debug.h" +#include "elapi_util.h" +#include "elapi_ini.h" + +/* FIXME - this should be taken from the config.h generated by autotools */ +#define SYSLOG_RETRY 60 +#define syslog_audit_config "/home/dpal/IPA/Code/elapi/etc/syslog_defaults.conf" +#define syslog_audit_dir "/home/dpal/IPA/Code/elapi/etc/syslog_defaults.d" + +/* FIXME there is currently no code + * to make sure we do not call syslog functions from multiple dispatchers. + * We probably should create a mutext at the load of the library and + * set a flag when the init function is called the first time + * and not call the openlog any more times. + * But I guess syslog can deal with this internally. + */ + + +struct syslog_event { + struct serial_data sd; + int priority; +} + + +/* Default conmfiguration for syslog */ +struct syslog_config { + int option; + int facility; + int level; + char *ident; +}; + +/* Internal function to intialize configuration */ +static int init_config(struct data_descriptor *dblock) +{ + struct syslog_conf *conf_data; + struct collection_item *file_config = (struct collection_item *)(NULL); + int found = 0; + int *option_cfg = (int *)(NULL); + int *facility_cfg = (int *)(NULL); + int *level_cfg = (int *)(NULL); + char *ident_cfg = NULL; + + DEBUG_STRING("init_config","Entry"); + + /* Allocate configuration data */ + conf_data = (struct syslog_conf *)(malloc(sizeof(struct syslog_config))); + if(conf_data == (struct syslog_conf *)(NULL)) return errno; + + /* Read configuration from the configuration file if any */ + (void)config_to_collection(dblock->appname, syslog_audit_config, syslog_audit_dir, &file_config); + + conf_data->option = LOG_ODELAY; + conf_data->facility = LOG_USER; + conf_data->level = LOG_INFO; + conf_data->ident = NULL; + + DEBUG_NUMBER("Option",conf_data->option); + DEBUG_NUMBER("Facility",conf_data->facility); + DEBUG_NUMBER("Level",conf_data->level); + DEBUG_STRING("Identity",conf_data->ident); + + /* Update defaults with settings from the file */ + error = get_value_from_config((void *)(&option_cfg),ELAPI_TYPE_INT, INI_DEFAULT_SECTION,"option",file_config); + if(error != EOK) { + /* There is fundamentally something wrong */ + DEBUG_NUMBER("Attempt to get option returned error",error); + return error; + } + + /* Get the value */ + if(option_cfg != (int *)(NULL)) { + conf_data->option = *option_cfg; + free((void *)(option_cfg); + } + + error = get_value_from_config((void *)(&facility_cfg),ELAPI_TYPE_INT, INI_DEFAULT_SECTION,"facility",file_config); + if(error != EOK) { + /* There is fundamentally something wrong */ + DEBUG_NUMBER("Attempt to get option returned error",error); + return error; + } + + /* Get the value */ + if(facility_cfg != (int *)(NULL)) { + conf_data->facility = *facility_cfg; + free((void *)(facility_cfg); + } + + error = get_value_from_config((void *)(&level_cfg),ELAPI_TYPE_INT, INI_DEFAULT_SECTION,"level",file_config); + if(error != EOK) { + /* There is fundamentally something wrong */ + DEBUG_NUMBER("Attempt to get option returned error",error); + return error; + } + + /* Get the value */ + if(level_cfg != (int *)(NULL)) { + conf_data->level = *level_cfg; + free((void *)(level_cfg); + } + + error = get_value_from_config((void *)(&ident_cfg),ELAPI_TYPE_STRING, INI_DEFAULT_SECTION,"identity",file_config); + if(error != EOK) { + /* There is fundamentally something wrong */ + DEBUG_NUMBER("Attempt to get option returned error",error); + return error; + } + + /* Get the value */ + if(ident_cfg != (char *)(NULL)) { + conf_data->ident = *ident_cfg; + free((void *)(ident_cfg); + } + + + DEBUG_NUMBER("Option (after conf file):",conf_data->option); + DEBUG_NUMBER("Facility (after conf file):",conf_data->facility); + DEBUG_NUMBER("Level (after conf file):",conf_data->level); + DEBUG_STRING("Identity (after conf file):",conf_data->ident); + + dblock->config = (void *)(conf_data); + + openlog(conf_data->ident,conf_data->option,conf_data->facility); + + DEBUG_STRING("init_config","Entry"); + return EOK; +} + +/***** Standard functions each facility has to provide *****/ +/* Initialize facility - open files, establish connnectons, etc... */ +static int syslog_sink_init(struct data_descriptor *dblock) +{ + struct syslog_event *event_storage; + int error; + + DEBUG_STRING("syslog_sink_init","Entry"); + + /* Prepare the block where the format function will store its data */ + errno = 0; + dblock->internal_data = NULL; + event_storage = (struct syslog_event *)(malloc(sizeof(struct syslog_event))); + if(event_storage == (struct syslog_event *)(NULL)) return errno; + + event_storage->sd.buffer = NULL; + event_storage->sd.size = 0; + event_storage->sd.length = 0; + event_storage->sd.nest_level = 0; + + dblock->internal_data = (void *)(event_storage); + + /* Prepare the configuration data block */ + if((error = init_config(dblock)) { + DEBUG_NUMBER("Failed to init config",error); + free(dblock->internal_data); + dblock->internal_data = NULL; + return error; + } + + DEBUG_NUMBER("DBLOCK in init",dblock); + DEBUG_NUMBER("internal data in init",dblock->internal_data); + + DEBUG_STRING("syslog_sink_init","Exit"); + return EOK; +} + + +/* Formatting calback */ +static int syslog_sink_format(struct data_descriptor *dblock,struct collection_item *event) +{ + struct syslog_event *event_storage; + struct syslog_config *config; + + int error = EOK; + + DEBUG_STRING("syslog_sink_format","Entry"); + DEBUG_NUMBER("DBLOCK in format",dblock); + DEBUG_NUMBER("internal data in format",dblock->internal_data); + + event_storage = (struct event_storage *)(dblock->internal_data); + config = (struct event_storage *)(dblock->config); + + event_storage->priority = config->level | config->facility; + + /* FIXME form priority here */ + + + + + /* Traverse collection */ + error = traverse_collection(event,ELAPI_TRAVERSE_DEFAULT | ELAPI_TRAVERSE_END ,serialize,(void *)(event_storage->sd)); + if(error) { + DEBUG_NUMBER("traverse_collection returned error",error); + return error; + } + + DEBUG_STRING("syslog_sink_format","Exit"); + return EOK; +} + + +/* Cleanup per event internal data after a failure */ +static void syslog_sink_cleanup(struct data_descriptor *dblock) +{ + struct syslog_event *event_storage; + struct syslog_config *config; + + DEBUG_STRING("syslog_sink_cleanup","Entry"); + + event_storage = (struct event_storage *)(dblock->internal_data); + config = (struct event_storage *)(dblock->config); + + if(event_storage->sd.buffer != NULL) { + free(event_storage->sd.buffer); + event_storage->sd.buffer = NULL; + event_storage->sd.size = 0; + event_storage->sd.length = 0; + event_storage->sd.nest_level = 0; + event_storage->priority = config->level | config->facility; + } + + DEBUG_STRING("syslog_sink_cleanup","Exit"); +} + +/* Close facility */ +static void syslog_sink_close(struct data_descriptor *dblock) +{ + DEBUG_STRING("syslog_sink_close","Entry"); + + if(dblock->internal_data != NULL) { + syslog_sink_cleanup(dblock); + free(dblock->internal_data); + free(dblock->config); + dblock->internal_data=NULL; + dblock->config=NULL; + } + + closelog(); + DEBUG_STRING("syslog_sink_close","Exit"); +} + + +/* Logging calback */ +static int syslog_sink_submit(struct data_descriptor *dblock) +{ + struct syslog_event *event_storage; + struct syslog_config *config; + + DEBUG_STRING("syslog_sink_submit","Entry"); + DEBUG_NUMBER("DBLOCK in submit",dblock); + DEBUG_NUMBER("internal data in submit",dblock->internal_data); + + event_storage = (struct serial_data *)(dblock->internal_data); + config = (struct event_storage *)(dblock->config); + + DEBUG_STRING("OUTPUT:",event_storage->db.buffer); + + fprintf(stderr,"%s %d %s\n",config->ident, event_storage->priority, event_storage->db.buffer); + + syslog_sink_cleanup(dblock); + + DEBUG_STRING("syslog_sink_submit","Exit"); + return EOK; +} + +/* Return a filled in structure */ +void get_sink_info(struct sink_capability *sink_cpb_block) +{ + DEBUG_STRING("get_sink_info","Entry"); + + sink_cpb_block->retry_interval = SYSLOG_RETRY; + sink_cpb_block->init_cb = syslog_sink_init; + sink_cpb_block->cleanup_cb = syslog_sink_cleanup; + sink_cpb_block->format_cb = syslog_sink_format; + sink_cpb_block->submit_cb = syslog_sink_submit; + sink_cpb_block->close_cb = syslog_sink_close; + + DEBUG_STRING("get_sink_info","Exit"); +} + |
