diff options
Diffstat (limited to 'mod_log_sql.c')
-rw-r--r-- | mod_log_sql.c | 181 |
1 files changed, 106 insertions, 75 deletions
diff --git a/mod_log_sql.c b/mod_log_sql.c index abebd04..68c1e98 100644 --- a/mod_log_sql.c +++ b/mod_log_sql.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $Header: /home/cvs/mod_log_sql/mod_log_sql.c,v 1.11 2004/01/21 04:34:21 urkle Exp $ */ | 1 | /* $Header: /home/cvs/mod_log_sql/mod_log_sql.c,v 1.12 2004/01/22 05:26:56 urkle Exp $ */ |
2 | /* --------* | 2 | /* --------* |
3 | * DEFINES * | 3 | * DEFINES * |
4 | * --------*/ | 4 | * --------*/ |
@@ -84,6 +84,15 @@ typedef struct { | |||
84 | 84 | ||
85 | static global_config_t global_config; | 85 | static global_config_t global_config; |
86 | 86 | ||
87 | /* structure to hold helper function info */ | ||
88 | typedef struct { | ||
89 | char key; /* item letter character */ | ||
90 | log_sql_item_func *func; /* its extraction function */ | ||
91 | const char *sql_field_name; /* its column in SQL */ | ||
92 | int want_orig_default; /* if it requires the original request prior to internal redirection */ | ||
93 | int string_contents; /* if it returns a string */ | ||
94 | } log_sql_item; | ||
95 | |||
87 | /* But the contents of this structure will vary by virtual server. | 96 | /* But the contents of this structure will vary by virtual server. |
88 | * This permits each virtual server to vary its configuration slightly | 97 | * This permits each virtual server to vary its configuration slightly |
89 | * for per-server customization. | 98 | * for per-server customization. |
@@ -98,14 +107,16 @@ typedef struct { | |||
98 | apr_array_header_t *hout_list; | 107 | apr_array_header_t *hout_list; |
99 | apr_array_header_t *hin_list; | 108 | apr_array_header_t *hin_list; |
100 | apr_array_header_t *cookie_list; | 109 | apr_array_header_t *cookie_list; |
101 | char *notes_table_name; | 110 | const char *notes_table_name; |
102 | char *hout_table_name; | 111 | const char *hout_table_name; |
103 | char *hin_table_name; | 112 | const char *hin_table_name; |
104 | char *cookie_table_name; | 113 | const char *cookie_table_name; |
105 | char *transfer_table_name; | 114 | const char *transfer_table_name; |
106 | char *transfer_log_format; | 115 | const char *transfer_log_format; |
107 | char *preserve_file; | 116 | apr_pool_t *parsed_pool; |
108 | char *cookie_name; | 117 | log_sql_item **parsed_log_format; |
118 | const char *preserve_file; | ||
119 | const char *cookie_name; | ||
109 | } logsql_state; | 120 | } logsql_state; |
110 | 121 | ||
111 | 122 | ||
@@ -115,39 +126,39 @@ typedef struct { | |||
115 | 126 | ||
116 | static int safe_create_tables(logsql_state *cls, request_rec *r); | 127 | static int safe_create_tables(logsql_state *cls, request_rec *r); |
117 | 128 | ||
118 | typedef struct { | ||
119 | char key; /* item letter character */ | ||
120 | log_sql_item_func *func; /* its extraction function */ | ||
121 | const char *sql_field_name; /* its column in SQL */ | ||
122 | int want_orig_default; /* if it requires the original request prior to internal redirection */ | ||
123 | int string_contents; /* if it returns a string */ | ||
124 | } log_sql_item; | ||
125 | |||
126 | static apr_array_header_t *log_sql_item_list; | 129 | static apr_array_header_t *log_sql_item_list; |
127 | 130 | ||
128 | /* Registration Function for extract functions */ | 131 | /* Registration Function for extract functions * |
129 | LOGSQL_DECLARE(void) log_sql_register_item(apr_pool_t *p, char key, | 132 | * and update parse cache for transfer_log_format * |
130 | log_sql_item_func *func, const char *sql_field_name, | 133 | * this is exported from the module */ |
134 | LOGSQL_DECLARE(void) log_sql_register_item(server_rec *s, apr_pool_t *p, | ||
135 | char key, log_sql_item_func *func, const char *sql_field_name, | ||
131 | int want_orig_default, int string_contents) | 136 | int want_orig_default, int string_contents) |
132 | { | 137 | { |
133 | log_sql_item *item = apr_array_push(log_sql_item_list); | 138 | server_rec *ts; |
139 | log_sql_item *item; | ||
140 | if (!log_sql_item_list) | ||
141 | log_sql_item_list = apr_array_make(p,10, sizeof(log_sql_item)); | ||
142 | |||
143 | item= apr_array_push(log_sql_item_list); | ||
134 | item->key = key; | 144 | item->key = key; |
135 | item->func = func; | 145 | item->func = func; |
136 | item->sql_field_name = sql_field_name; | 146 | item->sql_field_name = sql_field_name; |
137 | item->want_orig_default = want_orig_default; | 147 | item->want_orig_default = want_orig_default; |
138 | item->string_contents = string_contents; | 148 | item->string_contents = string_contents; |
139 | } | 149 | /* some voodoo here to post parse logitems in all servers * |
140 | 150 | * so a "cached" list is used in the main logging loop for speed */ | |
141 | /* Search through item array */ | 151 | for (ts = s; ts; ts = ts->next) { |
142 | static inline log_sql_item *log_sql_get_item(char key) | 152 | logsql_state *cfg = ap_get_module_config(ts->module_config, |
143 | { | 153 | &log_sql_module); |
144 | int itr; | 154 | char *pos; |
145 | for(itr=0; itr<log_sql_item_list->nelts; itr++) { | 155 | |
146 | if (((log_sql_item *)log_sql_item_list->elts)[itr].key == key) { | 156 | if (cfg->transfer_log_format) { |
147 | return &((log_sql_item *)log_sql_item_list->elts)[itr]; | 157 | if ( (pos = strchr(cfg->transfer_log_format,key))!=NULL) { |
158 | cfg->parsed_log_format[pos - cfg->transfer_log_format] = item; | ||
159 | } | ||
148 | } | 160 | } |
149 | } | 161 | } |
150 | return NULL; | ||
151 | } | 162 | } |
152 | 163 | ||
153 | /* Include all the extract functions */ | 164 | /* Include all the extract functions */ |
@@ -570,6 +581,19 @@ static const char *set_server_string_slot(cmd_parms *cmd, | |||
570 | return NULL; | 581 | return NULL; |
571 | } | 582 | } |
572 | 583 | ||
584 | static const char *set_logformat_slot(cmd_parms *cmd, | ||
585 | void *struct_ptr, | ||
586 | const char *arg) | ||
587 | { | ||
588 | logsql_state *cfg = ap_get_module_config(cmd->server->module_config, | ||
589 | &log_sql_module); | ||
590 | |||
591 | cfg->transfer_log_format = arg; | ||
592 | /* apr_pool_clear(cfg->parsed_pool);*/ | ||
593 | cfg->parsed_log_format = apr_pcalloc(cfg->parsed_pool, | ||
594 | strlen(arg) * sizeof(log_sql_item *)); | ||
595 | return NULL; | ||
596 | } | ||
573 | 597 | ||
574 | static const char *set_server_nmv_string_slot(cmd_parms *parms, | 598 | static const char *set_server_nmv_string_slot(cmd_parms *parms, |
575 | void *struct_ptr, | 599 | void *struct_ptr, |
@@ -681,9 +705,9 @@ void *log_sql_initializer(server_rec *main_server, apr_pool_t *p) | |||
681 | 705 | ||
682 | } | 706 | } |
683 | */ | 707 | */ |
684 | 708 | /* post_config / module_init */ | |
685 | #if defined(WITH_APACHE20) | 709 | #if defined(WITH_APACHE20) |
686 | static int log_sql_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) | 710 | static int log_sql_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) |
687 | #elif defined(WITH_APACHE13) | 711 | #elif defined(WITH_APACHE13) |
688 | static void log_sql_module_init(server_rec *s, apr_pool_t *p) | 712 | static void log_sql_module_init(server_rec *s, apr_pool_t *p) |
689 | #endif | 713 | #endif |
@@ -693,41 +717,38 @@ static void log_sql_module_init(server_rec *s, apr_pool_t *p) | |||
693 | global_config.socketfile = "/tmp/mysql.sock"; | 717 | global_config.socketfile = "/tmp/mysql.sock"; |
694 | if (!global_config.tcpport) | 718 | if (!global_config.tcpport) |
695 | global_config.tcpport = 3306; | 719 | global_config.tcpport = 3306; |
696 | if (!log_sql_item_list) | ||
697 | log_sql_item_list = apr_array_make(p,10,sizeof(log_sql_item)); | ||
698 | 720 | ||
699 | /* Register handlers */ | 721 | /* Register handlers */ |
700 | log_sql_register_item(p,'A', extract_agent, "agent", 1, 1); | 722 | log_sql_register_item(s,p,'A', extract_agent, "agent", 1, 1); |
701 | log_sql_register_item(p,'a', extract_request_args, "request_args", 1, 1); | 723 | log_sql_register_item(s,p,'a', extract_request_args, "request_args", 1, 1); |
702 | log_sql_register_item(p,'b', extract_bytes_sent, "bytes_sent", 0, 0); | 724 | log_sql_register_item(s,p,'b', extract_bytes_sent, "bytes_sent", 0, 0); |
703 | log_sql_register_item(p,'c', extract_cookie, "cookie", 0, 1); | 725 | log_sql_register_item(s,p,'c', extract_cookie, "cookie", 0, 1); |
704 | log_sql_register_item(p,'e', extract_env_var, "env_var", 0, 1); | 726 | log_sql_register_item(s,p,'e', extract_env_var, "env_var", 0, 1); |
705 | log_sql_register_item(p,'f', extract_request_file, "request_file", 0, 1); | 727 | log_sql_register_item(s,p,'f', extract_request_file, "request_file", 0, 1); |
706 | log_sql_register_item(p,'H', extract_request_protocol, "request_protocol", 0, 1); | 728 | log_sql_register_item(s,p,'H', extract_request_protocol, "request_protocol", 0, 1); |
707 | log_sql_register_item(p,'h', extract_remote_host, "remote_host", 0, 1); | 729 | log_sql_register_item(s,p,'h', extract_remote_host, "remote_host", 0, 1); |
708 | log_sql_register_item(p,'I', extract_unique_id, "id", 0, 1); | 730 | log_sql_register_item(s,p,'I', extract_unique_id, "id", 0, 1); |
709 | log_sql_register_item(p,'l', extract_remote_logname, "remote_logname", 0, 1); | 731 | log_sql_register_item(s,p,'l', extract_remote_logname, "remote_logname", 0, 1); |
710 | log_sql_register_item(p,'m', extract_request_method, "request_method", 0, 1); | 732 | log_sql_register_item(s,p,'m', extract_request_method, "request_method", 0, 1); |
711 | log_sql_register_item(p,'M', extract_machine_id, "machine_id", 0, 1); | 733 | log_sql_register_item(s,p,'M', extract_machine_id, "machine_id", 0, 1); |
712 | log_sql_register_item(p,'P', extract_child_pid, "child_pid", 0, 0); | 734 | log_sql_register_item(s,p,'P', extract_child_pid, "child_pid", 0, 0); |
713 | log_sql_register_item(p,'p', extract_server_port, "server_port", 0, 0); | 735 | log_sql_register_item(s,p,'p', extract_server_port, "server_port", 0, 0); |
714 | log_sql_register_item(p,'R', extract_referer, "referer", 1, 1); | 736 | log_sql_register_item(s,p,'R', extract_referer, "referer", 1, 1); |
715 | log_sql_register_item(p,'r', extract_request_line, "request_line", 1, 1); | 737 | log_sql_register_item(s,p,'r', extract_request_line, "request_line", 1, 1); |
716 | log_sql_register_item(p,'S', extract_request_timestamp, "time_stamp", 0, 0); | 738 | log_sql_register_item(s,p,'S', extract_request_timestamp, "time_stamp", 0, 0); |
717 | log_sql_register_item(p,'s', extract_status, "status", 1, 0); | 739 | log_sql_register_item(s,p,'s', extract_status, "status", 1, 0); |
718 | log_sql_register_item(p,'T', extract_request_duration, "request_duration", 1, 0); | 740 | log_sql_register_item(s,p,'T', extract_request_duration, "request_duration", 1, 0); |
719 | log_sql_register_item(p,'t', extract_request_time, "request_time", 0, 1); | 741 | log_sql_register_item(s,p,'t', extract_request_time, "request_time", 0, 1); |
720 | log_sql_register_item(p,'u', extract_remote_user, "remote_user", 0, 1); | 742 | log_sql_register_item(s,p,'u', extract_remote_user, "remote_user", 0, 1); |
721 | log_sql_register_item(p,'U', extract_request_uri, "request_uri", 1, 1); | 743 | log_sql_register_item(s,p,'U', extract_request_uri, "request_uri", 1, 1); |
722 | log_sql_register_item(p,'v', extract_virtual_host, "virtual_host", 0, 1); | 744 | log_sql_register_item(s,p,'v', extract_virtual_host, "virtual_host", 0, 1); |
723 | 745 | ||
724 | #if defined(WITH_APACHE20) | 746 | #if defined(WITH_APACHE20) |
725 | return OK; | 747 | return OK; |
726 | #endif | 748 | #endif |
727 | } | 749 | } |
728 | 750 | ||
729 | /* | 751 | /* This function gets called to create a per-server configuration |
730 | * This function gets called to create a per-server configuration | ||
731 | * record. It will always be called for the main server and | 752 | * record. It will always be called for the main server and |
732 | * for each virtual server that is established. Each server maintains | 753 | * for each virtual server that is established. Each server maintains |
733 | * its own state that is separate from the others' states. | 754 | * its own state that is separate from the others' states. |
@@ -741,6 +762,9 @@ static void *log_sql_make_state(apr_pool_t *p, server_rec *s) | |||
741 | 762 | ||
742 | /* These defaults are overridable in the httpd.conf file. */ | 763 | /* These defaults are overridable in the httpd.conf file. */ |
743 | cls->transfer_log_format = DEFAULT_TRANSFER_LOG_FMT; | 764 | cls->transfer_log_format = DEFAULT_TRANSFER_LOG_FMT; |
765 | apr_pool_create(&cls->parsed_pool, p); | ||
766 | cls->parsed_log_format = apr_pcalloc(cls->parsed_pool, | ||
767 | strlen(cls->transfer_log_format) * sizeof(log_sql_item *)); | ||
744 | cls->notes_table_name = DEFAULT_NOTES_TABLE_NAME; | 768 | cls->notes_table_name = DEFAULT_NOTES_TABLE_NAME; |
745 | cls->hin_table_name = DEFAULT_HIN_TABLE_NAME; | 769 | cls->hin_table_name = DEFAULT_HIN_TABLE_NAME; |
746 | cls->hout_table_name = DEFAULT_HOUT_TABLE_NAME; | 770 | cls->hout_table_name = DEFAULT_HOUT_TABLE_NAME; |
@@ -773,8 +797,12 @@ static void *log_sql_merge_state(apr_pool_t *p, void *basev, void *addv) | |||
773 | /* No default for transfer_table_name because we want its absence | 797 | /* No default for transfer_table_name because we want its absence |
774 | * to disable logging. */ | 798 | * to disable logging. */ |
775 | 799 | ||
776 | if (child->transfer_log_format == DEFAULT_TRANSFER_LOG_FMT) | 800 | if (child->transfer_log_format == DEFAULT_TRANSFER_LOG_FMT) { |
777 | child->transfer_log_format = parent->transfer_log_format; | 801 | child->transfer_log_format = parent->transfer_log_format; |
802 | /*apr_pool_clear(child->parsed_pool);*/ | ||
803 | child->parsed_log_format = apr_pcalloc(child->parsed_pool, | ||
804 | strlen(child->transfer_log_format) * sizeof(log_sql_item *)); | ||
805 | } | ||
778 | 806 | ||
779 | if (child->preserve_file == DEFAULT_PRESERVE_FILE) | 807 | if (child->preserve_file == DEFAULT_PRESERVE_FILE) |
780 | child->preserve_file = parent->preserve_file; | 808 | child->preserve_file = parent->preserve_file; |
@@ -827,11 +855,11 @@ static int log_sql_transaction(request_rec *orig) | |||
827 | logsql_state *cls = ap_get_module_config(orig->server->module_config, &log_sql_module); | 855 | logsql_state *cls = ap_get_module_config(orig->server->module_config, &log_sql_module); |
828 | const char *access_query; | 856 | const char *access_query; |
829 | request_rec *r; | 857 | request_rec *r; |
830 | char *transfer_tablename = cls->transfer_table_name; | 858 | const char *transfer_tablename = cls->transfer_table_name; |
831 | char *notes_tablename = cls->notes_table_name; | 859 | const char *notes_tablename = cls->notes_table_name; |
832 | char *hout_tablename = cls->hout_table_name; | 860 | const char *hout_tablename = cls->hout_table_name; |
833 | char *hin_tablename = cls->hin_table_name; | 861 | const char *hin_tablename = cls->hin_table_name; |
834 | char *cookie_tablename = cls->cookie_table_name; | 862 | const char *cookie_tablename = cls->cookie_table_name; |
835 | 863 | ||
836 | /* We handle mass virtual hosting differently. Dynamically determine the name | 864 | /* We handle mass virtual hosting differently. Dynamically determine the name |
837 | * of the table from the virtual server's name, and flag it for creation. | 865 | * of the table from the virtual server's name, and flag it for creation. |
@@ -882,8 +910,7 @@ static int log_sql_transaction(request_rec *orig) | |||
882 | char *cookie_query = NULL; | 910 | char *cookie_query = NULL; |
883 | const char *unique_id; | 911 | const char *unique_id; |
884 | const char *formatted_item; | 912 | const char *formatted_item; |
885 | char *s; | 913 | int i,length; |
886 | int i; | ||
887 | int proceed; | 914 | int proceed; |
888 | 915 | ||
889 | for (r = orig; r->next; r = r->next) { | 916 | for (r = orig; r->next; r = r->next) { |
@@ -932,9 +959,14 @@ static int log_sql_transaction(request_rec *orig) | |||
932 | 959 | ||
933 | /* Iterate through the format characters and set up the INSERT string according to | 960 | /* Iterate through the format characters and set up the INSERT string according to |
934 | * what the user has configured. */ | 961 | * what the user has configured. */ |
935 | i = 0; | 962 | length = strlen(cls->transfer_log_format); |
936 | for (s = cls->transfer_log_format; *s != '\0' ; s++) { | 963 | for (i = 0; i<length; i++) { |
937 | log_sql_item *item = log_sql_get_item(*s); | 964 | log_sql_item *item = cls->parsed_log_format[i]; |
965 | if (item==NULL) { | ||
966 | log_error(APLOG_MARK, APLOG_ERR, orig->server, | ||
967 | "Log Format '%c' unknown",cls->transfer_log_format[i]); | ||
968 | continue; | ||
969 | } | ||
938 | 970 | ||
939 | /* Yes, this key is one of the configured keys. | 971 | /* Yes, this key is one of the configured keys. |
940 | * Call the key's function and put the returned value into 'formatted_item' */ | 972 | * Call the key's function and put the returned value into 'formatted_item' */ |
@@ -956,7 +988,6 @@ static int log_sql_transaction(request_rec *orig) | |||
956 | (item->string_contents ? "'" : ""), | 988 | (item->string_contents ? "'" : ""), |
957 | escape_query(formatted_item, r->pool), | 989 | escape_query(formatted_item, r->pool), |
958 | (item->string_contents ? "'" : ""), NULL); | 990 | (item->string_contents ? "'" : ""), NULL); |
959 | i = 1; | ||
960 | } | 991 | } |
961 | 992 | ||
962 | /* Work through the list of notes defined by LogSQLWhichNotes */ | 993 | /* Work through the list of notes defined by LogSQLWhichNotes */ |
@@ -1188,8 +1219,8 @@ static const command_rec log_sql_cmds[] = { | |||
1188 | (void *)APR_OFFSETOF(logsql_state, cookie_table_name), RSRC_CONF, | 1219 | (void *)APR_OFFSETOF(logsql_state, cookie_table_name), RSRC_CONF, |
1189 | "The database table that holds the cookie info") | 1220 | "The database table that holds the cookie info") |
1190 | , | 1221 | , |
1191 | AP_INIT_TAKE1("LogSQLTransferLogFormat", set_server_string_slot, | 1222 | AP_INIT_TAKE1("LogSQLTransferLogFormat", set_logformat_slot, |
1192 | (void *)APR_OFFSETOF(logsql_state,transfer_log_format), RSRC_CONF, | 1223 | NULL, RSRC_CONF, |
1193 | "Instruct the module what information to log to the database transfer log") | 1224 | "Instruct the module what information to log to the database transfer log") |
1194 | , | 1225 | , |
1195 | AP_INIT_TAKE1("LogSQLMachineID", set_global_string_slot, | 1226 | AP_INIT_TAKE1("LogSQLMachineID", set_global_string_slot, |
@@ -1271,7 +1302,7 @@ static const command_rec log_sql_cmds[] = { | |||
1271 | /* The configuration array that sets up the hooks into the module. */ | 1302 | /* The configuration array that sets up the hooks into the module. */ |
1272 | #if defined(WITH_APACHE20) | 1303 | #if defined(WITH_APACHE20) |
1273 | static void register_hooks(apr_pool_t *p) { | 1304 | static void register_hooks(apr_pool_t *p) { |
1274 | ap_hook_pre_config(log_sql_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); | 1305 | ap_hook_post_config(log_sql_post_config, NULL, NULL, APR_HOOK_REALLY_FIRST); |
1275 | ap_hook_child_init(log_sql_child_init, NULL, NULL, APR_HOOK_MIDDLE); | 1306 | ap_hook_child_init(log_sql_child_init, NULL, NULL, APR_HOOK_MIDDLE); |
1276 | ap_hook_open_logs(log_sql_open, NULL, NULL, APR_HOOK_MIDDLE); | 1307 | ap_hook_open_logs(log_sql_open, NULL, NULL, APR_HOOK_MIDDLE); |
1277 | ap_hook_log_transaction(log_sql_transaction, NULL, NULL, APR_HOOK_MIDDLE); | 1308 | ap_hook_log_transaction(log_sql_transaction, NULL, NULL, APR_HOOK_MIDDLE); |