diff options
| -rw-r--r-- | utility/Makefile.in | 3 | ||||
| -rw-r--r-- | utility/config.c | 57 | ||||
| -rw-r--r-- | utility/database.c | 36 | ||||
| -rw-r--r-- | utility/database.h | 6 | ||||
| -rw-r--r-- | utility/logparse.c | 80 | ||||
| -rw-r--r-- | utility/logparse.h | 4 | ||||
| -rw-r--r-- | utility/mod_log_sql.conf | 10 | ||||
| -rw-r--r-- | utility/shell.c | 2 | ||||
| -rw-r--r-- | utility/util.c | 10 | ||||
| -rw-r--r-- | utility/util.h | 2 |
10 files changed, 177 insertions, 33 deletions
diff --git a/utility/Makefile.in b/utility/Makefile.in index eeb26b8..c7a5e3d 100644 --- a/utility/Makefile.in +++ b/utility/Makefile.in | |||
| @@ -6,7 +6,8 @@ builddir = @abs_builddir@ | |||
| 6 | 6 | ||
| 7 | #@APR_CFLAGS@ | 7 | #@APR_CFLAGS@ |
| 8 | CFLAGS = -g3 -Wall -fno-strict-aliasing \ | 8 | CFLAGS = -g3 -Wall -fno-strict-aliasing \ |
| 9 | @APR_INCLUDES@ @APU_INCLUDES@ @PCRE_CFLAGS@ | 9 | @APR_INCLUDES@ @APU_INCLUDES@ @PCRE_CFLAGS@ \ |
| 10 | -I$(top_srcdir)/include | ||
| 10 | CPPFLAGS = @APR_CPPFLAGS@ | 11 | CPPFLAGS = @APR_CPPFLAGS@ |
| 11 | LDFLAGS = @APR_LDFLAGS@ @APU_LDFLAGS@ @PCRE_LIBS@ | 12 | LDFLAGS = @APR_LDFLAGS@ @APU_LDFLAGS@ @PCRE_LIBS@ |
| 12 | 13 | ||
diff --git a/utility/config.c b/utility/config.c index fca2f77..28bb5cd 100644 --- a/utility/config.c +++ b/utility/config.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "config.h" | 9 | #include "config.h" |
| 10 | #include "util.h" | 10 | #include "util.h" |
| 11 | #include "logparse.h" | 11 | #include "logparse.h" |
| 12 | #include "autoconfig.h" | ||
| 12 | 13 | ||
| 13 | apr_hash_t *g_config_opts; | 14 | apr_hash_t *g_config_opts; |
| 14 | 15 | ||
| @@ -148,9 +149,19 @@ static apr_status_t config_set_filter(config_t *cfg, config_opt_t *opt, | |||
| 148 | { | 149 | { |
| 149 | int argn = 1; | 150 | int argn = 1; |
| 150 | config_filter_t *filter; | 151 | config_filter_t *filter; |
| 151 | filter = apr_pcalloc(cfg->pool, sizeof(config_filter_t)); | 152 | switch (opt->name[1]) { |
| 153 | case 'i': //line | ||
| 154 | filter = apr_array_push(cfg->linefilters); | ||
| 155 | break; | ||
| 156 | case 'r': //pre | ||
| 157 | filter = apr_array_push(cfg->prefilters); | ||
| 158 | break; | ||
| 159 | case 'o': //post | ||
| 160 | filter = apr_array_push(cfg->postfilters); | ||
| 161 | break; | ||
| 162 | } | ||
| 152 | 163 | ||
| 153 | if (opt->name[0]!='L') { // Pre or post 2-3 args | 164 | if (opt->name[0]=='P') { // Pre or post 2-3 args |
| 154 | if (argc == 1) | 165 | if (argc == 1) |
| 155 | return APR_EINVAL; | 166 | return APR_EINVAL; |
| 156 | filter->field = apr_pstrdup(cfg->pool, argv[1]); | 167 | filter->field = apr_pstrdup(cfg->pool, argv[1]); |
| @@ -158,16 +169,20 @@ static apr_status_t config_set_filter(config_t *cfg, config_opt_t *opt, | |||
| 158 | } // Otherwise Line based only 1-2 args (no field) | 169 | } // Otherwise Line based only 1-2 args (no field) |
| 159 | if (argc <= argn) | 170 | if (argc <= argn) |
| 160 | return APR_EINVAL; | 171 | return APR_EINVAL; |
| 161 | if (argv[argn][0] == '+') | 172 | if (*argv[argn] == '+') |
| 162 | argn++; | 173 | argn++; |
| 163 | if (argv[argn][0] == '-') { | 174 | if (*argv[argn] == '-') { |
| 164 | filter->negative = 1; | 175 | filter->negative = 1; |
| 165 | argn++; | 176 | argn++; |
| 166 | } | 177 | } |
| 178 | if (filter->negative && argc == argn) { | ||
| 179 | // if no filter for negative.. that's ok.. Assume ALL | ||
| 180 | return APR_SUCCESS; | ||
| 181 | } | ||
| 167 | if (argc <= argn) | 182 | if (argc <= argn) |
| 168 | return APR_EINVAL; | 183 | return APR_EINVAL; |
| 169 | filter->filter = apr_pstrdup(cfg->pool, argv[argn]); | 184 | filter->filter = apr_pstrdup(cfg->pool, argv[argn]); |
| 170 | filter->regex = ap_pregcomp(cfg->pool, filter->filter, AP_REG_ICASE); | 185 | filter->regex = ap_pregcomp(cfg->pool, filter->filter, AP_REG_EXTENDED|AP_REG_ICASE); |
| 171 | return APR_SUCCESS; | 186 | return APR_SUCCESS; |
| 172 | } | 187 | } |
| 173 | 188 | ||
| @@ -176,6 +191,7 @@ void config_dump(config_t *cfg) | |||
| 176 | apr_hash_index_t *hi; | 191 | apr_hash_index_t *hi; |
| 177 | int i; | 192 | int i; |
| 178 | config_output_field_t *fields; | 193 | config_output_field_t *fields; |
| 194 | config_filter_t *filters; | ||
| 179 | 195 | ||
| 180 | printf("ErrorLog: %s\n", cfg->errorlog); | 196 | printf("ErrorLog: %s\n", cfg->errorlog); |
| 181 | printf("LogLevel: %d\n", cfg->loglevel); | 197 | printf("LogLevel: %d\n", cfg->loglevel); |
| @@ -224,6 +240,26 @@ void config_dump(config_t *cfg) | |||
| 224 | } | 240 | } |
| 225 | printf("\n"); | 241 | printf("\n"); |
| 226 | } | 242 | } |
| 243 | printf("Filters:\n>> Line:\n"); | ||
| 244 | filters = cfg->linefilters->elts; | ||
| 245 | for (i=0; i<cfg->linefilters->nelts; i++) { | ||
| 246 | printf(">>>> %c \"%s\" (%pp)\n",filters[i].negative ? '-':'+', | ||
| 247 | filters[i].filter, filters[i].regex); | ||
| 248 | } | ||
| 249 | printf(">> Pre:\n"); | ||
| 250 | filters = cfg->prefilters->elts; | ||
| 251 | for (i=0; i<cfg->prefilters->nelts; i++) { | ||
| 252 | printf(">>>> %s %c \"%s\" (%pp)\n", | ||
| 253 | filters[i].field, filters[i].negative ? '-':'+', | ||
| 254 | filters[i].filter, filters[i].regex); | ||
| 255 | } | ||
| 256 | printf(">> Post:\n"); | ||
| 257 | filters = cfg->postfilters->elts; | ||
| 258 | for (i=0; i<cfg->postfilters->nelts; i++) { | ||
| 259 | printf(">>>> %s %c \"%s\" (%pp)\n", | ||
| 260 | filters[i].field, filters[i].negative ? '-':'+', | ||
| 261 | filters[i].filter, filters[i].regex); | ||
| 262 | } | ||
| 227 | 263 | ||
| 228 | printf("DryRun: %d\n", cfg->dryrun); | 264 | printf("DryRun: %d\n", cfg->dryrun); |
| 229 | printf("Summary: %d\n", cfg->summary); | 265 | printf("Summary: %d\n", cfg->summary); |
| @@ -309,10 +345,13 @@ config_t *config_create(apr_pool_t *p) | |||
| 309 | cfg->loglevel = LOGLEVEL_ERROR; | 345 | cfg->loglevel = LOGLEVEL_ERROR; |
| 310 | cfg->summary = 1; | 346 | cfg->summary = 1; |
| 311 | cfg->transactions = 1; | 347 | cfg->transactions = 1; |
| 312 | cfg->input_files = apr_array_make(cfg->pool, 10, sizeof(char *)); | 348 | cfg->input_files = apr_array_make(cfg->pool, 2, sizeof(char *)); |
| 313 | cfg->log_formats = apr_hash_make(cfg->pool); | 349 | cfg->log_formats = apr_hash_make(cfg->pool); |
| 314 | cfg->output_fields = apr_array_make(cfg->pool, 10, | 350 | cfg->output_fields = apr_array_make(cfg->pool, 10, |
| 315 | sizeof(config_output_field_t)); | 351 | sizeof(config_output_field_t)); |
| 352 | cfg->linefilters = apr_array_make(cfg->pool, 2, sizeof(config_filter_t)); | ||
| 353 | cfg->prefilters = apr_array_make(cfg->pool, 2, sizeof(config_filter_t)); | ||
| 354 | cfg->postfilters = apr_array_make(cfg->pool, 2, sizeof(config_filter_t)); | ||
| 316 | return cfg; | 355 | return cfg; |
| 317 | } | 356 | } |
| 318 | 357 | ||
| @@ -335,6 +374,12 @@ apr_status_t config_check(config_t *cfg) | |||
| 335 | logging_log(cfg, LOGLEVEL_NOISE, "CONFIG: No Input Log Formats Defined"); | 374 | logging_log(cfg, LOGLEVEL_NOISE, "CONFIG: No Input Log Formats Defined"); |
| 336 | ret = APR_EINVAL; | 375 | ret = APR_EINVAL; |
| 337 | } | 376 | } |
| 377 | #if !defined(HAVE_APR_DBD_TRANSACTION_MODE_GET) | ||
| 378 | if (cfg->transactions) { | ||
| 379 | logging_log(cfg, LOGLEVEL_NOISE, "CONFIG: Disabling Transaction Support. Requires apr-util 1.3.0 or higher"); | ||
| 380 | cfg->transactions = 0; | ||
| 381 | } | ||
| 382 | #endif | ||
| 338 | return ret; | 383 | return ret; |
| 339 | } | 384 | } |
| 340 | 385 | ||
diff --git a/utility/database.c b/utility/database.c index c4e4bc9..0d1d4f7 100644 --- a/utility/database.c +++ b/utility/database.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | #include "apr_strings.h" | 4 | #include "apr_strings.h" |
| 5 | 5 | ||
| 6 | #include "util.h" | 6 | #include "util.h" |
| 7 | #include "mysql/mysql.h" | 7 | #include "autoconfig.h" |
| 8 | 8 | ||
| 9 | struct config_dbd_t { | 9 | struct config_dbd_t { |
| 10 | const apr_dbd_driver_t *driver; | 10 | const apr_dbd_driver_t *driver; |
| @@ -30,7 +30,7 @@ apr_status_t database_connect(config_t *cfg) | |||
| 30 | if (rv) { | 30 | if (rv) { |
| 31 | 31 | ||
| 32 | logging_log(cfg, LOGLEVEL_ERROR, | 32 | logging_log(cfg, LOGLEVEL_ERROR, |
| 33 | "Could not load database driver %s. Error %s", cfg->dbdriver, | 33 | "DB: Could not load database driver %s. Error %s", cfg->dbdriver, |
| 34 | logging_strerror(rv)); | 34 | logging_strerror(rv)); |
| 35 | return rv; | 35 | return rv; |
| 36 | } | 36 | } |
| @@ -39,7 +39,7 @@ apr_status_t database_connect(config_t *cfg) | |||
| 39 | &(cfg->dbconn->dbd)); | 39 | &(cfg->dbconn->dbd)); |
| 40 | if (rv) { | 40 | if (rv) { |
| 41 | logging_log(cfg, LOGLEVEL_ERROR, | 41 | logging_log(cfg, LOGLEVEL_ERROR, |
| 42 | "Could not connect to database. Error %s", logging_strerror(rv)); | 42 | "DB: Could not connect to database. Error %s", logging_strerror(rv)); |
| 43 | return rv; | 43 | return rv; |
| 44 | } | 44 | } |
| 45 | 45 | ||
| @@ -89,13 +89,13 @@ static apr_dbd_prepared_t *database_prepare_insert(config_t *cfg, apr_pool_t *p) | |||
| 89 | 89 | ||
| 90 | sql = apr_pstrcatv(p, vec, i+2, NULL); | 90 | sql = apr_pstrcatv(p, vec, i+2, NULL); |
| 91 | 91 | ||
| 92 | logging_log(cfg, LOGLEVEL_DEBUG, "Generated SQL: %s", sql); | 92 | logging_log(cfg, LOGLEVEL_DEBUG, "DB: Generated SQL: %s", sql); |
| 93 | 93 | ||
| 94 | rv = apr_dbd_prepare(cfg->dbconn->driver, cfg->pool, cfg->dbconn->dbd, sql, | 94 | rv = apr_dbd_prepare(cfg->dbconn->driver, cfg->pool, cfg->dbconn->dbd, sql, |
| 95 | "INSERT", &stmt); | 95 | "INSERT", &stmt); |
| 96 | 96 | ||
| 97 | if (rv) { | 97 | if (rv) { |
| 98 | logging_log(cfg, LOGLEVEL_ERROR, "Unable to Prepare SQL insert: %s", | 98 | logging_log(cfg, LOGLEVEL_NOISE, "DB: Unable to Prepare SQL insert: %s", |
| 99 | apr_dbd_error(cfg->dbconn->driver, cfg->dbconn->dbd, rv)); | 99 | apr_dbd_error(cfg->dbconn->driver, cfg->dbconn->dbd, rv)); |
| 100 | return NULL; | 100 | return NULL; |
| 101 | } | 101 | } |
| @@ -112,7 +112,6 @@ apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) | |||
| 112 | if (!cfg->dbconn->stmt) { | 112 | if (!cfg->dbconn->stmt) { |
| 113 | cfg->dbconn->stmt = database_prepare_insert(cfg, p); | 113 | cfg->dbconn->stmt = database_prepare_insert(cfg, p); |
| 114 | if (!cfg->dbconn->stmt) { | 114 | if (!cfg->dbconn->stmt) { |
| 115 | logging_log(cfg, LOGLEVEL_NOISE, "Unable to prepare SQL statement"); | ||
| 116 | return APR_EINVAL; | 115 | return APR_EINVAL; |
| 117 | } | 116 | } |
| 118 | cfg->dbconn->args = apr_palloc(cfg->pool, nfs * sizeof(char *)); | 117 | cfg->dbconn->args = apr_palloc(cfg->pool, nfs * sizeof(char *)); |
| @@ -123,7 +122,7 @@ apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) | |||
| 123 | rv = apr_dbd_pquery(cfg->dbconn->driver, p, cfg->dbconn->dbd, &f, | 122 | rv = apr_dbd_pquery(cfg->dbconn->driver, p, cfg->dbconn->dbd, &f, |
| 124 | cfg->dbconn->stmt, nfs, cfg->dbconn->args); | 123 | cfg->dbconn->stmt, nfs, cfg->dbconn->args); |
| 125 | if (rv) { | 124 | if (rv) { |
| 126 | logging_log(cfg, LOGLEVEL_ERROR, "Unable to Insert SQL: %s", | 125 | logging_log(cfg, LOGLEVEL_ERROR, "DB: Unable to Insert SQL: %s", |
| 127 | apr_dbd_error(cfg->dbconn->driver, cfg->dbconn->dbd, rv)); | 126 | apr_dbd_error(cfg->dbconn->driver, cfg->dbconn->dbd, rv)); |
| 128 | return rv; | 127 | return rv; |
| 129 | } | 128 | } |
| @@ -131,3 +130,26 @@ apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) | |||
| 131 | } | 130 | } |
| 132 | 131 | ||
| 133 | /** @todo implement transactions */ | 132 | /** @todo implement transactions */ |
| 133 | apr_status_t database_trans_start(config_t *cfg, apr_pool_t *p) | ||
| 134 | { | ||
| 135 | #if HAVE_APR_DBD_TRANSACTION_MODE_GET | ||
| 136 | #else | ||
| 137 | return APR_SUCCESS; | ||
| 138 | #endif | ||
| 139 | } | ||
| 140 | |||
| 141 | apr_status_t database_trans_stop(config_t *cfg, apr_pool_t *p) | ||
| 142 | { | ||
| 143 | #if HAVE_APR_DBD_TRANSACTION_MODE_GET | ||
| 144 | #else | ||
| 145 | return APR_SUCCESS; | ||
| 146 | #endif | ||
| 147 | } | ||
| 148 | |||
| 149 | apr_status_t database_trans_abort(config_t *cfg) | ||
| 150 | { | ||
| 151 | #if HAVE_APR_DBD_TRANSACTION_MODE_GET | ||
| 152 | #else | ||
| 153 | return APR_SUCCESS; | ||
| 154 | #endif | ||
| 155 | } | ||
diff --git a/utility/database.h b/utility/database.h index fd24994..eed8898 100644 --- a/utility/database.h +++ b/utility/database.h | |||
| @@ -13,4 +13,10 @@ apr_status_t database_disconnect(config_t *cfg); | |||
| 13 | 13 | ||
| 14 | apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data); | 14 | apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data); |
| 15 | 15 | ||
| 16 | apr_status_t database_trans_start(config_t *cfg, apr_pool_t *p); | ||
| 17 | |||
| 18 | apr_status_t database_trans_stop(config_t *cfg, apr_pool_t *p); | ||
| 19 | |||
| 20 | apr_status_t database_trans_abort(config_t *cfg); | ||
| 21 | |||
| 16 | #endif /*DATABASE_H_*/ | 22 | #endif /*DATABASE_H_*/ |
diff --git a/utility/logparse.c b/utility/logparse.c index 6a21964..ac70ee2 100644 --- a/utility/logparse.c +++ b/utility/logparse.c | |||
| @@ -349,12 +349,12 @@ apr_status_t parse_logfile(config_t *cfg, const char *filename) | |||
| 349 | apr_pool_create(&tp, cfg->pool); | 349 | apr_pool_create(&tp, cfg->pool); |
| 350 | apr_pool_create(&targp, tp); | 350 | apr_pool_create(&targp, tp); |
| 351 | 351 | ||
| 352 | logging_log(cfg, LOGLEVEL_NOTICE, "Begin Parsing Log File '%s'", filename); | 352 | logging_log(cfg, LOGLEVEL_NOTICE, "PARSER: Begin Parsing Log File '%s'", filename); |
| 353 | 353 | ||
| 354 | rv = apr_file_open(&file, filename, APR_FOPEN_READ | APR_BUFFERED, | 354 | rv = apr_file_open(&file, filename, APR_FOPEN_READ | APR_BUFFERED, |
| 355 | APR_OS_DEFAULT, tp); | 355 | APR_OS_DEFAULT, tp); |
| 356 | if (rv != APR_SUCCESS) { | 356 | if (rv != APR_SUCCESS) { |
| 357 | logging_log(cfg, LOGLEVEL_NOISE, "Could not open %s", filename); | 357 | logging_log(cfg, LOGLEVEL_NOISE, "PARSER: Could not open %s", filename); |
| 358 | return rv; | 358 | return rv; |
| 359 | } | 359 | } |
| 360 | 360 | ||
| @@ -362,17 +362,38 @@ apr_status_t parse_logfile(config_t *cfg, const char *filename) | |||
| 362 | do { | 362 | do { |
| 363 | rv = apr_file_gets(buff, 1024, file); | 363 | rv = apr_file_gets(buff, 1024, file); |
| 364 | if (rv == APR_SUCCESS) { | 364 | if (rv == APR_SUCCESS) { |
| 365 | int i,m, cont = 0; | ||
| 366 | config_filter_t *filters; | ||
| 367 | |||
| 365 | line++; | 368 | line++; |
| 366 | // chomp off newline | 369 | // chomp off newline |
| 367 | line_chomp(buff); | 370 | line_chomp(buff); |
| 371 | // Run line filters | ||
| 372 | for (i=0, m=cfg->linefilters->nelts, | ||
| 373 | filters = (config_filter_t *)cfg->linefilters->elts; | ||
| 374 | i<m; i++) { | ||
| 375 | if (!filters[i].regex || ap_regexec(filters[i].regex, buff, 0, NULL,0)==0) { | ||
| 376 | if (filters[i].negative) { | ||
| 377 | logging_log(cfg, LOGLEVEL_DEBUG, | ||
| 378 | "PARSER: LINEFILTER: Skipping Line %d due to Filter (%d)%s", | ||
| 379 | line, i, filters[i].filter); | ||
| 380 | cont = 1; | ||
| 381 | } else { | ||
| 382 | logging_log(cfg, LOGLEVEL_DEBUG, | ||
| 383 | "PARSER: LINEFILTER: Force Parsing Line %d due to Filter (%d)%s", | ||
| 384 | line, i, filters[i].filter); | ||
| 385 | } | ||
| 386 | break; | ||
| 387 | } | ||
| 388 | } | ||
| 389 | if (cont) continue; | ||
| 368 | 390 | ||
| 369 | apr_pool_clear(targp); | 391 | apr_pool_clear(targp); |
| 370 | tokenize_logline(buff, &targv, targp, 0); | 392 | tokenize_logline(buff, &targv, targp, 0); |
| 371 | targc = 0; | 393 | targc = 0; |
| 372 | while (targv[targc]) | 394 | while (targv[targc]) |
| 373 | targc++; | 395 | targc++; |
| 374 | /** @todo Run Line Filters here */ | 396 | rv = parse_processline(targp, cfg, line, targv, targc); |
| 375 | rv = parse_processline(targp, cfg, targv, targc); | ||
| 376 | if (rv != APR_SUCCESS) { | 397 | if (rv != APR_SUCCESS) { |
| 377 | int i; | 398 | int i; |
| 378 | logging_log(cfg, LOGLEVEL_ERROR, "Line %d(%d): %s", line, | 399 | logging_log(cfg, LOGLEVEL_ERROR, "Line %d(%d): %s", line, |
| @@ -387,21 +408,22 @@ apr_status_t parse_logfile(config_t *cfg, const char *filename) | |||
| 387 | apr_file_close(file); | 408 | apr_file_close(file); |
| 388 | apr_pool_destroy(tp); | 409 | apr_pool_destroy(tp); |
| 389 | logging_log(cfg, LOGLEVEL_NOTICE, | 410 | logging_log(cfg, LOGLEVEL_NOTICE, |
| 390 | "Finish Parsing Log File '%s'. Lines: %d", filename, line); | 411 | "PARSER: Finish Parsing Log File '%s'. Lines: %d", filename, line); |
| 391 | 412 | ||
| 392 | return APR_SUCCESS; | 413 | return APR_SUCCESS; |
| 393 | } | 414 | } |
| 394 | 415 | ||
| 395 | apr_status_t parse_processline(apr_pool_t *ptemp, config_t *cfg, char **argv, | 416 | apr_status_t parse_processline(apr_pool_t *ptemp, config_t *cfg, int line, |
| 396 | int argc) | 417 | char **argv, int argc) |
| 397 | { | 418 | { |
| 398 | config_logformat_t *fmt; | 419 | config_logformat_t *fmt; |
| 399 | config_logformat_field_t *ifields; | 420 | config_logformat_field_t *ifields; |
| 400 | config_output_field_t *ofields; | 421 | config_output_field_t *ofields; |
| 422 | config_filter_t *filters; | ||
| 401 | apr_table_t *datain; | 423 | apr_table_t *datain; |
| 402 | apr_table_t *dataout; | 424 | apr_table_t *dataout; |
| 403 | apr_status_t rv= APR_SUCCESS; | 425 | apr_status_t rv= APR_SUCCESS; |
| 404 | int i; | 426 | int i,m; |
| 405 | 427 | ||
| 406 | fmt = apr_hash_get(cfg->log_formats, cfg->logformat, APR_HASH_KEY_STRING); | 428 | fmt = apr_hash_get(cfg->log_formats, cfg->logformat, APR_HASH_KEY_STRING); |
| 407 | if (!fmt) | 429 | if (!fmt) |
| @@ -416,13 +438,31 @@ apr_status_t parse_processline(apr_pool_t *ptemp, config_t *cfg, char **argv, | |||
| 416 | for (i=0; i<fmt->fields->nelts; i++) { | 438 | for (i=0; i<fmt->fields->nelts; i++) { |
| 417 | apr_table_setn(datain, ifields[i].name, argv[i]); | 439 | apr_table_setn(datain, ifields[i].name, argv[i]); |
| 418 | } | 440 | } |
| 419 | /** @todo Run Pre Filters here */ | 441 | // Run Pre Filters |
| 442 | for (i=0, m=cfg->prefilters->nelts, | ||
| 443 | filters = (config_filter_t *)cfg->prefilters->elts; | ||
| 444 | i<m; i++) { | ||
| 445 | const char *temp = apr_table_get(datain, filters[i].field); | ||
| 446 | if (temp && (!filters[i].regex || ap_regexec(filters[i].regex, temp, 0, NULL,0)==0)) { | ||
| 447 | if (filters[i].negative) { | ||
| 448 | logging_log(cfg, LOGLEVEL_DEBUG, | ||
| 449 | "PARSER: PREFILTER: Skipping Line %d due to Filter (%d)%s", | ||
| 450 | line, i, filters[i].filter); | ||
| 451 | return APR_SUCCESS; | ||
| 452 | } else { | ||
| 453 | logging_log(cfg, LOGLEVEL_DEBUG, | ||
| 454 | "PARSER: PREFILTER: Force Parsing Line %d due to Filter (%d)%s", | ||
| 455 | line, i, filters[i].filter); | ||
| 456 | } | ||
| 457 | break; | ||
| 458 | } | ||
| 459 | } | ||
| 420 | 460 | ||
| 421 | ofields = (config_output_field_t *)cfg->output_fields->elts; | 461 | ofields = (config_output_field_t *)cfg->output_fields->elts; |
| 422 | // clear out ofield function per-line data | 462 | // clear out ofield function per-line data |
| 423 | memset(&g_parser_linedata[1],0,sizeof(void *)*(int)g_parser_linedata[0]); | 463 | memset(&g_parser_linedata[1],0,sizeof(void *)*(int)g_parser_linedata[0]); |
| 424 | // Convert input fields to output fields | 464 | // Convert input fields to output fields |
| 425 | for (i=0; i<cfg->output_fields->nelts; i++) { | 465 | for (i=0,m=cfg->output_fields->nelts; i<m; i++) { |
| 426 | const char *val; | 466 | const char *val; |
| 427 | val = apr_table_get(datain, ofields[i].source); | 467 | val = apr_table_get(datain, ofields[i].source); |
| 428 | // If we can't find the source field just continue | 468 | // If we can't find the source field just continue |
| @@ -442,7 +482,25 @@ apr_status_t parse_processline(apr_pool_t *ptemp, config_t *cfg, char **argv, | |||
| 442 | } | 482 | } |
| 443 | } | 483 | } |
| 444 | 484 | ||
| 445 | /** @todo Run Post Filters here */ | 485 | // Run Post filters |
| 486 | for (i=0, m=cfg->postfilters->nelts, | ||
| 487 | filters = (config_filter_t *)cfg->postfilters->elts; | ||
| 488 | i<m; i++) { | ||
| 489 | const char *temp = apr_table_get(dataout, filters[i].field); | ||
| 490 | if (temp && (!filters[i].regex || ap_regexec(filters[i].regex, temp, 0, NULL,0)==0)) { | ||
| 491 | if (filters[i].negative) { | ||
| 492 | logging_log(cfg, LOGLEVEL_DEBUG, | ||
| 493 | "PARSER: POSTFILTER: Skipping Line %d due to Filter (%d)%s", | ||
| 494 | line, i, filters[i].filter); | ||
| 495 | return APR_SUCCESS; | ||
| 496 | } else { | ||
| 497 | logging_log(cfg, LOGLEVEL_DEBUG, | ||
| 498 | "PARSER: POSTFILTER: Force Parsing Line %d due to Filter (%d)%s", | ||
| 499 | line, i, filters[i].filter); | ||
| 500 | } | ||
| 501 | break; | ||
| 502 | } | ||
| 503 | } | ||
| 446 | 504 | ||
| 447 | // Process DB Query | 505 | // Process DB Query |
| 448 | if (!cfg->dryrun) { | 506 | if (!cfg->dryrun) { |
diff --git a/utility/logparse.h b/utility/logparse.h index bc39cb1..0b8607b 100644 --- a/utility/logparse.h +++ b/utility/logparse.h | |||
| @@ -25,7 +25,7 @@ void parser_find_logs(config_t *cfg); | |||
| 25 | 25 | ||
| 26 | apr_status_t parse_logfile(config_t *cfg, const char *filename); | 26 | apr_status_t parse_logfile(config_t *cfg, const char *filename); |
| 27 | 27 | ||
| 28 | apr_status_t parse_processline(apr_pool_t *ptemp, config_t *cfg, char **argv, | 28 | apr_status_t parse_processline(apr_pool_t *ptemp, config_t *cfg, int line, |
| 29 | int argc); | 29 | char **argv, int argc); |
| 30 | 30 | ||
| 31 | #endif /*LOGPARSE_H_*/ | 31 | #endif /*LOGPARSE_H_*/ |
diff --git a/utility/mod_log_sql.conf b/utility/mod_log_sql.conf index ee0cb07..fde7cc6 100644 --- a/utility/mod_log_sql.conf +++ b/utility/mod_log_sql.conf | |||
| @@ -29,9 +29,12 @@ LogFormatConfig Combined agent String | |||
| 29 | 29 | ||
| 30 | LogFormat Combined | 30 | LogFormat Combined |
| 31 | 31 | ||
| 32 | # not yet implemented | ||
| 33 | Linefilter - "BAD" | 32 | Linefilter - "BAD" |
| 34 | PreFilter request - "GET \/images" | 33 | LineFilter "GOOD" |
| 34 | LineFilter + "BETTER" | ||
| 35 | # the next filter ignores ALL lines | ||
| 36 | LineFilter - | ||
| 37 | PreFilter request + "Rebuild" | ||
| 35 | PostFilter request_method "GET" | 38 | PostFilter request_method "GET" |
| 36 | 39 | ||
| 37 | # Usage field datatype(size) default source [function [param]...] | 40 | # Usage field datatype(size) default source [function [param]...] |
| @@ -41,7 +44,8 @@ OutputField remote_host varchar(50) "" remhost | |||
| 41 | OutputField request_method varchar(25) "" request regexmatch "^(\\w+)" | 44 | OutputField request_method varchar(25) "" request regexmatch "^(\\w+)" |
| 42 | OutputField time_stamp int 0 date totimestamp | 45 | OutputField time_stamp int 0 date totimestamp |
| 43 | OutputField status smallint 0 status | 46 | OutputField status smallint 0 status |
| 44 | OutputField request_uri varchar(255) "" request regexmatch "^\\w+ (.+) \\w+/[\\d\\.]+$" | 47 | OutputField request_line varchar(255) "" request |
| 48 | #OutputField request_uri varchar(255) "" request regexmatch "^\\w+ (.+) \\w+/[\\d\\.]+$" | ||
| 45 | OutputField remote_user varchar(50) "" user | 49 | OutputField remote_user varchar(50) "" user |
| 46 | OutputField remote_logname varchar(50) "" ident | 50 | OutputField remote_logname varchar(50) "" ident |
| 47 | OutputField request_time char(28) "" date wrap "[" "]" | 51 | OutputField request_time char(28) "" date wrap "[" "]" |
diff --git a/utility/shell.c b/utility/shell.c index e521916..3de65b3 100644 --- a/utility/shell.c +++ b/utility/shell.c | |||
| @@ -134,6 +134,8 @@ int main(int argc, const char *const argv[]) | |||
| 134 | database_init(pool); | 134 | database_init(pool); |
| 135 | // Process configuration file | 135 | // Process configuration file |
| 136 | cfg = config_create(pool); | 136 | cfg = config_create(pool); |
| 137 | // initialize STD out error log | ||
| 138 | logging_preinit(cfg); | ||
| 137 | rv = config_read(cfg, apr_table_get(args,"Config"), args); | 139 | rv = config_read(cfg, apr_table_get(args,"Config"), args); |
| 138 | apr_pool_destroy(ptemp); | 140 | apr_pool_destroy(ptemp); |
| 139 | 141 | ||
diff --git a/utility/util.c b/utility/util.c index 7ecb902..45b95ba 100644 --- a/utility/util.c +++ b/utility/util.c | |||
| @@ -124,11 +124,15 @@ int ap_unescape_url(char *url) | |||
| 124 | #endif | 124 | #endif |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | void logging_init(config_t *cfg) | 127 | void logging_preinit(config_t *cfg) |
| 128 | { | 128 | { |
| 129 | apr_status_t rv; | ||
| 130 | apr_pool_create(&cfg->errorlog_p, cfg->pool); | 129 | apr_pool_create(&cfg->errorlog_p, cfg->pool); |
| 131 | apr_file_open_stderr(&cfg->errorlog_fperr, cfg->pool); | 130 | apr_file_open_stderr(&cfg->errorlog_fperr, cfg->pool); |
| 131 | } | ||
| 132 | |||
| 133 | void logging_init(config_t *cfg) | ||
| 134 | { | ||
| 135 | apr_status_t rv; | ||
| 132 | if (cfg->errorlog) { | 136 | if (cfg->errorlog) { |
| 133 | rv = apr_file_open(&cfg->errorlog_fp, cfg->errorlog, | 137 | rv = apr_file_open(&cfg->errorlog_fp, cfg->errorlog, |
| 134 | APR_FOPEN_CREATE | APR_FOPEN_WRITE | APR_FOPEN_APPEND, | 138 | APR_FOPEN_CREATE | APR_FOPEN_WRITE | APR_FOPEN_APPEND, |
| @@ -170,7 +174,7 @@ void logging_log(config_t *cfg, loglevel_e level, const char *fmt, ...) | |||
| 170 | if (level == LOGLEVEL_NOISE) { | 174 | if (level == LOGLEVEL_NOISE) { |
| 171 | apr_file_writev(cfg->errorlog_fperr,vec,2,&blen); | 175 | apr_file_writev(cfg->errorlog_fperr,vec,2,&blen); |
| 172 | } | 176 | } |
| 173 | if (cfg->loglevel > LOGLEVEL_NONE) { | 177 | if (cfg->loglevel > LOGLEVEL_NONE && cfg->errorlog_fp) { |
| 174 | apr_file_writev(cfg->errorlog_fp,vec,2,&blen); | 178 | apr_file_writev(cfg->errorlog_fp,vec,2,&blen); |
| 175 | } | 179 | } |
| 176 | 180 | ||
diff --git a/utility/util.h b/utility/util.h index 99f93aa..a5a7f7e 100644 --- a/utility/util.h +++ b/utility/util.h | |||
| @@ -14,6 +14,8 @@ void line_chomp(char *str); | |||
| 14 | 14 | ||
| 15 | int ap_unescape_url(char *url); | 15 | int ap_unescape_url(char *url); |
| 16 | 16 | ||
| 17 | void logging_preinit(config_t *cfg); | ||
| 18 | |||
| 17 | void logging_init(config_t *cfg); | 19 | void logging_init(config_t *cfg); |
| 18 | 20 | ||
| 19 | void logging_log(config_t *cfg, loglevel_e level, const char *fmt, ...) | 21 | void logging_log(config_t *cfg, loglevel_e level, const char *fmt, ...) |
