diff options
author | Edward Rudd | 2008-10-26 01:53:49 +0000 |
---|---|---|
committer | Edward Rudd | 2008-10-26 01:53:49 +0000 |
commit | fc70e99444b2852f45303d9bf55332f247ec6b4f (patch) | |
tree | b74c53e122b67b9b6b82ddbdf02c4fb12e9236de /utility | |
parent | ede07b5bec9a17f2fe208abdf12e72209b79780c (diff) |
finish transaction implementation
if a single log file aborts DO NOT keep going
switch to using libtool for linking (so rpath is set)
Diffstat (limited to 'utility')
-rw-r--r-- | utility/Makefile.in | 7 | ||||
-rw-r--r-- | utility/database.c | 66 | ||||
-rw-r--r-- | utility/logparse.c | 12 | ||||
-rw-r--r-- | utility/mod_log_sql.conf | 12 | ||||
-rw-r--r-- | utility/shell.c | 9 |
5 files changed, 87 insertions, 19 deletions
diff --git a/utility/Makefile.in b/utility/Makefile.in index c7a5e3d..fdc3846 100644 --- a/utility/Makefile.in +++ b/utility/Makefile.in | |||
@@ -2,14 +2,15 @@ | |||
2 | 2 | ||
3 | top_srcdir = @top_srcdir@ | 3 | top_srcdir = @top_srcdir@ |
4 | srcdir = @abs_srcdir@ | 4 | srcdir = @abs_srcdir@ |
5 | top_builddir = @top_builddir@ | ||
5 | builddir = @abs_builddir@ | 6 | builddir = @abs_builddir@ |
6 | 7 | ||
7 | #@APR_CFLAGS@ | 8 | LIBTOOL=@LIBTOOL@ |
8 | CFLAGS = -g3 -Wall -fno-strict-aliasing \ | 9 | CFLAGS = -g3 -Wall -fno-strict-aliasing \ |
9 | @APR_INCLUDES@ @APU_INCLUDES@ @PCRE_CFLAGS@ \ | 10 | @APR_INCLUDES@ @APU_INCLUDES@ @PCRE_CFLAGS@ \ |
10 | -I$(top_srcdir)/include | 11 | -I$(top_srcdir)/include |
11 | CPPFLAGS = @APR_CPPFLAGS@ | 12 | CPPFLAGS = @APR_CPPFLAGS@ |
12 | LDFLAGS = @APR_LDFLAGS@ @APU_LDFLAGS@ @PCRE_LIBS@ | 13 | LDFLAGS = @APR_LIBTOOL@ @APU_LIBTOOL@ @PCRE_LIBS@ |
13 | 14 | ||
14 | ifeq (@OOO_MAINTAIN@,1) | 15 | ifeq (@OOO_MAINTAIN@,1) |
15 | CFLAGS += -Werror | 16 | CFLAGS += -Werror |
@@ -28,7 +29,7 @@ TARGETS = mod_log_sql | |||
28 | all: $(TARGETS) | 29 | all: $(TARGETS) |
29 | 30 | ||
30 | mod_log_sql: $(OBJECTS) $(HEADERS) | 31 | mod_log_sql: $(OBJECTS) $(HEADERS) |
31 | $(CC) -o $@ $(OBJECTS) $(LDFLAGS) | 32 | $(LIBTOOL) --tag=CC --mode=link $(CC) -o $@ $(OBJECTS) $(LDFLAGS) |
32 | 33 | ||
33 | %.o: %.c %.d | 34 | %.o: %.c %.d |
34 | gcc -c $(CFLAGS) $(CPPFLAGS) $< -o $@ | 35 | gcc -c $(CFLAGS) $(CPPFLAGS) $< -o $@ |
diff --git a/utility/database.c b/utility/database.c index af8db97..98c203b 100644 --- a/utility/database.c +++ b/utility/database.c | |||
@@ -10,6 +10,7 @@ struct config_dbd_t { | |||
10 | const apr_dbd_driver_t *driver; | 10 | const apr_dbd_driver_t *driver; |
11 | apr_dbd_t *dbd; | 11 | apr_dbd_t *dbd; |
12 | apr_dbd_prepared_t *stmt; | 12 | apr_dbd_prepared_t *stmt; |
13 | apr_dbd_transaction_t *txn; | ||
13 | const char **args; | 14 | const char **args; |
14 | }; | 15 | }; |
15 | 16 | ||
@@ -30,8 +31,8 @@ apr_status_t database_connect(config_t *cfg) | |||
30 | if (rv) { | 31 | if (rv) { |
31 | 32 | ||
32 | logging_log(cfg, LOGLEVEL_ERROR, | 33 | logging_log(cfg, LOGLEVEL_ERROR, |
33 | "DB: Could not load database driver %s. Error %s", cfg->dbdriver, | 34 | "DB: Could not load database driver %s. Error %s", |
34 | logging_strerror(rv)); | 35 | cfg->dbdriver, logging_strerror(rv)); |
35 | return rv; | 36 | return rv; |
36 | } | 37 | } |
37 | 38 | ||
@@ -39,7 +40,8 @@ apr_status_t database_connect(config_t *cfg) | |||
39 | &(cfg->dbconn->dbd)); | 40 | &(cfg->dbconn->dbd)); |
40 | if (rv) { | 41 | if (rv) { |
41 | logging_log(cfg, LOGLEVEL_ERROR, | 42 | logging_log(cfg, LOGLEVEL_ERROR, |
42 | "DB: Could not connect to database. Error (%d)%s", rv, logging_strerror(rv)); | 43 | "DB: Could not connect to database. Error (%d)%s", rv, |
44 | logging_strerror(rv)); | ||
43 | return rv; | 45 | return rv; |
44 | } | 46 | } |
45 | 47 | ||
@@ -57,7 +59,7 @@ static apr_dbd_prepared_t *database_prepare_insert(config_t *cfg, apr_pool_t *p) | |||
57 | char *sql; | 59 | char *sql; |
58 | int i, f; | 60 | int i, f; |
59 | struct iovec *vec; | 61 | struct iovec *vec; |
60 | apr_dbd_prepared_t *stmt = NULL; | 62 | apr_dbd_prepared_t *stmt= NULL; |
61 | int nfs = cfg->output_fields->nelts; | 63 | int nfs = cfg->output_fields->nelts; |
62 | config_output_field_t *ofields; | 64 | config_output_field_t *ofields; |
63 | 65 | ||
@@ -95,12 +97,14 @@ static apr_dbd_prepared_t *database_prepare_insert(config_t *cfg, apr_pool_t *p) | |||
95 | "INSERT", &stmt); | 97 | "INSERT", &stmt); |
96 | 98 | ||
97 | if (rv) { | 99 | if (rv) { |
98 | logging_log(cfg, LOGLEVEL_NOISE, "DB: Unable to Prepare SQL insert: %s", | 100 | logging_log(cfg, LOGLEVEL_NOISE, |
99 | apr_dbd_error(cfg->dbconn->driver, cfg->dbconn->dbd, rv)); | 101 | "DB: Unable to Prepare SQL insert: %s", apr_dbd_error( |
102 | cfg->dbconn->driver, cfg->dbconn->dbd, rv)); | ||
100 | return NULL; | 103 | return NULL; |
101 | } | 104 | } |
102 | return stmt; | 105 | return stmt; |
103 | } | 106 | } |
107 | |||
104 | apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) | 108 | apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) |
105 | { | 109 | { |
106 | apr_status_t rv; | 110 | apr_status_t rv; |
@@ -129,10 +133,25 @@ apr_status_t database_insert(config_t *cfg, apr_pool_t *p, apr_table_t *data) | |||
129 | return APR_SUCCESS; | 133 | return APR_SUCCESS; |
130 | } | 134 | } |
131 | 135 | ||
132 | /** @todo implement transactions */ | ||
133 | apr_status_t database_trans_start(config_t *cfg, apr_pool_t *p) | 136 | apr_status_t database_trans_start(config_t *cfg, apr_pool_t *p) |
134 | { | 137 | { |
135 | #if HAVE_APR_DBD_TRANSACTION_MODE_GET | 138 | #if HAVE_APR_DBD_TRANSACTION_MODE_GET |
139 | apr_status_t rv; | ||
140 | if (!cfg->transactions) | ||
141 | return APR_SUCCESS; | ||
142 | if (cfg->dbconn->txn) { | ||
143 | logging_log(cfg, LOGLEVEL_NOISE, | ||
144 | "Transaction Already Started. Something is BROKE"); | ||
145 | return APR_EINVAL; | ||
146 | } | ||
147 | logging_log(cfg, LOGLEVEL_DEBUG, "DB: Starting Transaction"); | ||
148 | rv = apr_dbd_transaction_start(cfg->dbconn->driver, p, cfg->dbconn->dbd, | ||
149 | &cfg->dbconn->txn); | ||
150 | if (rv) | ||
151 | logging_log(cfg, LOGLEVEL_NOISE, | ||
152 | "DB: Error Starting Transaction: (%d)%s", rv, apr_dbd_error( | ||
153 | cfg->dbconn->driver, cfg->dbconn->dbd, rv)); | ||
154 | return rv; | ||
136 | #else | 155 | #else |
137 | return APR_SUCCESS; | 156 | return APR_SUCCESS; |
138 | #endif | 157 | #endif |
@@ -141,6 +160,23 @@ apr_status_t database_trans_start(config_t *cfg, apr_pool_t *p) | |||
141 | apr_status_t database_trans_stop(config_t *cfg, apr_pool_t *p) | 160 | apr_status_t database_trans_stop(config_t *cfg, apr_pool_t *p) |
142 | { | 161 | { |
143 | #if HAVE_APR_DBD_TRANSACTION_MODE_GET | 162 | #if HAVE_APR_DBD_TRANSACTION_MODE_GET |
163 | apr_status_t rv; | ||
164 | if (!cfg->transactions) | ||
165 | return APR_SUCCESS; | ||
166 | if (!cfg->dbconn->txn) { | ||
167 | logging_log(cfg, LOGLEVEL_NOISE, | ||
168 | "No Transaction Started. Something is BROKE"); | ||
169 | return APR_EINVAL; | ||
170 | } | ||
171 | logging_log(cfg, LOGLEVEL_DEBUG, "DB: Stopping Transaction"); | ||
172 | rv = apr_dbd_transaction_end(cfg->dbconn->driver, p, cfg->dbconn->txn); | ||
173 | if (rv) | ||
174 | logging_log(cfg, LOGLEVEL_NOISE, | ||
175 | "DB: Error Stopping Transaction: (%d)%s", rv, apr_dbd_error( | ||
176 | cfg->dbconn->driver, cfg->dbconn->dbd, rv)); | ||
177 | |||
178 | cfg->dbconn->txn = NULL; | ||
179 | return rv; | ||
144 | #else | 180 | #else |
145 | return APR_SUCCESS; | 181 | return APR_SUCCESS; |
146 | #endif | 182 | #endif |
@@ -149,6 +185,22 @@ apr_status_t database_trans_stop(config_t *cfg, apr_pool_t *p) | |||
149 | apr_status_t database_trans_abort(config_t *cfg) | 185 | apr_status_t database_trans_abort(config_t *cfg) |
150 | { | 186 | { |
151 | #if HAVE_APR_DBD_TRANSACTION_MODE_GET | 187 | #if HAVE_APR_DBD_TRANSACTION_MODE_GET |
188 | apr_status_t rv; | ||
189 | if (!cfg->transactions) | ||
190 | return APR_SUCCESS; | ||
191 | if (!cfg->dbconn->txn) { | ||
192 | logging_log(cfg, LOGLEVEL_NOISE, | ||
193 | "No Transaction Started. Something is BROKE"); | ||
194 | return APR_EINVAL; | ||
195 | } | ||
196 | logging_log(cfg, LOGLEVEL_NOTICE, "DB: Aborting Transaction"); | ||
197 | rv = apr_dbd_transaction_mode_set(cfg->dbconn->driver, cfg->dbconn->txn, | ||
198 | APR_DBD_TRANSACTION_ROLLBACK); | ||
199 | if (rv) | ||
200 | logging_log(cfg, LOGLEVEL_NOISE, | ||
201 | "DB: Error Aborting Transaction: (%d)%s", rv, apr_dbd_error( | ||
202 | cfg->dbconn->driver, cfg->dbconn->dbd, rv)); | ||
203 | return rv; | ||
152 | #else | 204 | #else |
153 | return APR_SUCCESS; | 205 | return APR_SUCCESS; |
154 | #endif | 206 | #endif |
diff --git a/utility/logparse.c b/utility/logparse.c index ac70ee2..923b581 100644 --- a/utility/logparse.c +++ b/utility/logparse.c | |||
@@ -359,6 +359,9 @@ apr_status_t parse_logfile(config_t *cfg, const char *filename) | |||
359 | } | 359 | } |
360 | 360 | ||
361 | line = 0; | 361 | line = 0; |
362 | // Start Transaction | ||
363 | database_trans_start(cfg,tp); | ||
364 | |||
362 | do { | 365 | do { |
363 | rv = apr_file_gets(buff, 1024, file); | 366 | rv = apr_file_gets(buff, 1024, file); |
364 | if (rv == APR_SUCCESS) { | 367 | if (rv == APR_SUCCESS) { |
@@ -396,6 +399,7 @@ apr_status_t parse_logfile(config_t *cfg, const char *filename) | |||
396 | rv = parse_processline(targp, cfg, line, targv, targc); | 399 | rv = parse_processline(targp, cfg, line, targv, targc); |
397 | if (rv != APR_SUCCESS) { | 400 | if (rv != APR_SUCCESS) { |
398 | int i; | 401 | int i; |
402 | database_trans_abort(cfg); | ||
399 | logging_log(cfg, LOGLEVEL_ERROR, "Line %d(%d): %s", line, | 403 | logging_log(cfg, LOGLEVEL_ERROR, "Line %d(%d): %s", line, |
400 | targc, buff); | 404 | targc, buff); |
401 | for (i = 0; targv[i]; i++) { | 405 | for (i = 0; targv[i]; i++) { |
@@ -403,14 +407,20 @@ apr_status_t parse_logfile(config_t *cfg, const char *filename) | |||
403 | targv[i]); | 407 | targv[i]); |
404 | } | 408 | } |
405 | } | 409 | } |
410 | } else { | ||
411 | rv = APR_SUCCESS; | ||
412 | break; | ||
406 | } | 413 | } |
407 | } while (rv == APR_SUCCESS); | 414 | } while (rv == APR_SUCCESS); |
408 | apr_file_close(file); | 415 | apr_file_close(file); |
416 | // Finish Transaction | ||
417 | database_trans_stop(cfg,tp); | ||
418 | |||
409 | apr_pool_destroy(tp); | 419 | apr_pool_destroy(tp); |
410 | logging_log(cfg, LOGLEVEL_NOTICE, | 420 | logging_log(cfg, LOGLEVEL_NOTICE, |
411 | "PARSER: Finish Parsing Log File '%s'. Lines: %d", filename, line); | 421 | "PARSER: Finish Parsing Log File '%s'. Lines: %d", filename, line); |
412 | 422 | ||
413 | return APR_SUCCESS; | 423 | return rv; |
414 | } | 424 | } |
415 | 425 | ||
416 | apr_status_t parse_processline(apr_pool_t *ptemp, config_t *cfg, int line, | 426 | apr_status_t parse_processline(apr_pool_t *ptemp, config_t *cfg, int line, |
diff --git a/utility/mod_log_sql.conf b/utility/mod_log_sql.conf index fde7cc6..54ac85d 100644 --- a/utility/mod_log_sql.conf +++ b/utility/mod_log_sql.conf | |||
@@ -29,13 +29,13 @@ LogFormatConfig Combined agent String | |||
29 | 29 | ||
30 | LogFormat Combined | 30 | LogFormat Combined |
31 | 31 | ||
32 | Linefilter - "BAD" | 32 | #Linefilter - "BAD" |
33 | LineFilter "GOOD" | 33 | #LineFilter "GOOD" |
34 | LineFilter + "BETTER" | 34 | #LineFilter + "BETTER" |
35 | # the next filter ignores ALL lines | 35 | # the next filter ignores ALL lines |
36 | LineFilter - | 36 | #LineFilter - |
37 | PreFilter request + "Rebuild" | 37 | #PreFilter request + "Rebuild" |
38 | PostFilter request_method "GET" | 38 | #PostFilter request_method "GET" |
39 | 39 | ||
40 | # Usage field datatype(size) default source [function [param]...] | 40 | # Usage field datatype(size) default source [function [param]...] |
41 | OutputField bytes_sent int 0 bytes_sent | 41 | OutputField bytes_sent int 0 bytes_sent |
diff --git a/utility/shell.c b/utility/shell.c index 3de65b3..5f011a6 100644 --- a/utility/shell.c +++ b/utility/shell.c | |||
@@ -21,7 +21,7 @@ const apr_getopt_option_t _opt_config[] = { | |||
21 | {"config", 'c', 1, "Configuration file to use (default mod_log_sql.conf)"}, | 21 | {"config", 'c', 1, "Configuration file to use (default mod_log_sql.conf)"}, |
22 | {"dryrun", 'n', 0, "Perform a dry run (do not actually alter the databse)"}, | 22 | {"dryrun", 'n', 0, "Perform a dry run (do not actually alter the databse)"}, |
23 | {"dump", 'd', 0, "Dump the configuration after parsing and quit"}, | 23 | {"dump", 'd', 0, "Dump the configuration after parsing and quit"}, |
24 | {"loglevel", 'l', 1, "Log Level (deubg, warn, error)"}, | 24 | {"loglevel", 'l', 1, "Log Level (deubg, notice, error)"}, |
25 | {"summary", 's', 1, "Summary (yes,no)"}, | 25 | {"summary", 's', 1, "Summary (yes,no)"}, |
26 | {"help", 'h', 0, "Show Help"}, | 26 | {"help", 'h', 0, "Show Help"}, |
27 | {NULL} | 27 | {NULL} |
@@ -170,7 +170,12 @@ int main(int argc, const char *const argv[]) | |||
170 | int f, l; | 170 | int f, l; |
171 | filelist = (char **)cfg->input_files->elts; | 171 | filelist = (char **)cfg->input_files->elts; |
172 | for (f=0, l=cfg->input_files->nelts; f < l; f++) { | 172 | for (f=0, l=cfg->input_files->nelts; f < l; f++) { |
173 | parse_logfile(cfg, filelist[f]); | 173 | rv = parse_logfile(cfg, filelist[f]); |
174 | if (rv) { | ||
175 | logging_log(cfg, LOGLEVEL_NOISE, | ||
176 | "Error occured parsing log files. Aborting"); | ||
177 | break; | ||
178 | } | ||
174 | } | 179 | } |
175 | } else { | 180 | } else { |
176 | logging_log(cfg,LOGLEVEL_NOISE,"No log files found to parse"); | 181 | logging_log(cfg,LOGLEVEL_NOISE,"No log files found to parse"); |