summaryrefslogtreecommitdiffstatsabout
path: root/mod_log_sql.c
diff options
context:
space:
mode:
Diffstat (limited to 'mod_log_sql.c')
-rw-r--r--mod_log_sql.c618
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
64static global_config_t global_config; 67static global_config_t global_config;
65 68
66/* structure to hold helper function info */ 69/* structure to hold helper function info */
67typedef struct { 70typedef 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 */
77static apr_array_header_t *logsql_function_list;
78
79/* structure to hold sqlfield mappings */
80typedef 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 */
92static 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 */
126LOGSQL_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);
103static 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);
108LOGSQL_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 */
146LOGSQL_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 */
172LOGSQL_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 */
200LOGSQL_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
265static const char *set_server_string_slot(cmd_parms *cmd, 375static 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
299static const char *set_logformat_slot(cmd_parms *cmd, 409static 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
313static const char *set_server_nmv_string_slot(cmd_parms *parms, 430static 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
524static 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
537static 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
634static 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)
465static int log_sql_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) 638static 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
467static void log_sql_module_init(server_rec *s, apr_pool_t *p) 640static 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 */ 964static 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{
681if (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
717static void *log_sql_merge_state(apr_pool_t *p, void *basev, void *addv) 1011static 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")