From 19bbdd68a491721dd4aeff7cacea51148ce3a9b9 Mon Sep 17 00:00:00 2001 From: Edward Rudd Date: Fri, 24 Oct 2008 13:55:48 +0000 Subject: add logging function added @todo tags for what needs to be finished --- utility/config.c | 31 +++++++++------- utility/config.h | 6 ++++ utility/database.c | 102 ++++++++++++++++++++++++++++++++++------------------- utility/logparse.c | 28 +++++++++------ utility/logparse.h | 2 +- utility/shell.c | 20 ++++++++--- utility/util.c | 39 ++++++++++++++++++++ utility/util.h | 7 ++++ 8 files changed, 170 insertions(+), 65 deletions(-) diff --git a/utility/config.c b/utility/config.c index d3a6ca5..ccdc6e5 100644 --- a/utility/config.c +++ b/utility/config.c @@ -23,19 +23,6 @@ static apr_status_t config_set_string(config_t *cfg, config_opt_t *opt, return APR_SUCCESS; } -static apr_status_t config_set_int(config_t *cfg, config_opt_t *opt, int argc, - const char **argv) __attribute__ ((__unused__)); -static apr_status_t config_set_int(config_t *cfg, config_opt_t *opt, int argc, - const char **argv) -{ - int offset = (int)(long)opt->data; - int *data = (int *)((void *)cfg + offset); - if (argc != 2) - return APR_EINVAL; - *data = apr_atoi64(argv[1]); - return APR_SUCCESS; -} - static apr_status_t config_set_flag(config_t *cfg, config_opt_t *opt, int argc, const char **argv) { @@ -329,6 +316,24 @@ config_t *config_create(apr_pool_t *p) return cfg; } +apr_status_t config_check(config_t *cfg) +{ + apr_status_t ret = APR_SUCCESS; + if (!cfg->dbdriver || !cfg->dbparams) { + printf("Database configuration is missing\n"); + ret = APR_EINVAL; + } + if (!cfg->table) { + printf("No Log Table defined\n"); + ret = APR_EINVAL; + } + if (apr_is_empty_array(cfg->output_fields)) { + printf("No Output Fields Defined\n"); + ret = APR_EINVAL; + } + return ret; +} + static int config_merge(void *rec, const char *key, const char *value) { config_t *cfg = (config_t *)rec; diff --git a/utility/config.h b/utility/config.h index 0e80856..611e9de 100644 --- a/utility/config.h +++ b/utility/config.h @@ -25,6 +25,7 @@ struct config_t { loglevel_e loglevel; /** error_log */ apr_file_t *errorlog_fp; + apr_pool_t *errorlog_p; /** input directory of log files */ const char *input_dir; @@ -134,6 +135,11 @@ void config_init(apr_pool_t *p); */ void config_dump(config_t *cfg); +/** + * Checks the configuration to ensure all the required settings are set + */ +apr_status_t config_check(config_t *cfg); + /** * Creates the default configuration */ diff --git a/utility/database.c b/utility/database.c index a979268..45022da 100644 --- a/utility/database.c +++ b/utility/database.c @@ -3,6 +3,8 @@ #include "apr_dbd.h" #include "apr_strings.h" +#include "util.h" + struct config_dbd_t { const apr_dbd_driver_t *driver; apr_dbd_t *dbd; @@ -18,17 +20,26 @@ void database_init(apr_pool_t *p) apr_status_t database_connect(config_t *cfg) { apr_status_t rv; + if (!cfg->dbdriver || !cfg->dbparams) + return APR_EINVAL; if (!cfg->dbconn) { cfg->dbconn = apr_pcalloc(cfg->pool, sizeof(config_dbd_t)); } rv = apr_dbd_get_driver(cfg->pool, cfg->dbdriver, &(cfg->dbconn->driver)); - if (rv) + if (rv) { + logging_log(cfg, LOGLEVEL_ERROR, + "Could not load database driver %s. Error %d", cfg->dbdriver, + rv); return rv; + } rv = apr_dbd_open(cfg->dbconn->driver, cfg->pool, cfg->dbparams, &(cfg->dbconn->dbd)); - if (rv) + if (rv) { + logging_log(cfg, LOGLEVEL_ERROR, + "Could not connect to database. Error %d", rv); return rv; + } return APR_SUCCESS; } @@ -38,6 +49,56 @@ apr_status_t database_disconnect(config_t *cfg) return apr_dbd_close(cfg->dbconn->driver, cfg->dbconn->dbd); } +static apr_dbd_prepared_t *database_prepare_insert(config_t *cfg, apr_pool_t *p) +{ + apr_status_t rv; + char *sql; + int i, f; + struct iovec *vec; + apr_dbd_prepared_t *stmt; + int nfs = cfg->output_fields->nelts; + config_output_field_t *ofields; + + ofields = (config_output_field_t *)cfg->output_fields->elts; + + vec = apr_palloc(p, (nfs*2 + 5) * sizeof(struct iovec)); + sql = apr_palloc(p, (nfs*3)); + + vec[0].iov_base = "INSERT INTO "; + vec[0].iov_len = 12; + vec[1].iov_base = (void *)cfg->table; + vec[1].iov_len = strlen(cfg->table); + vec[2].iov_base = " ("; + vec[2].iov_len = 2; + for (i=3, f=0; fdbconn->driver, cfg->pool, cfg->dbconn->dbd, sql, + "INSERT", &stmt); + + if (rv) { + printf("DB Error: %s\n", apr_dbd_error(cfg->dbconn->driver, + cfg->dbconn->dbd, rv)); + return NULL; + } + return stmt; +} apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) { apr_status_t rv; @@ -47,41 +108,8 @@ apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) nfs = cfg->output_fields->nelts; // Prepare statement if (!cfg->dbconn->stmt) { - char *sql; - int i; - struct iovec *vec; - vec = apr_palloc(p, (nfs*2 + 5) * sizeof(struct iovec)); - sql = apr_palloc(p, (nfs*3)); - vec[0].iov_base = "INSERT INTO "; - vec[0].iov_len = 12; - vec[1].iov_base = (void *)cfg->table; - vec[1].iov_len = strlen(cfg->table); - vec[2].iov_base = " ("; - vec[2].iov_len = 2; - for (i=3, f=0; fdbconn->stmt = database_prepare_insert(cfg, p); cfg->dbconn->args = apr_palloc(cfg->pool, nfs * sizeof(char *)); - rv = apr_dbd_prepare(cfg->dbconn->driver, cfg->pool, cfg->dbconn->dbd, - sql, "INSERT", &(cfg->dbconn->stmt)); - if (rv) { - printf("DB Error: %s\n", apr_dbd_error(cfg->dbconn->driver, - cfg->dbconn->dbd, rv)); - return rv; - } } for (f=0; fdbconn->args[f] = apr_table_get(data, ofields[f].field); @@ -95,3 +123,5 @@ apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) } return APR_SUCCESS; } + +/** @todo implement transactions */ diff --git a/utility/logparse.c b/utility/logparse.c index dfe2e9b..4b5ab40 100644 --- a/utility/logparse.c +++ b/utility/logparse.c @@ -15,7 +15,7 @@ apr_hash_t *g_parser_funcs; static apr_status_t parser_func_regexmatch(apr_pool_t *p, config_t *cfg, - config_output_field_t *field, const char *value, char **ret) + config_output_field_t *field, const char *value, const char **ret) { struct { ap_regex_t *rx; @@ -48,7 +48,7 @@ static apr_status_t parser_func_regexmatch(apr_pool_t *p, config_t *cfg, } static apr_status_t parser_func_totimestamp(apr_pool_t *p, config_t *cfg, - config_output_field_t *field, const char *value, char **ret) + config_output_field_t *field, const char *value, const char **ret) { time_t time; struct tm ts; @@ -63,12 +63,18 @@ static apr_status_t parser_func_totimestamp(apr_pool_t *p, config_t *cfg, } static apr_status_t parser_func_machineid(apr_pool_t *p, config_t *cfg, - config_output_field_t *field, const char *value, char **ret) + config_output_field_t *field, const char *value, const char **ret) { - *ret = apr_pstrdup(p,cfg->machineid); + if (cfg->machineid) { + *ret = apr_pstrdup(p,cfg->machineid); + } else { + *ret = field->def; + } return APR_SUCCESS; } +/** @todo Implement Query arg ripping function */ + parser_func_t parser_get_func(const char *name) { return apr_hash_get(g_parser_funcs, name, APR_HASH_KEY_STRING); @@ -258,6 +264,7 @@ apr_status_t parse_logfile(config_t *cfg, const char *filename) rv = apr_file_open(&file, filename, APR_FOPEN_READ | APR_BUFFERED, APR_OS_DEFAULT, tp); if (rv != APR_SUCCESS) { + logging_log(cfg, LOGLEVEL_ERROR, "Could not open %s",filename); printf("Could not open %s\n", filename); return rv; } @@ -298,7 +305,7 @@ apr_status_t parse_processline(apr_pool_t *ptemp, config_t *cfg, char **argv, in config_output_field_t *ofields; apr_table_t *datain; apr_table_t *dataout; - apr_status_t rv; + apr_status_t rv = APR_SUCCESS; int i; fmt = apr_hash_get(cfg->log_formats, cfg->logformat, APR_HASH_KEY_STRING); @@ -326,21 +333,20 @@ apr_status_t parse_processline(apr_pool_t *ptemp, config_t *cfg, char **argv, in } if (!ofields[i].func) { apr_table_setn(dataout,ofields[i].field, val); - //printf("S: %s = %s\n",ofields[i].field, val); } else { - char *ret = NULL; + const char *ret = NULL; rv = ((parser_func_t)ofields[i].func)(ptemp, cfg, &ofields[i], val, &ret); if (rv) return rv; apr_table_setn(dataout, ofields[i].field, ret); - //printf("S: %s = %s\n",ofields[i].field, ret); } } /** @todo Run Post Filters here */ // Process DB Query - rv = database_insert(cfg, ptemp, dataout); - if (rv) return rv; - return APR_SUCCESS; + if (!cfg->dryrun) { + rv = database_insert(cfg, ptemp, dataout); + } + return rv; } diff --git a/utility/logparse.h b/utility/logparse.h index 53b376b..816624a 100644 --- a/utility/logparse.h +++ b/utility/logparse.h @@ -4,7 +4,7 @@ #include "config.h" typedef apr_status_t (*parser_func_t)(apr_pool_t *p, config_t *cfg, - config_output_field_t *field, const char *value, char **ret); + config_output_field_t *field, const char *value, const char **ret); parser_func_t parser_get_func(const char *name); diff --git a/utility/shell.c b/utility/shell.c index 94cca35..b289bce 100644 --- a/utility/shell.c +++ b/utility/shell.c @@ -10,6 +10,7 @@ #include "config.h" #include "logparse.h" #include "database.h" +#include "util.h" const apr_getopt_option_t _opt_config[] = { {"machineid", 'm', 1, "Machine ID for the log file"}, @@ -127,6 +128,7 @@ int main(int argc, const char *const argv[]) parser_init(pool); config_init(pool); database_init(pool); + logging_init(pool); // Process configuration file base = config_create(pool); rv = config_read(base, apr_table_get(args,"Config"), args); @@ -139,11 +141,18 @@ int main(int argc, const char *const argv[]) } config_dump(base); + if (config_check(base)) { + printf("Please correct the configuration\n"); + exit(1); + } + // Find files and parse parser_find_logs(base); - if ((rv = database_connect(base))) { - printf("Error Connecting to Database: %d\n",rv); - exit(1); + if (!base->dryrun) { + if ((rv = database_connect(base))) { + printf("Error Connecting to Database: %d\n",rv); + exit(1); + } } if (!apr_is_empty_array(base->input_files)) { char **filelist; @@ -156,6 +165,9 @@ int main(int argc, const char *const argv[]) } else { printf("No input files\n"); } - database_disconnect(base); + if (!base->dryrun) { + database_disconnect(base); + } + /** @todo summary goes here */ return 0; } diff --git a/utility/util.c b/utility/util.c index ef3ea68..cb6898d 100644 --- a/utility/util.c +++ b/utility/util.c @@ -1,7 +1,11 @@ #include "util.h" #include "apr_strings.h" #include "apr_lib.h" +#include "apr_file_io.h" +#include "config.h" + +#include char *lowerstr(apr_pool_t *pool, const char *input) { @@ -26,3 +30,38 @@ void line_chomp(char *str) } } } + +void logging_init(config_t *cfg) +{ + if (cfg->errorlog) { + apr_file_open(&cfg->errorlog_fp, cfg->errorlog, + APR_FOPEN_CREATE | APR_FOPEN_WRITE | APR_BUFFERED, + APR_OS_DEFAULT, + cfg->pool); + apr_pool_create(&cfg->errorlog_p, cfg->pool); + } +} + +/** + * @todo implement logging + */ +void logging_log(config_t *cfg, loglevel_e level, const char *fmt, ...) +{ + va_list ap; + struct iovec vec[2]; + apr_size_t blen; + + if (!cfg->errorlog_fp || cfg->loglevel < level) return; + + va_start(ap, fmt); + apr_pool_clear(cfg->errorlog_p); + + vec[0].iov_base = apr_pvsprintf(cfg->errorlog_p, fmt, ap); + vec[0].iov_len = strlen(vec[0].iov_base); + vec[1].iov_base = "\n"; + vec[1].iov_len = 1; + + apr_file_writev(cfg->errorlog_fp,vec,2,&blen); + + va_end(ap); +} diff --git a/utility/util.h b/utility/util.h index 8c48474..9e3aed3 100644 --- a/utility/util.h +++ b/utility/util.h @@ -3,6 +3,8 @@ #include "apr_pools.h" +#include "config.h" + char *lowerstr(apr_pool_t *pool, const char *input); /** @@ -10,4 +12,9 @@ char *lowerstr(apr_pool_t *pool, const char *input); */ void line_chomp(char *str); +void logging_init(config_t *cfg); + +void logging_log(config_t *cfg, loglevel_e level, const char *fmt, ...) + __attribute__((format(printf, 3, 4))); + #endif /*UTIL_H_*/ -- cgit