diff options
Diffstat (limited to 'mod_log_sql.c')
-rw-r--r-- | mod_log_sql.c | 618 |
1 files changed, 457 insertions, 161 deletions
diff --git a/mod_log_sql.c b/mod_log_sql.c index 1892eec..a6086d7 100644 --- a/mod_log_sql.c +++ b/mod_log_sql.c | |||
@@ -59,18 +59,37 @@ typedef struct { | |||
59 | int announce; | 59 | int announce; |
60 | logsql_dbconnection db; | 60 | logsql_dbconnection db; |
61 | logsql_dbdriver *driver; | 61 | logsql_dbdriver *driver; |
62 | /** Show config support */ | ||
63 | char *showconfig; | ||
64 | apr_file_t *showconfig_fp; | ||
62 | } global_config_t; | 65 | } global_config_t; |
63 | 66 | ||
64 | static global_config_t global_config; | 67 | static global_config_t global_config; |
65 | 68 | ||
66 | /* structure to hold helper function info */ | 69 | /* structure to hold helper function info */ |
67 | typedef struct { | 70 | typedef struct { |
68 | char key; /* item letter character */ | 71 | const char *alias; /* The function alias */ |
69 | logsql_item_func *func; /* its extraction function */ | 72 | logsql_item_func *func; /* The extraction function pointer */ |
73 | int want_orig_req; /* if it requires the original request prior to internal redirection */ | ||
74 | } logsql_function; | ||
75 | |||
76 | /* list of logsql_functions's for log types */ | ||
77 | static apr_array_header_t *logsql_function_list; | ||
78 | |||
79 | /* structure to hold sqlfield mappings */ | ||
80 | typedef struct { | ||
81 | const char *alias; /* long name for item */ | ||
82 | const char *funcalias; /* The function alias */ | ||
83 | logsql_function *func; /* its extraction function */ | ||
84 | char *param; /* Parameter for function */ | ||
70 | const char *sql_field_name; /* its column in SQL */ | 85 | const char *sql_field_name; /* its column in SQL */ |
71 | int want_orig_default; /* if it requires the original request prior to internal redirection */ | 86 | char string_contents; /* Whether this is a string field or not */ |
72 | int string_contents; /* if it returns a string */ | 87 | logsql_field_datatype datatype; /* the field data type */ |
73 | } logsql_item; | 88 | apr_size_t size; /* The size of the data type */ |
89 | } logsql_field; | ||
90 | |||
91 | /* list of logsql_item's for log types */ | ||
92 | static apr_array_header_t *logsql_field_list; | ||
74 | 93 | ||
75 | /* But the contents of this structure will vary by virtual server. | 94 | /* But the contents of this structure will vary by virtual server. |
76 | * This permits each virtual server to vary its configuration slightly | 95 | * This permits each virtual server to vary its configuration slightly |
@@ -91,45 +110,140 @@ typedef struct { | |||
91 | const char *hin_table_name; | 110 | const char *hin_table_name; |
92 | const char *cookie_table_name; | 111 | const char *cookie_table_name; |
93 | const char *transfer_table_name; | 112 | const char *transfer_table_name; |
94 | const char *transfer_log_format; | 113 | apr_array_header_t *transfer_log_format; |
95 | apr_pool_t *parsed_pool; | 114 | apr_pool_t *parsed_pool; |
96 | logsql_item **parsed_log_format; | 115 | logsql_field **parsed_log_format; |
97 | const char *preserve_file; | 116 | const char *preserve_file; |
98 | const char *cookie_name; | 117 | const char *cookie_name; |
99 | } logsql_state; | 118 | } logsql_state; |
100 | 119 | ||
120 | /** Registration function for extract functions | ||
121 | * | ||
122 | * This functions registers an alias for a function | ||
123 | * | ||
124 | * @note This is exported from the module | ||
125 | */ | ||
126 | LOGSQL_DECLARE(void) log_sql_register_function(apr_pool_t *p, | ||
127 | const char *alias, logsql_item_func *func, | ||
128 | logsql_function_req want_orig_req) | ||
129 | { | ||
130 | logsql_function *item; | ||
131 | if (!logsql_function_list) | ||
132 | logsql_function_list = apr_array_make(p,10, sizeof(logsql_function)); | ||
101 | 133 | ||
102 | /* list of "handlers" for log types */ | 134 | item = apr_array_push(logsql_function_list); |
103 | static apr_array_header_t *logsql_item_list; | 135 | item->alias = alias; |
104 | 136 | item->func = func; | |
105 | /* Registration function for extract functions * | 137 | item->want_orig_req = want_orig_req; |
106 | * and update parse cache for transfer_log_format * | 138 | if (global_config.showconfig_fp) { |
107 | * this is exported from the module */ | 139 | apr_file_printf(global_config.showconfig_fp," Function : %s\n",alias); |
108 | LOGSQL_DECLARE(void) log_sql_register_item(server_rec *s, apr_pool_t *p, | 140 | } |
109 | char key, logsql_item_func *func, const char *sql_field_name, | 141 | } |
110 | int want_orig_default, int string_contents) | 142 | /** Register a old style sql mapping to the new style |
143 | * | ||
144 | * @note This is exported from the module | ||
145 | */ | ||
146 | LOGSQL_DECLARE(void) log_sql_register_alias(server_rec *s, apr_pool_t *p, | ||
147 | char key, const char *alias) | ||
111 | { | 148 | { |
112 | server_rec *ts; | 149 | server_rec *ts; |
113 | logsql_item *item; | 150 | for (ts = s; ts; ts = ts->next) { |
114 | if (!logsql_item_list) | 151 | logsql_state *cfg = ap_get_module_config(ts->module_config, |
115 | logsql_item_list = apr_array_make(p,10, sizeof(logsql_item)); | 152 | &log_sql_module); |
153 | int itr; | ||
154 | for (itr = 0; itr < cfg->transfer_log_format->nelts; itr++) { | ||
155 | const char *logformat = ((const char **)cfg->transfer_log_format->elts)[itr]; | ||
156 | //log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "Testing Logformat %s against %c for %s",logformat,key,alias); | ||
157 | // Check if it is only one character AND it is our key | ||
158 | if (logformat[1]=='\0' && logformat[0]==key) { | ||
159 | ((const char **)cfg->transfer_log_format->elts)[itr] = alias; | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | } | ||
116 | 164 | ||
117 | item= apr_array_push(logsql_item_list); | 165 | |
118 | item->key = key; | 166 | /** Registration sqlfield aliases to functions |
119 | item->func = func; | 167 | * |
120 | item->sql_field_name = sql_field_name; | 168 | * And update parse cache for transfer_log_format |
121 | item->want_orig_default = want_orig_default; | 169 | * |
122 | item->string_contents = string_contents; | 170 | * @note This is exported from the module |
171 | */ | ||
172 | LOGSQL_DECLARE(void) log_sql_register_field(apr_pool_t *p, | ||
173 | const char *alias, | ||
174 | const char *funcalias, const char *param, | ||
175 | const char *sql_field_name, | ||
176 | logsql_field_datatype datatype, apr_size_t size) | ||
177 | { | ||
178 | logsql_field *item; | ||
179 | |||
180 | if (!logsql_field_list) | ||
181 | logsql_field_list = apr_array_make(p,10, sizeof(logsql_field)); | ||
182 | |||
183 | item = apr_array_push(logsql_field_list); | ||
184 | item->func = NULL; | ||
185 | item->alias = apr_pstrdup(p, alias); | ||
186 | item->funcalias = apr_pstrdup(p, funcalias); | ||
187 | item->param = apr_pstrdup(p, param); | ||
188 | item->sql_field_name = apr_pstrdup(p,sql_field_name); | ||
189 | item->datatype = datatype; | ||
190 | item->string_contents = 0; | ||
191 | if (datatype == LOGSQL_DATATYPE_CHAR || datatype == LOGSQL_DATATYPE_VARCHAR) { | ||
192 | item->string_contents = 1; | ||
193 | } | ||
194 | item->size = size; | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * Links sql field items with their functions | ||
199 | */ | ||
200 | LOGSQL_DECLARE(void) log_sql_register_finish(server_rec *s) | ||
201 | { | ||
202 | server_rec *ts; | ||
203 | int itr, f; | ||
204 | logsql_field *item; | ||
205 | logsql_function *func; | ||
206 | for (itr = 0; itr < logsql_field_list->nelts; itr++) { | ||
207 | item = &((logsql_field *)logsql_field_list->elts)[itr]; | ||
208 | if (item->func) continue; | ||
209 | /* Find function alias in function list */ | ||
210 | for (f = 0; f < logsql_function_list->nelts; f++) { | ||
211 | func = &((logsql_function *)logsql_function_list->elts)[f]; | ||
212 | if (strcmp(func->alias,item->funcalias)==0) { | ||
213 | item->func = func; | ||
214 | if (global_config.showconfig_fp) { | ||
215 | apr_file_printf(global_config.showconfig_fp," Item : %s using function %s(%s)\n" | ||
216 | "\tStoring in field %s of type %s(%d)\n", | ||
217 | item->alias, item->funcalias, item->param, | ||
218 | item->sql_field_name, item->string_contents ? "TEXT":"NUMERIC", item->size); | ||
219 | } | ||
220 | break; | ||
221 | } | ||
222 | } | ||
223 | if (!item->func) { | ||
224 | log_error(APLOG_MARK, APLOG_DEBUG, 0, s, | ||
225 | "Could not find function %s for item %s",item->funcalias, item->alias); | ||
226 | } | ||
227 | } | ||
123 | /* some voodoo here to post parse logitems in all servers * | 228 | /* some voodoo here to post parse logitems in all servers * |
124 | * so a "cached" list is used in the main logging loop for speed */ | 229 | * so a "cached" list is used in the main logging loop for speed */ |
125 | for (ts = s; ts; ts = ts->next) { | 230 | for (ts = s; ts; ts = ts->next) { |
126 | logsql_state *cfg = ap_get_module_config(ts->module_config, | 231 | logsql_state *cfg = ap_get_module_config(ts->module_config, |
127 | &log_sql_module); | 232 | &log_sql_module); |
128 | char *pos; | ||
129 | 233 | ||
130 | if (cfg->transfer_log_format) { | 234 | if (!cfg->parsed_log_format) { |
131 | if ( (pos = ap_strchr_c(cfg->transfer_log_format,key))!=NULL) { | 235 | cfg->parsed_log_format = apr_pcalloc(cfg->parsed_pool, |
132 | cfg->parsed_log_format[pos - cfg->transfer_log_format] = item; | 236 | cfg->transfer_log_format->nelts * sizeof(logsql_field *)); |
237 | } | ||
238 | |||
239 | for (itr = 0; itr < cfg->transfer_log_format->nelts; itr++) { | ||
240 | const char *logformat = ((char **)cfg->transfer_log_format->elts)[itr]; | ||
241 | for (f = 0; f < logsql_field_list->nelts; f++) { | ||
242 | item = &((logsql_field *)logsql_field_list->elts)[f]; | ||
243 | if (item->func && strcmp(logformat,item->alias)==0) { | ||
244 | cfg->parsed_log_format[itr] = item; | ||
245 | break; | ||
246 | } | ||
133 | } | 247 | } |
134 | } | 248 | } |
135 | } | 249 | } |
@@ -157,7 +271,7 @@ static logsql_opendb_ret log_sql_opendb_link(server_rec* s) | |||
157 | return LOGSQL_OPENDB_FAIL; | 271 | return LOGSQL_OPENDB_FAIL; |
158 | } | 272 | } |
159 | if (global_config.forcepreserve) { | 273 | if (global_config.forcepreserve) { |
160 | //global_config.db.connected = 1; | 274 | /*global_config.db.connected = 1;*/ |
161 | return LOGSQL_OPENDB_PRESERVE; | 275 | return LOGSQL_OPENDB_PRESERVE; |
162 | } | 276 | } |
163 | if (global_config.db.connected) { | 277 | if (global_config.db.connected) { |
@@ -187,13 +301,9 @@ static void preserve_entry(request_rec *r, const char *query) | |||
187 | { | 301 | { |
188 | logsql_state *cls = ap_get_module_config(r->server->module_config, | 302 | logsql_state *cls = ap_get_module_config(r->server->module_config, |
189 | &log_sql_module); | 303 | &log_sql_module); |
190 | #if defined(WITH_APACHE20) | 304 | apr_status_t result; |
191 | apr_file_t *fp; | 305 | apr_file_t *fp; |
192 | apr_status_t result; | 306 | |
193 | #elif defined(WITH_APACHE13) | ||
194 | FILE *fp; | ||
195 | int result; | ||
196 | #endif | ||
197 | /* If preserve file is disabled bail out */ | 307 | /* If preserve file is disabled bail out */ |
198 | if (global_config.disablepreserve) | 308 | if (global_config.disablepreserve) |
199 | return; | 309 | return; |
@@ -207,11 +317,10 @@ static void preserve_entry(request_rec *r, const char *query) | |||
207 | log_error(APLOG_MARK, APLOG_ERR, result, r->server, | 317 | log_error(APLOG_MARK, APLOG_ERR, result, r->server, |
208 | "attempted append of local preserve file '%s' but failed.",cls->preserve_file); | 318 | "attempted append of local preserve file '%s' but failed.",cls->preserve_file); |
209 | } else { | 319 | } else { |
320 | apr_file_printf(fp,"%s;\n", query); | ||
210 | #if defined(WITH_APACHE20) | 321 | #if defined(WITH_APACHE20) |
211 | apr_file_printf(fp,"%s;\n", query); | ||
212 | apr_file_close(fp); | 322 | apr_file_close(fp); |
213 | #elif defined(WITH_APACHE13) | 323 | #elif defined(WITH_APACHE13) |
214 | fprintf(fp,"%s;\n", query); | ||
215 | ap_pfclose(r->pool, fp); | 324 | ap_pfclose(r->pool, fp); |
216 | #endif | 325 | #endif |
217 | log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, | 326 | log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, |
@@ -262,6 +371,7 @@ static const char *set_global_string_slot(cmd_parms *cmd, | |||
262 | *(const char **)((char *)ptr + offset) = apr_pstrdup(cmd->pool,arg); | 371 | *(const char **)((char *)ptr + offset) = apr_pstrdup(cmd->pool,arg); |
263 | return NULL; | 372 | return NULL; |
264 | } | 373 | } |
374 | |||
265 | static const char *set_server_string_slot(cmd_parms *cmd, | 375 | static const char *set_server_string_slot(cmd_parms *cmd, |
266 | void *struct_ptr, | 376 | void *struct_ptr, |
267 | const char *arg) | 377 | const char *arg) |
@@ -296,18 +406,25 @@ static const char *set_server_file_slot(cmd_parms *cmd, | |||
296 | return NULL; | 406 | return NULL; |
297 | } | 407 | } |
298 | 408 | ||
299 | static const char *set_logformat_slot(cmd_parms *cmd, | 409 | static apr_array_header_t *create_logformat_default(apr_pool_t *p) |
300 | void *struct_ptr, | ||
301 | const char *arg) | ||
302 | { | 410 | { |
303 | logsql_state *cfg = ap_get_module_config(cmd->server->module_config, | 411 | apr_array_header_t *logformat; |
304 | &log_sql_module); | 412 | char **addme; |
305 | 413 | ||
306 | cfg->transfer_log_format = arg; | 414 | logformat = apr_array_make(p, 12, sizeof(char *)); |
307 | /* apr_pool_clear(cfg->parsed_pool);*/ | 415 | addme = apr_array_push(logformat); *addme = "useragent"; |
308 | cfg->parsed_log_format = apr_pcalloc(cfg->parsed_pool, | 416 | addme = apr_array_push(logformat); *addme = "bytes_sent"; |
309 | strlen(arg) * sizeof(logsql_item *)); | 417 | addme = apr_array_push(logformat); *addme = "request_protocol"; |
310 | return NULL; | 418 | addme = apr_array_push(logformat); *addme = "remote_host"; |
419 | addme = apr_array_push(logformat); *addme = "request_method"; | ||
420 | addme = apr_array_push(logformat); *addme = "referer"; | ||
421 | addme = apr_array_push(logformat); *addme = "timestamp"; | ||
422 | addme = apr_array_push(logformat); *addme = "status"; | ||
423 | addme = apr_array_push(logformat); *addme = "request_duration"; | ||
424 | addme = apr_array_push(logformat); *addme = "request_uri"; | ||
425 | addme = apr_array_push(logformat); *addme = "remote_user"; | ||
426 | addme = apr_array_push(logformat); *addme = "virtual_host"; | ||
427 | return logformat; | ||
311 | } | 428 | } |
312 | 429 | ||
313 | static const char *set_server_nmv_string_slot(cmd_parms *parms, | 430 | static const char *set_server_nmv_string_slot(cmd_parms *parms, |
@@ -404,6 +521,60 @@ static const char *add_server_string_slot(cmd_parms *cmd, | |||
404 | return NULL; | 521 | return NULL; |
405 | } | 522 | } |
406 | 523 | ||
524 | static const char *set_logformat_slot(cmd_parms *cmd, | ||
525 | void *struct_ptr, | ||
526 | const char *arg) | ||
527 | { | ||
528 | const char *t; | ||
529 | char t2[2] = {'\0','\0'}; | ||
530 | for (t = arg; *t != '\0'; t++) { | ||
531 | t2[0] = *t; | ||
532 | add_server_string_slot(cmd, NULL, t2); | ||
533 | } | ||
534 | return NULL; | ||
535 | } | ||
536 | |||
537 | static const char *set_register_field(cmd_parms *cmd, | ||
538 | void *struct_ptr, | ||
539 | const char *arg) | ||
540 | { | ||
541 | char *alias, *funcalias, *param, *field, *datatype_s, *size_s; | ||
542 | logsql_field_datatype datatype; | ||
543 | apr_size_t size; | ||
544 | |||
545 | alias = ap_getword_white(cmd->pool, &arg); | ||
546 | funcalias = ap_getword_white(cmd->pool, &arg); | ||
547 | param = ap_getword_conf(cmd->pool, &arg); | ||
548 | field = ap_getword_white(cmd->pool, &arg); | ||
549 | datatype_s = ap_getword_white(cmd->pool, &arg); | ||
550 | size_s = ap_getword_white(cmd->pool, &arg); | ||
551 | |||
552 | if (strcasecmp("VARCHAR",datatype_s)==0) { | ||
553 | datatype = LOGSQL_DATATYPE_VARCHAR; | ||
554 | } else if (strcasecmp("INT",datatype_s)==0) { | ||
555 | datatype = LOGSQL_DATATYPE_INT; | ||
556 | } else if (strcasecmp("CHAR",datatype_s)==0) { | ||
557 | datatype = LOGSQL_DATATYPE_CHAR; | ||
558 | } else if (strcasecmp("SMALLINT",datatype_s)==0) { | ||
559 | datatype = LOGSQL_DATATYPE_SMALLINT; | ||
560 | } else if (strcasecmp("BIGINT",datatype_s)==0) { | ||
561 | datatype = LOGSQL_DATATYPE_BIGINT; | ||
562 | } else { | ||
563 | return apr_psprintf(cmd->pool, "Unknown data type %s",datatype_s); | ||
564 | } | ||
565 | |||
566 | size = atoi(size_s); | ||
567 | |||
568 | log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, | ||
569 | "%s, %s, %s, %s, %s(%d), %s(%d)", | ||
570 | alias, funcalias, param, field, datatype_s, datatype, size_s, size); | ||
571 | |||
572 | log_sql_register_field(cmd->pool, alias, funcalias, param, | ||
573 | field, datatype, size); | ||
574 | |||
575 | return NULL; | ||
576 | } | ||
577 | |||
407 | /*------------------------------------------------------------* | 578 | /*------------------------------------------------------------* |
408 | * Apache-specific hooks into the module code * | 579 | * Apache-specific hooks into the module code * |
409 | * that are defined in the array 'mysql_lgog_module' (at EOF) * | 580 | * that are defined in the array 'mysql_lgog_module' (at EOF) * |
@@ -460,6 +631,8 @@ static void log_sql_child_init(server_rec *s, apr_pool_t *p) | |||
460 | } | 631 | } |
461 | } | 632 | } |
462 | 633 | ||
634 | static apr_array_header_t *do_merge_array(apr_array_header_t *parent, apr_array_header_t *child, apr_pool_t *p); | ||
635 | |||
463 | /* post_config / module_init */ | 636 | /* post_config / module_init */ |
464 | #if defined(WITH_APACHE20) | 637 | #if defined(WITH_APACHE20) |
465 | static int log_sql_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) | 638 | static int log_sql_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) |
@@ -467,47 +640,161 @@ static int log_sql_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptem | |||
467 | static void log_sql_module_init(server_rec *s, apr_pool_t *p) | 640 | static void log_sql_module_init(server_rec *s, apr_pool_t *p) |
468 | #endif | 641 | #endif |
469 | { | 642 | { |
470 | /* TODO: Add local_address, remote_address, server_name, connection_status */ | 643 | server_rec *cur_s; |
644 | const char *default_p = ap_server_root_relative(p, DEFAULT_PRESERVE_FILE); | ||
645 | apr_array_header_t *parent = NULL; | ||
646 | |||
647 | if (global_config.showconfig != NULL) { | ||
648 | const char *tempfile = ap_server_root_relative(p, global_config.showconfig); | ||
649 | apr_status_t result; | ||
650 | #if defined(WITH_APACHE20) | ||
651 | result = apr_file_open(&global_config.showconfig_fp, tempfile,APR_TRUNCATE | APR_WRITE | APR_CREATE, APR_OS_DEFAULT, p); | ||
652 | #elif defined(WITH_APACHE13) | ||
653 | global_config.showconfig_fp = ap_pfopen(p, tempfile, "w"); | ||
654 | result = (fp)?0:errno; | ||
655 | #endif | ||
656 | if (result != APR_SUCCESS) { | ||
657 | log_error(APLOG_MARK, APLOG_ERR, result, s, | ||
658 | "attempted open of showconfig file '%s' failed.",tempfile); | ||
659 | global_config.showconfig_fp = NULL; | ||
660 | } else { | ||
661 | #if defined(WITH_APACHE20) | ||
662 | char temp_time[APR_RFC822_DATE_LEN]; | ||
663 | apr_rfc822_date(temp_time,apr_time_now()); | ||
664 | #elif defined(WITH_APACHE13) | ||
665 | char *temp_time = ap_get_time()); | ||
666 | #endif | ||
667 | apr_file_printf(global_config.showconfig_fp,"Mod_log_sql Config dump created on %s\n", temp_time); | ||
668 | } | ||
669 | } | ||
670 | |||
671 | for (cur_s = s; cur_s != NULL; cur_s= cur_s->next) { | ||
672 | logsql_state *cls = ap_get_module_config(cur_s->module_config, | ||
673 | &log_sql_module); | ||
674 | /* ap_server_root_relative any default preserve file locations */ | ||
675 | if (cls->preserve_file == DEFAULT_PRESERVE_FILE) | ||
676 | cls->preserve_file = default_p; | ||
677 | |||
678 | /* Post-process logformats */ | ||
679 | if (!cur_s->is_virtual) { | ||
680 | parent = create_logformat_default(p); | ||
681 | cls->transfer_log_format = do_merge_array(parent, cls->transfer_log_format, p); | ||
682 | parent = cls->transfer_log_format; | ||
683 | } else { | ||
684 | cls->transfer_log_format = do_merge_array(parent, cls->transfer_log_format, p); | ||
685 | } | ||
686 | } | ||
687 | |||
688 | /* TODO: Add local_address, remote_address, connection_status */ | ||
689 | /** Register functions */ | ||
690 | /** register_function(p, funcname, func_ptr, which request_rec); */ | ||
691 | log_sql_register_function(p, "useragent", extract_agent, LOGSQL_FUNCTION_REQ_ORIG); | ||
692 | log_sql_register_function(p, "request_args", extract_request_query, LOGSQL_FUNCTION_REQ_ORIG); | ||
693 | log_sql_register_function(p, "bytes_sent", extract_bytes_sent, LOGSQL_FUNCTION_REQ_FINAL); | ||
694 | log_sql_register_function(p, "cookie", extract_specific_cookie,LOGSQL_FUNCTION_REQ_FINAL); | ||
695 | log_sql_register_function(p, "request_file", extract_request_file, LOGSQL_FUNCTION_REQ_FINAL); | ||
696 | log_sql_register_function(p, "request_protocol",extract_request_protocol,LOGSQL_FUNCTION_REQ_FINAL); | ||
697 | log_sql_register_function(p, "remote_host", extract_remote_host, LOGSQL_FUNCTION_REQ_FINAL); | ||
698 | log_sql_register_function(p, "unique_id", extract_unique_id, LOGSQL_FUNCTION_REQ_FINAL); | ||
699 | log_sql_register_function(p, "remote_logname", extract_remote_logname, LOGSQL_FUNCTION_REQ_FINAL); | ||
700 | log_sql_register_function(p, "request_method", extract_request_method, LOGSQL_FUNCTION_REQ_FINAL); | ||
701 | log_sql_register_function(p, "machine_id", extract_machine_id, LOGSQL_FUNCTION_REQ_FINAL); | ||
702 | log_sql_register_function(p, "child_pid", extract_child_pid, LOGSQL_FUNCTION_REQ_FINAL); | ||
703 | log_sql_register_function(p, "server_port", extract_server_port, LOGSQL_FUNCTION_REQ_FINAL); | ||
704 | log_sql_register_function(p, "referrer", extract_referer, LOGSQL_FUNCTION_REQ_ORIG); | ||
705 | log_sql_register_function(p, "request_line", extract_request_line, LOGSQL_FUNCTION_REQ_ORIG); | ||
706 | log_sql_register_function(p, "timestamp", extract_request_timestamp,LOGSQL_FUNCTION_REQ_FINAL); | ||
707 | log_sql_register_function(p, "status", extract_status, LOGSQL_FUNCTION_REQ_ORIG); | ||
708 | log_sql_register_function(p, "request_duration",extract_request_duration,LOGSQL_FUNCTION_REQ_ORIG); | ||
709 | log_sql_register_function(p, "request_time", extract_request_time, LOGSQL_FUNCTION_REQ_FINAL); | ||
710 | log_sql_register_function(p, "remote_user", extract_remote_user, LOGSQL_FUNCTION_REQ_FINAL); | ||
711 | log_sql_register_function(p, "request_uri", extract_request_uri, LOGSQL_FUNCTION_REQ_ORIG); | ||
712 | log_sql_register_function(p, "virtual_host", extract_virtual_host, LOGSQL_FUNCTION_REQ_FINAL); | ||
713 | log_sql_register_function(p, "server_name", extract_server_name, LOGSQL_FUNCTION_REQ_FINAL); | ||
714 | |||
715 | /** Old style aliases */ | ||
716 | /** register_alias(s, shortname, longname) */ | ||
717 | log_sql_register_alias(s,p,'A',"useragent"); | ||
718 | log_sql_register_alias(s,p,'a',"request_args"); | ||
719 | log_sql_register_alias(s,p,'b',"bytes_sent"); | ||
720 | log_sql_register_alias(s,p,'c',"cookie"); | ||
721 | log_sql_register_alias(s,p,'f',"request_file"); | ||
722 | log_sql_register_alias(s,p,'H',"request_protocol"); | ||
723 | log_sql_register_alias(s,p,'h',"remote_host"); | ||
724 | log_sql_register_alias(s,p,'I',"unique_id"); | ||
725 | log_sql_register_alias(s,p,'l',"remote_logname"); | ||
726 | log_sql_register_alias(s,p,'m',"request_method"); | ||
727 | log_sql_register_alias(s,p,'M',"machine_id"); | ||
728 | log_sql_register_alias(s,p,'P',"child_pid"); | ||
729 | log_sql_register_alias(s,p,'p',"server_port"); | ||
730 | log_sql_register_alias(s,p,'R',"referrer"); | ||
731 | log_sql_register_alias(s,p,'r',"request_line"); | ||
732 | log_sql_register_alias(s,p,'S',"timestamp"); | ||
733 | log_sql_register_alias(s,p,'s',"status"); | ||
734 | log_sql_register_alias(s,p,'T',"request_duration"); | ||
735 | log_sql_register_alias(s,p,'t',"request_time"); | ||
736 | log_sql_register_alias(s,p,'u',"remote_user"); | ||
737 | log_sql_register_alias(s,p,'U',"request_uri"); | ||
738 | log_sql_register_alias(s,p,'v',"virtual_host"); | ||
739 | log_sql_register_alias(s,p,'V',"server_name"); | ||
740 | |||
471 | /* Register handlers */ | 741 | /* Register handlers */ |
472 | log_sql_register_item(s,p,'A', extract_agent, "agent", 1, 1); | 742 | /** register_field(s,p, longname, funcalias, arg, |
473 | log_sql_register_item(s,p,'a', extract_request_query, "request_args", 1, 1); | 743 | * sqlfieldname, DATATYPE, DATA LENGTH); */ |
474 | log_sql_register_item(s,p,'b', extract_bytes_sent, "bytes_sent", 0, 0); | 744 | log_sql_register_field(p,"useragent", "useragent",NULL, |
475 | log_sql_register_item(s,p,'c', extract_cookie, "cookie", 0, 1); | 745 | "agent", LOGSQL_DATATYPE_VARCHAR, 0); |
476 | /* TODO: Document */ | 746 | log_sql_register_field(p,"request_args", "request_args",NULL, |
477 | log_sql_register_item(s,p,'f', extract_request_file, "request_file", 0, 1); | 747 | "request_args",LOGSQL_DATATYPE_VARCHAR,0); |
478 | log_sql_register_item(s,p,'H', extract_request_protocol, "request_protocol", 0, 1); | 748 | log_sql_register_field(p,"bytes_sent", "bytes_sent",NULL, |
479 | log_sql_register_item(s,p,'h', extract_remote_host, "remote_host", 0, 1); | 749 | "bytes_sent",LOGSQL_DATATYPE_INT,0); |
480 | log_sql_register_item(s,p,'I', extract_unique_id, "id", 0, 1); | 750 | log_sql_register_field(p,"cookie", "cookie","Apache", |
481 | log_sql_register_item(s,p,'l', extract_remote_logname, "remote_logname", 0, 1); | 751 | "cookie",LOGSQL_DATATYPE_VARCHAR,0); |
482 | log_sql_register_item(s,p,'m', extract_request_method, "request_method", 0, 1); | 752 | log_sql_register_field(p,"request_file", "request_file",NULL, |
483 | log_sql_register_item(s,p,'M', extract_machine_id, "machine_id", 0, 1); | 753 | "request_file",LOGSQL_DATATYPE_VARCHAR,0); |
484 | log_sql_register_item(s,p,'P', extract_child_pid, "child_pid", 0, 0); | 754 | log_sql_register_field(p,"request_protocol", "request_protocol",NULL, |
485 | log_sql_register_item(s,p,'p', extract_server_port, "server_port", 0, 0); | 755 | "request_protocol",LOGSQL_DATATYPE_VARCHAR,0); |
486 | log_sql_register_item(s,p,'R', extract_referer, "referer", 1, 1); | 756 | log_sql_register_field(p,"remote_host", "remote_host",NULL, |
487 | log_sql_register_item(s,p,'r', extract_request_line, "request_line", 1, 1); | 757 | "remote_host",LOGSQL_DATATYPE_VARCHAR,0); |
488 | log_sql_register_item(s,p,'S', extract_request_timestamp, "time_stamp", 0, 0); | 758 | log_sql_register_field(p,"unique_id", "unique_id",NULL, |
489 | log_sql_register_item(s,p,'s', extract_status, "status", 1, 0); | 759 | "id",LOGSQL_DATATYPE_VARCHAR,0); |
490 | log_sql_register_item(s,p,'T', extract_request_duration, "request_duration", 1, 0); | 760 | log_sql_register_field(p,"remote_logname", "remote_logname",NULL, |
491 | log_sql_register_item(s,p,'t', extract_request_time, "request_time", 0, 1); | 761 | "remote_logname",LOGSQL_DATATYPE_VARCHAR,0); |
492 | log_sql_register_item(s,p,'u', extract_remote_user, "remote_user", 0, 1); | 762 | log_sql_register_field(p,"request_method", "request_method",NULL, |
493 | log_sql_register_item(s,p,'U', extract_request_uri, "request_uri", 1, 1); | 763 | "request_method",LOGSQL_DATATYPE_VARCHAR,0); |
494 | log_sql_register_item(s,p,'v', extract_virtual_host, "virtual_host", 0, 1); | 764 | log_sql_register_field(p,"machine_id", "machine_id",NULL, |
495 | log_sql_register_item(s,p,'V', extract_server_name, "virtual_host", 0, 1); | 765 | "machine_id",LOGSQL_DATATYPE_VARCHAR,0); |
766 | log_sql_register_field(p,"child_pid", "child_pid",NULL, | ||
767 | "child_pid",LOGSQL_DATATYPE_INT,0); | ||
768 | log_sql_register_field(p,"server_port", "server_port",NULL, | ||
769 | "server_port",LOGSQL_DATATYPE_INT,0); | ||
770 | log_sql_register_field(p,"referer", "referrer",NULL, | ||
771 | "referer",LOGSQL_DATATYPE_VARCHAR,0); | ||
772 | log_sql_register_field(p,"referrer", "referrer",NULL, | ||
773 | "referer",LOGSQL_DATATYPE_VARCHAR,0); | ||
774 | log_sql_register_field(p,"request_line", "request_line",NULL, | ||
775 | "request_line",LOGSQL_DATATYPE_VARCHAR,0); | ||
776 | log_sql_register_field(p,"timestamp", "timestamp",NULL, | ||
777 | "time_stamp",LOGSQL_DATATYPE_INT,0); | ||
778 | log_sql_register_field(p,"status", "status",NULL, | ||
779 | "status",LOGSQL_DATATYPE_INT,0); | ||
780 | log_sql_register_field(p,"request_duration", "request_duration",NULL, | ||
781 | "request_duration",LOGSQL_DATATYPE_INT,0); | ||
782 | log_sql_register_field(p,"request_time", "request_time",NULL, | ||
783 | "request_time",LOGSQL_DATATYPE_VARCHAR,0); | ||
784 | log_sql_register_field(p,"remote_user", "remote_user",NULL, | ||
785 | "remote_user",LOGSQL_DATATYPE_VARCHAR,0); | ||
786 | log_sql_register_field(p,"request_uri", "request_uri",NULL, | ||
787 | "request_uri",LOGSQL_DATATYPE_VARCHAR,0); | ||
788 | log_sql_register_field(p,"virtual_host", "virtual_host",NULL, | ||
789 | "virtual_host",LOGSQL_DATATYPE_VARCHAR,0); | ||
790 | log_sql_register_field(p,"server_name", "server_name",NULL, | ||
791 | "virtual_host",LOGSQL_DATATYPE_VARCHAR,0); | ||
792 | |||
793 | log_sql_register_finish(s); | ||
496 | 794 | ||
497 | if (global_config.announce) { | 795 | if (global_config.announce) { |
498 | ap_add_version_component(p, PACKAGE_NAME"/"PACKAGE_VERSION); | 796 | ap_add_version_component(p, PACKAGE_NAME"/"PACKAGE_VERSION); |
499 | } | 797 | } |
500 | /* ap_server_root_relative any default preserve file locations */ | ||
501 | { | ||
502 | server_rec *cur_s; | ||
503 | const char *default_p = ap_server_root_relative(p, DEFAULT_PRESERVE_FILE); | ||
504 | for (cur_s = s; cur_s != NULL; cur_s= cur_s->next) { | ||
505 | logsql_state *cls = ap_get_module_config(cur_s->module_config, | ||
506 | &log_sql_module); | ||
507 | if (cls->preserve_file == DEFAULT_PRESERVE_FILE) | ||
508 | cls->preserve_file = default_p; | ||
509 | } | ||
510 | } | ||
511 | global_config.db.p = p; | 798 | global_config.db.p = p; |
512 | 799 | ||
513 | #if defined(WITH_APACHE20) | 800 | #if defined(WITH_APACHE20) |
@@ -639,10 +926,9 @@ static void *log_sql_make_state(apr_pool_t *p, server_rec *s) | |||
639 | logsql_state *cls = (logsql_state *) apr_pcalloc(p, sizeof(logsql_state)); | 926 | logsql_state *cls = (logsql_state *) apr_pcalloc(p, sizeof(logsql_state)); |
640 | 927 | ||
641 | /* These defaults are overridable in the httpd.conf file. */ | 928 | /* These defaults are overridable in the httpd.conf file. */ |
642 | cls->transfer_log_format = DEFAULT_TRANSFER_LOG_FMT; | 929 | cls->transfer_log_format = apr_array_make(p, 1, sizeof(char *)); |
643 | apr_pool_create(&cls->parsed_pool, p); | 930 | cls->parsed_pool = p; |
644 | cls->parsed_log_format = apr_pcalloc(cls->parsed_pool, | 931 | |
645 | strlen(cls->transfer_log_format) * sizeof(logsql_item *)); | ||
646 | cls->notes_table_name = DEFAULT_NOTES_TABLE_NAME; | 932 | cls->notes_table_name = DEFAULT_NOTES_TABLE_NAME; |
647 | cls->hin_table_name = DEFAULT_HIN_TABLE_NAME; | 933 | cls->hin_table_name = DEFAULT_HIN_TABLE_NAME; |
648 | cls->hout_table_name = DEFAULT_HOUT_TABLE_NAME; | 934 | cls->hout_table_name = DEFAULT_HOUT_TABLE_NAME; |
@@ -656,7 +942,6 @@ static void *log_sql_make_state(apr_pool_t *p, server_rec *s) | |||
656 | cls->hin_list = apr_array_make(p, 1, sizeof(char *)); | 942 | cls->hin_list = apr_array_make(p, 1, sizeof(char *)); |
657 | cls->hout_list = apr_array_make(p, 1, sizeof(char *)); | 943 | cls->hout_list = apr_array_make(p, 1, sizeof(char *)); |
658 | cls->cookie_list = apr_array_make(p, 1, sizeof(char *)); | 944 | cls->cookie_list = apr_array_make(p, 1, sizeof(char *)); |
659 | |||
660 | return (void *) cls; | 945 | return (void *) cls; |
661 | } | 946 | } |
662 | 947 | ||
@@ -675,43 +960,52 @@ static int in_array(apr_array_header_t *ary, const char *elem) | |||
675 | } | 960 | } |
676 | 961 | ||
677 | 962 | ||
678 | /* Parse through cookie lists and merge based on +/- prefixes */ | 963 | /* Parse through lists and merge based on +/- prefixes */ |
679 | /* TODO: rewrite as a function */ | 964 | static apr_array_header_t *do_merge_array(apr_array_header_t *parent, apr_array_header_t *child, apr_pool_t *p) |
680 | #define DO_MERGE_ARRAY(parent,child,pool) \ | 965 | { |
681 | if (apr_is_empty_array(child)) { \ | 966 | apr_array_header_t *ret; |
682 | apr_array_cat(child, parent); \ | 967 | ret = apr_array_make(p, 1, sizeof(char *)); |
683 | } else { \ | 968 | if (apr_is_empty_array(child)) { |
684 | apr_array_header_t *addlist, *dellist; \ | 969 | apr_array_cat(ret, parent); |
685 | char **elem, **ptr = (char **)(child->elts); \ | 970 | } else { |
686 | int itr, overwrite = 0; \ | 971 | apr_array_header_t *addlist, *dellist; |
687 | addlist = apr_array_make(pool,5,sizeof(char *)); \ | 972 | apr_pool_t *subp; |
688 | dellist = apr_array_make(subp,5,sizeof(char *)); \ | 973 | char **elem, **ptr = (char **)(child->elts); |
689 | \ | 974 | int itr, overwrite = 0; |
690 | for (itr=0; itr<child->nelts; itr++) { \ | 975 | |
691 | if (*ptr[itr] == '+') { \ | 976 | apr_pool_create(&subp,p); |
692 | elem = (char **)apr_array_push(addlist); \ | 977 | |
693 | *elem = (ptr[itr]+1); \ | 978 | addlist = apr_array_make(subp,5,sizeof(char *)); |
694 | } else if (*ptr[itr] == '-') { \ | 979 | dellist = apr_array_make(subp,5,sizeof(char *)); |
695 | elem = (char **)apr_array_push(dellist); \ | 980 | |
696 | *elem = (ptr[itr]+1); \ | 981 | for (itr=0; itr<child->nelts; itr++) { |
697 | } else { \ | 982 | if (*ptr[itr] == '+') { |
698 | overwrite = 1; \ | 983 | elem = (char **)apr_array_push(addlist); |
699 | elem = (char **)apr_array_push(addlist); \ | 984 | *elem = (ptr[itr]+1); |
700 | *elem = ptr[itr]; \ | 985 | } else if (*ptr[itr] == '-') { |
701 | } \ | 986 | elem = (char **)apr_array_push(dellist); |
702 | } \ | 987 | *elem = (ptr[itr]+1); |
703 | child = apr_array_make(p,1,sizeof(char *)); \ | 988 | } else { |
704 | ptr = (char **)(parent->elts); \ | 989 | overwrite = 1; |
705 | if (overwrite==0) { \ | 990 | elem = (char **)apr_array_push(addlist); |
706 | /* if we are not overwriting the existing then prepare for merge */ \ | 991 | *elem = ptr[itr]; |
707 | for (itr=0; itr<parent->nelts; itr++) { \ | 992 | } |
708 | if (!in_array(addlist, ptr[itr]) && !in_array(dellist,ptr[itr])) { \ | 993 | } |
709 | elem = apr_array_push(child); \ | 994 | child = apr_array_make(p,1,sizeof(char *)); |
710 | *elem = apr_pstrdup(p, ptr[itr]); \ | 995 | ptr = (char **)(parent->elts); |
711 | } \ | 996 | if (overwrite==0) { |
712 | } \ | 997 | /* if we are not overwriting the existing then prepare for merge */ |
713 | } \ | 998 | for (itr=0; itr<parent->nelts; itr++) { |
714 | apr_array_cat(child, addlist); \ | 999 | if (!in_array(addlist, ptr[itr]) && !in_array(dellist,ptr[itr])) { |
1000 | elem = apr_array_push(ret); | ||
1001 | *elem = apr_pstrdup(p, ptr[itr]); | ||
1002 | } | ||
1003 | } | ||
1004 | } | ||
1005 | apr_array_cat(ret, addlist); | ||
1006 | apr_pool_destroy(subp); | ||
1007 | } | ||
1008 | return ret; | ||
715 | } | 1009 | } |
716 | 1010 | ||
717 | static void *log_sql_merge_state(apr_pool_t *p, void *basev, void *addv) | 1011 | static void *log_sql_merge_state(apr_pool_t *p, void *basev, void *addv) |
@@ -720,10 +1014,6 @@ static void *log_sql_merge_state(apr_pool_t *p, void *basev, void *addv) | |||
720 | logsql_state *parent = (logsql_state *) basev; | 1014 | logsql_state *parent = (logsql_state *) basev; |
721 | logsql_state *child = (logsql_state *) addv; | 1015 | logsql_state *child = (logsql_state *) addv; |
722 | 1016 | ||
723 | apr_pool_t *subp; | ||
724 | |||
725 | apr_pool_create(&subp,p); | ||
726 | |||
727 | /* Child can override these, otherwise they default to parent's choice. | 1017 | /* Child can override these, otherwise they default to parent's choice. |
728 | * If the parent didn't set them, create reasonable defaults for the | 1018 | * If the parent didn't set them, create reasonable defaults for the |
729 | * ones that should have such default settings. Leave the others null. */ | 1019 | * ones that should have such default settings. Leave the others null. */ |
@@ -734,13 +1024,6 @@ static void *log_sql_merge_state(apr_pool_t *p, void *basev, void *addv) | |||
734 | child->transfer_table_name = parent->transfer_table_name; | 1024 | child->transfer_table_name = parent->transfer_table_name; |
735 | } | 1025 | } |
736 | 1026 | ||
737 | if (child->transfer_log_format == DEFAULT_TRANSFER_LOG_FMT) { | ||
738 | child->transfer_log_format = parent->transfer_log_format; | ||
739 | /*apr_pool_clear(child->parsed_pool);*/ | ||
740 | child->parsed_log_format = apr_pcalloc(child->parsed_pool, | ||
741 | strlen(child->transfer_log_format) * sizeof(logsql_item *)); | ||
742 | } | ||
743 | |||
744 | if (child->preserve_file == DEFAULT_PRESERVE_FILE) | 1027 | if (child->preserve_file == DEFAULT_PRESERVE_FILE) |
745 | child->preserve_file = parent->preserve_file; | 1028 | child->preserve_file = parent->preserve_file; |
746 | /* server_root_relative the preserve file location */ | 1029 | /* server_root_relative the preserve file location */ |
@@ -759,15 +1042,13 @@ static void *log_sql_merge_state(apr_pool_t *p, void *basev, void *addv) | |||
759 | if (child->cookie_table_name == DEFAULT_COOKIE_TABLE_NAME) | 1042 | if (child->cookie_table_name == DEFAULT_COOKIE_TABLE_NAME) |
760 | child->cookie_table_name = parent->cookie_table_name; | 1043 | child->cookie_table_name = parent->cookie_table_name; |
761 | 1044 | ||
762 | DO_MERGE_ARRAY(parent->transfer_ignore_list, child->transfer_ignore_list, subp); | 1045 | child->transfer_ignore_list = do_merge_array(parent->transfer_ignore_list, child->transfer_ignore_list, p); |
763 | DO_MERGE_ARRAY(parent->transfer_accept_list, child->transfer_accept_list, subp); | 1046 | child->transfer_accept_list = do_merge_array(parent->transfer_accept_list, child->transfer_accept_list, p); |
764 | DO_MERGE_ARRAY(parent->remhost_ignore_list, child->remhost_ignore_list, subp); | 1047 | child->remhost_ignore_list = do_merge_array(parent->remhost_ignore_list, child->remhost_ignore_list, p); |
765 | DO_MERGE_ARRAY(parent->notes_list, child->notes_list, subp); | 1048 | child->notes_list = do_merge_array(parent->notes_list, child->notes_list, p); |
766 | DO_MERGE_ARRAY(parent->hin_list, child->hin_list, subp); | 1049 | child->hin_list = do_merge_array(parent->hin_list, child->hin_list, p); |
767 | DO_MERGE_ARRAY(parent->hout_list, child->hout_list, subp); | 1050 | child->hout_list = do_merge_array(parent->hout_list, child->hout_list, p); |
768 | DO_MERGE_ARRAY(parent->cookie_list,child->cookie_list, subp); | 1051 | child->cookie_list = do_merge_array(parent->cookie_list,child->cookie_list, p); |
769 | |||
770 | apr_pool_destroy(subp); | ||
771 | 1052 | ||
772 | if (!child->cookie_name) | 1053 | if (!child->cookie_name) |
773 | child->cookie_name = parent->cookie_name; | 1054 | child->cookie_name = parent->cookie_name; |
@@ -844,7 +1125,7 @@ static int log_sql_transaction(request_rec *orig) | |||
844 | char *cookie_query = NULL; | 1125 | char *cookie_query = NULL; |
845 | const char *unique_id; | 1126 | const char *unique_id; |
846 | const char *formatted_item; | 1127 | const char *formatted_item; |
847 | int i,length; | 1128 | int i, showcomma; |
848 | int proceed; | 1129 | int proceed; |
849 | 1130 | ||
850 | for (r = orig; r->next; r = r->next) { | 1131 | for (r = orig; r->next; r = r->next) { |
@@ -885,7 +1166,7 @@ static int log_sql_transaction(request_rec *orig) | |||
885 | thehost = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME, NULL); | 1166 | thehost = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME, NULL); |
886 | if (thehost) { | 1167 | if (thehost) { |
887 | for (ptrptr = (char **) cls->remhost_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->remhost_ignore_list->elt_size)) | 1168 | for (ptrptr = (char **) cls->remhost_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->remhost_ignore_list->elt_size)) |
888 | if (ap_strstr(thehost, *ptrptr)) { | 1169 | if (ap_strstr_c(thehost, *ptrptr)) { |
889 | return OK; | 1170 | return OK; |
890 | } | 1171 | } |
891 | } | 1172 | } |
@@ -893,18 +1174,19 @@ static int log_sql_transaction(request_rec *orig) | |||
893 | 1174 | ||
894 | /* Iterate through the format characters and set up the INSERT string according to | 1175 | /* Iterate through the format characters and set up the INSERT string according to |
895 | * what the user has configured. */ | 1176 | * what the user has configured. */ |
896 | length = strlen(cls->transfer_log_format); | 1177 | showcomma = 0; |
897 | for (i = 0; i<length; i++) { | 1178 | for (i = 0; i<cls->transfer_log_format->nelts; i++) { |
898 | logsql_item *item = cls->parsed_log_format[i]; | 1179 | logsql_field *item = cls->parsed_log_format[i]; |
899 | if (item==NULL) { | 1180 | if (item==NULL || item->func==NULL) { |
900 | log_error(APLOG_MARK, APLOG_ERR, 0, orig->server, | 1181 | log_error(APLOG_MARK, APLOG_ERR, 0, orig->server, |
901 | "Log Format '%c' unknown",cls->transfer_log_format[i]); | 1182 | "Log Format '%s' unknown or incomplete",((char **)cls->transfer_log_format->elts)[i]); |
902 | continue; | 1183 | continue; |
903 | } | 1184 | } |
904 | 1185 | ||
905 | /* Yes, this key is one of the configured keys. | 1186 | /* Yes, this key is one of the configured keys. |
906 | * Call the key's function and put the returned value into 'formatted_item' */ | 1187 | * Call the key's function and put the returned value into 'formatted_item' */ |
907 | formatted_item = item->func(item->want_orig_default ? orig : r, ""); | 1188 | formatted_item = item->func->func(item->func->want_orig_req ? orig : r, |
1189 | item->param ? item->param : ""); | ||
908 | 1190 | ||
909 | /* Massage 'formatted_item' for proper SQL eligibility... */ | 1191 | /* Massage 'formatted_item' for proper SQL eligibility... */ |
910 | if (!formatted_item) { | 1192 | if (!formatted_item) { |
@@ -916,10 +1198,11 @@ static int log_sql_transaction(request_rec *orig) | |||
916 | } | 1198 | } |
917 | 1199 | ||
918 | /* Append the fieldname and value-to-insert to the appropriate strings, quoting stringvals with ' as appropriate */ | 1200 | /* Append the fieldname and value-to-insert to the appropriate strings, quoting stringvals with ' as appropriate */ |
919 | fields = apr_pstrcat(r->pool, fields, (i ? "," : ""), | 1201 | fields = apr_pstrcat(r->pool, fields, (showcomma ? "," : ""), |
920 | item->sql_field_name, NULL); | 1202 | item->sql_field_name, NULL); |
921 | values = apr_pstrcat(r->pool, values, (i ? "," : ""), | 1203 | values = apr_pstrcat(r->pool, values, (showcomma ? "," : ""), |
922 | global_config.driver->escape(formatted_item, r->pool,&global_config.db), NULL); | 1204 | global_config.driver->escape(formatted_item, r->pool,&global_config.db), NULL); |
1205 | showcomma = 1; | ||
923 | } | 1206 | } |
924 | 1207 | ||
925 | /* Work through the list of notes defined by LogSQLWhichNotes */ | 1208 | /* Work through the list of notes defined by LogSQLWhichNotes */ |
@@ -1171,10 +1454,19 @@ static const command_rec log_sql_cmds[] = { | |||
1171 | (void *)APR_OFFSETOF(logsql_state, cookie_table_name), RSRC_CONF, | 1454 | (void *)APR_OFFSETOF(logsql_state, cookie_table_name), RSRC_CONF, |
1172 | "The database table that holds the cookie info") | 1455 | "The database table that holds the cookie info") |
1173 | , | 1456 | , |
1174 | /* Log format */ | 1457 | /* New Log Format */ |
1175 | AP_INIT_TAKE1("LogSQLTransferLogFormat", set_logformat_slot, | 1458 | AP_INIT_ITERATE("LogSQLTransferLogItems", add_server_string_slot, |
1459 | (void *)APR_OFFSETOF(logsql_state, transfer_log_format), RSRC_CONF, | ||
1460 | "What fields to log to the database transfer log") | ||
1461 | , | ||
1462 | AP_INIT_RAW_ARGS("LogSQLRegisterItem", set_register_field, | ||
1176 | NULL, RSRC_CONF, | 1463 | NULL, RSRC_CONF, |
1177 | "Instruct the module what information to log to the database transfer log") | 1464 | "Register a new Item for logging, Arguments: ItemName function argument sqlfield datatype datalen<br>" |
1465 | "datatypes are INT, SMALLINT, VARCHAR, CHAR<br>") | ||
1466 | , | ||
1467 | AP_INIT_TAKE1("LogSQLShowConfig", set_global_string_slot, | ||
1468 | (void *)APR_OFFSETOF(global_config_t, showconfig), RSRC_CONF, | ||
1469 | "Add this to export the entire running function and dfield configuration to the named file") | ||
1178 | , | 1470 | , |
1179 | /* Machine ID */ | 1471 | /* Machine ID */ |
1180 | AP_INIT_TAKE1("LogSQLMachineID", set_global_string_slot, | 1472 | AP_INIT_TAKE1("LogSQLMachineID", set_global_string_slot, |
@@ -1194,7 +1486,7 @@ static const command_rec log_sql_cmds[] = { | |||
1194 | (void *)APR_OFFSETOF(logsql_state, remhost_ignore_list), RSRC_CONF, | 1486 | (void *)APR_OFFSETOF(logsql_state, remhost_ignore_list), RSRC_CONF, |
1195 | "List of remote hosts to ignore. Accesses that match will not be logged to database") | 1487 | "List of remote hosts to ignore. Accesses that match will not be logged to database") |
1196 | , | 1488 | , |
1197 | /* Special loggin table configuration */ | 1489 | /* Special logging table configuration */ |
1198 | AP_INIT_TAKE1("LogSQLWhichCookie", set_server_string_slot, | 1490 | AP_INIT_TAKE1("LogSQLWhichCookie", set_server_string_slot, |
1199 | (void *)APR_OFFSETOF(logsql_state, cookie_name), RSRC_CONF, | 1491 | (void *)APR_OFFSETOF(logsql_state, cookie_name), RSRC_CONF, |
1200 | "The single cookie that you want logged in the access_log when using the 'c' config directive") | 1492 | "The single cookie that you want logged in the access_log when using the 'c' config directive") |
@@ -1219,6 +1511,10 @@ static const command_rec log_sql_cmds[] = { | |||
1219 | "<br><b>Deprecated</b><br>The following Commands are deprecated and should not be used.. <br>Read the documentation for more information<br><b>Deprecated</b>") | 1511 | "<br><b>Deprecated</b><br>The following Commands are deprecated and should not be used.. <br>Read the documentation for more information<br><b>Deprecated</b>") |
1220 | , | 1512 | , |
1221 | /* Deprecated commands */ | 1513 | /* Deprecated commands */ |
1514 | AP_INIT_TAKE1("LogSQLTransferLogFormat", set_logformat_slot, | ||
1515 | (void *)APR_OFFSETOF(logsql_state, transfer_log_format), RSRC_CONF, | ||
1516 | "<b>(Deprecated) Use LogSQLTransferLogItem to specify symbolic log items instead") | ||
1517 | , | ||
1222 | AP_INIT_TAKE1("LogSQLDatabase", set_dbparam_slot, | 1518 | AP_INIT_TAKE1("LogSQLDatabase", set_dbparam_slot, |
1223 | (void *)"database", RSRC_CONF, | 1519 | (void *)"database", RSRC_CONF, |
1224 | "<b>(Deprecated) Use LogSQLDBParam database dbname.</b> The name of the database database for logging") | 1520 | "<b>(Deprecated) Use LogSQLDBParam database dbname.</b> The name of the database database for logging") |