diff options
Diffstat (limited to 'mod_log_sql.c')
-rw-r--r-- | mod_log_sql.c | 324 |
1 files changed, 205 insertions, 119 deletions
diff --git a/mod_log_sql.c b/mod_log_sql.c index 3fc7ace..117111b 100644 --- a/mod_log_sql.c +++ b/mod_log_sql.c | |||
@@ -1,11 +1,11 @@ | |||
1 | /* $Id: mod_log_sql.c,v 1.19 2002/11/27 07:13:58 helios Exp $ */ | 1 | /* $Id: mod_log_sql.c,v 1.20 2002/12/10 19:43:21 helios Exp $ */ |
2 | 2 | ||
3 | /* --------* | 3 | /* --------* |
4 | * DEFINES * | 4 | * DEFINES * |
5 | * --------*/ | 5 | * --------*/ |
6 | 6 | ||
7 | /* The enduser may wish to modify this */ | 7 | /* The enduser may wish to modify this */ |
8 | #define DEBUG | 8 | #undef DEBUG |
9 | 9 | ||
10 | /* The enduser won't modify these */ | 10 | /* The enduser won't modify these */ |
11 | #define MYSQL_ERROR(mysql) ((mysql)?(mysql_error(mysql)):"MySQL server has gone away") | 11 | #define MYSQL_ERROR(mysql) ((mysql)?(mysql_error(mysql)):"MySQL server has gone away") |
@@ -20,11 +20,13 @@ | |||
20 | #include <time.h> | 20 | #include <time.h> |
21 | #include <stdio.h> | 21 | #include <stdio.h> |
22 | #include <stdlib.h> | 22 | #include <stdlib.h> |
23 | #include <string.h> | ||
23 | #include "httpd.h" | 24 | #include "httpd.h" |
24 | #include "http_config.h" | 25 | #include "http_config.h" |
25 | #include "http_log.h" | 26 | #include "http_log.h" |
26 | #include "http_core.h" | 27 | #include "http_core.h" |
27 | #include "mysql.h" | 28 | #include "mysql.h" |
29 | #include "mysqld_error.h" | ||
28 | 30 | ||
29 | #if MODULE_MAGIC_NUMBER >= 19980324 /* M_M_N is defined in /usr/local/Apache/include/ap_mmn.h, 19990320 as of this writing. */ | 31 | #if MODULE_MAGIC_NUMBER >= 19980324 /* M_M_N is defined in /usr/local/Apache/include/ap_mmn.h, 19990320 as of this writing. */ |
30 | #include "ap_compat.h" | 32 | #include "ap_compat.h" |
@@ -73,8 +75,8 @@ typedef const char *(*item_key_func) (request_rec *, char *); | |||
73 | * Each child process has its own segregated copy of this structure. | 75 | * Each child process has its own segregated copy of this structure. |
74 | */ | 76 | */ |
75 | typedef struct { | 77 | typedef struct { |
76 | int table_made; | ||
77 | array_header *transfer_ignore_list; | 78 | array_header *transfer_ignore_list; |
79 | array_header *transfer_accept_list; | ||
78 | array_header *remhost_ignore_list; | 80 | array_header *remhost_ignore_list; |
79 | array_header *notes_list; | 81 | array_header *notes_list; |
80 | array_header *hout_list; | 82 | array_header *hout_list; |
@@ -94,6 +96,9 @@ typedef struct { | |||
94 | /* -----------------* | 96 | /* -----------------* |
95 | * HELPER FUNCTIONS * | 97 | * HELPER FUNCTIONS * |
96 | * -----------------*/ | 98 | * -----------------*/ |
99 | |||
100 | int safe_create_tables(log_sql_state *cls, request_rec *r); | ||
101 | |||
97 | static char *format_integer(pool *p, int i) | 102 | static char *format_integer(pool *p, int i) |
98 | { | 103 | { |
99 | char dummy[40]; | 104 | char dummy[40]; |
@@ -484,7 +489,7 @@ static const char *extract_request_timestamp(request_rec *r, char *a) | |||
484 | { | 489 | { |
485 | char tstr[32]; | 490 | char tstr[32]; |
486 | 491 | ||
487 | snprintf(tstr, 32, "%ld", time(NULL)); | 492 | ap_snprintf(tstr, 32, "%ld", time(NULL)); |
488 | return pstrdup(r->pool, tstr); | 493 | return pstrdup(r->pool, tstr); |
489 | } | 494 | } |
490 | 495 | ||
@@ -665,73 +670,123 @@ void preserve_entry(request_rec *r, const char *query) | |||
665 | /* Parms: request record, SQL insert statement */ | 670 | /* Parms: request record, SQL insert statement */ |
666 | /* Returns: 0 (OK) on success */ | 671 | /* Returns: 0 (OK) on success */ |
667 | /* 1 if have no log handle */ | 672 | /* 1 if have no log handle */ |
668 | /* actual MySQL return code on error */ | 673 | /* 2 if insert delayed failed (kluge) */ |
674 | /* the actual MySQL return code on error */ | ||
669 | /*-----------------------------------------------------*/ | 675 | /*-----------------------------------------------------*/ |
670 | unsigned int safe_mysql_query(request_rec *r, const char *query) | 676 | unsigned int safe_mysql_query(request_rec *r, const char *query) |
671 | { | 677 | { |
672 | unsigned int retval; | 678 | int retval; |
673 | unsigned int real_error; | ||
674 | struct timespec delay, remainder; | 679 | struct timespec delay, remainder; |
675 | int ret; | 680 | int ret; |
676 | void (*handler) (int); | 681 | void (*handler) (int); |
677 | 682 | log_sql_state *cls; | |
683 | unsigned int real_error; | ||
684 | #ifdef WANT_DELAYED_MYSQL_INSERT | ||
685 | char *real_error_str; | ||
686 | #endif | ||
678 | 687 | ||
679 | /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */ | 688 | /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */ |
680 | handler = signal(SIGPIPE, SIG_IGN); | 689 | handler = signal(SIGPIPE, SIG_IGN); |
681 | 690 | ||
682 | /* First attempt for the query */ | 691 | /* First attempt for the query */ |
683 | if (mysql_log != NULL) | 692 | if (!mysql_log) { |
684 | retval = mysql_query(mysql_log, query); | 693 | signal(SIGPIPE, handler); |
685 | else | 694 | return 1; |
686 | return 1; | 695 | } else if (!(retval = mysql_query(mysql_log, query))) { |
696 | signal(SIGPIPE, handler); | ||
697 | return 0; | ||
698 | } | ||
687 | 699 | ||
688 | if ( retval != 0 ) | 700 | /* If we ran the query and it returned an error, try to be robust. |
689 | { | 701 | * (After all, the module thought it had a valid mysql_log connection but the query |
690 | /* If we ran the query and it returned an error, try to be robust. | 702 | * could have failed for a number of reasons, so we have to be extra-safe and check.) */ |
691 | * (After all, the module thought it had a valid mysql_log connection but the query | 703 | #ifdef WANT_DELAYED_MYSQL_INSERT |
692 | * could have failed for a number of reasons, so we have to be extra-safe and check.) */ | 704 | real_error_str = MYSQL_ERROR(mysql_log); |
693 | 705 | #else | |
694 | log_sql_state *cls = get_module_config(r->server->module_config, &sql_log_module); | 706 | real_error = mysql_errno(mysql_log); |
695 | 707 | #endif | |
696 | real_error = mysql_errno(mysql_log); /* What really happened? */ | 708 | |
697 | 709 | /* Check to see if the error is "nonexistent table" */ | |
698 | /* Something went wrong, so start by trying to restart the db link. */ | 710 | #ifdef WANT_DELAYED_MYSQL_INSERT |
699 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: first attempt failed, API said: error %d, %s", real_error, MYSQL_ERROR(mysql_log)); | 711 | if ((strstr(real_error_str, "Table")) && (strstr(real_error_str,"doesn't exist"))) { |
700 | mysql_close(mysql_log); | 712 | #else |
701 | mysql_log = NULL; | 713 | if (real_error == ER_NO_SUCH_TABLE) { |
702 | open_logdb_link(r->server); | 714 | #endif |
703 | 715 | if (create_tables) { | |
704 | if (mysql_log == NULL) { /* still unable to link */ | 716 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: table doesn't exist...creating now"); |
705 | signal(SIGPIPE, handler); | 717 | cls = get_module_config(r->server->module_config, &sql_log_module); |
706 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: reconnect failed, unable to reach database. SQL logging stopped until child regains a db connection."); | 718 | if (safe_create_tables(cls, r)) { |
707 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: log entries are being preserved in %s", cls->preserve_file); | 719 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: child attempted but failed to create one or more tables for %s, preserving query", ap_get_server_name(r)); |
708 | return 1; | 720 | preserve_entry(r, query); |
709 | } else | 721 | retval = mysql_errno(mysql_log); |
710 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: reconnect successful"); | 722 | } else { |
711 | 723 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: tables successfully created - retrying query"); | |
712 | /* First sleep for a tiny amount of time. */ | 724 | if (mysql_query(mysql_log, query)) { |
713 | delay.tv_sec = 0; | 725 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: giving up, preserving query"); |
714 | delay.tv_nsec = 250000000; /* max is 999999999 (nine nines) */ | 726 | preserve_entry(r, query); |
715 | ret = nanosleep(&delay, &remainder); | 727 | retval = mysql_errno(mysql_log); |
716 | if (ret && errno != EINTR) | 728 | } else |
717 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: nanosleep unsuccessful"); | 729 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: query successful after table creation"); |
718 | 730 | retval = 0; | |
719 | /* Then make our second attempt */ | 731 | } |
720 | retval = mysql_query(mysql_log,query); | 732 | } else { |
721 | 733 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql, table doesn't exist, creation denied by configuration, preserving query"); | |
722 | /* If this one also failed, log that and append to our local offline file */ | 734 | preserve_entry(r, query); |
723 | if ( retval != 0 ) | 735 | retval = ER_NO_SUCH_TABLE; |
724 | { | 736 | } |
725 | real_error = mysql_errno(mysql_log); | 737 | /* Restore SIGPIPE to its original handler function */ |
726 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: second attempt failed, API said: error %d, %s", real_error, MYSQL_ERROR(mysql_log)); | 738 | signal(SIGPIPE, handler); |
727 | retval = real_error; | 739 | return retval; |
728 | } else | ||
729 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: second attempt successful"); | ||
730 | } | 740 | } |
731 | 741 | ||
742 | /* Handle all other types of errors */ | ||
743 | |||
744 | cls = get_module_config(r->server->module_config, &sql_log_module); | ||
745 | |||
746 | /* Something went wrong, so start by trying to restart the db link. */ | ||
747 | #ifdef WANT_DELAYED_MYSQL_INSERT | ||
748 | real_error = 2; | ||
749 | #else | ||
750 | real_error = mysql_errno(mysql_log); | ||
751 | #endif | ||
752 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: first attempt failed, API said: error %d, \"%s\"", real_error, MYSQL_ERROR(mysql_log)); | ||
753 | mysql_close(mysql_log); | ||
754 | mysql_log = NULL; | ||
755 | open_logdb_link(r->server); | ||
756 | |||
757 | if (mysql_log == NULL) { /* still unable to link */ | ||
758 | signal(SIGPIPE, handler); | ||
759 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: reconnect failed, unable to reach database. SQL logging stopped until child regains a db connection."); | ||
760 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: log entries are being preserved in %s", cls->preserve_file); | ||
761 | return 1; | ||
762 | } else | ||
763 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: db reconnect successful"); | ||
764 | |||
765 | /* First sleep for a tiny amount of time. */ | ||
766 | delay.tv_sec = 0; | ||
767 | delay.tv_nsec = 250000000; /* max is 999999999 (nine nines) */ | ||
768 | ret = nanosleep(&delay, &remainder); | ||
769 | if (ret && errno != EINTR) | ||
770 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: nanosleep unsuccessful"); | ||
771 | |||
772 | /* Then make our second attempt */ | ||
773 | retval = mysql_query(mysql_log,query); | ||
774 | |||
775 | /* If this one also failed, log that and append to our local offline file */ | ||
776 | if (retval) { | ||
777 | #ifdef WANT_DELAYED_MYSQL_INSERT | ||
778 | real_error = 2; | ||
779 | #else | ||
780 | real_error = mysql_errno(mysql_log); | ||
781 | #endif | ||
782 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: second attempt failed, API said: error %d, \"%s\" -- preserving", real_error, MYSQL_ERROR(mysql_log)); | ||
783 | preserve_entry(r, query); | ||
784 | retval = real_error; | ||
785 | } else | ||
786 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: second attempt successful"); | ||
787 | |||
732 | /* Restore SIGPIPE to its original handler function */ | 788 | /* Restore SIGPIPE to its original handler function */ |
733 | signal(SIGPIPE, handler); | 789 | signal(SIGPIPE, handler); |
734 | |||
735 | return retval; | 790 | return retval; |
736 | } | 791 | } |
737 | 792 | ||
@@ -811,35 +866,29 @@ int safe_create_tables(log_sql_state *cls, request_rec *r) | |||
811 | #endif | 866 | #endif |
812 | 867 | ||
813 | /* Assume that things worked unless told otherwise */ | 868 | /* Assume that things worked unless told otherwise */ |
814 | cls->table_made = 1; | ||
815 | retval = 0; | 869 | retval = 0; |
816 | 870 | ||
817 | if ((create_results = safe_mysql_query(r, create_access)) != 0) { | 871 | if ((create_results = safe_mysql_query(r, create_access))) { |
818 | cls->table_made = 0; | ||
819 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create access table"); | 872 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create access table"); |
820 | retval = create_results; | 873 | retval = create_results; |
821 | } | 874 | } |
822 | 875 | ||
823 | if ((create_results = safe_mysql_query(r, create_notes)) != 0) { | 876 | if ((create_results = safe_mysql_query(r, create_notes))) { |
824 | cls->table_made = 0; | ||
825 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create notes table"); | 877 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create notes table"); |
826 | retval = create_results; | 878 | retval = create_results; |
827 | } | 879 | } |
828 | 880 | ||
829 | if ((create_results = safe_mysql_query(r, create_hin)) != 0) { | 881 | if ((create_results = safe_mysql_query(r, create_hin))) { |
830 | cls->table_made = 0; | ||
831 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create header_out table"); | 882 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create header_out table"); |
832 | retval = create_results; | 883 | retval = create_results; |
833 | } | 884 | } |
834 | 885 | ||
835 | if ((create_results = safe_mysql_query(r, create_hout)) != 0) { | 886 | if ((create_results = safe_mysql_query(r, create_hout))) { |
836 | cls->table_made = 0; | ||
837 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create header_in table"); | 887 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create header_in table"); |
838 | retval = create_results; | 888 | retval = create_results; |
839 | } | 889 | } |
840 | 890 | ||
841 | if ((create_results = safe_mysql_query(r, create_cookies)) != 0) { | 891 | if ((create_results = safe_mysql_query(r, create_cookies))) { |
842 | cls->table_made = 0; | ||
843 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create cookies table"); | 892 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create cookies table"); |
844 | retval = create_results; | 893 | retval = create_results; |
845 | } | 894 | } |
@@ -872,8 +921,8 @@ const char *set_log_sql_machine_id(cmd_parms *parms, void *dummy, char *arg) | |||
872 | 921 | ||
873 | const char *set_log_sql_create(cmd_parms *parms, void *dummy, int flag) | 922 | const char *set_log_sql_create(cmd_parms *parms, void *dummy, int flag) |
874 | { | 923 | { |
875 | if (massvirtual != 0) | 924 | if (massvirtual) |
876 | ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLCreateTables when LogSQLMassVirtualHosting is On. Ignoring."); | 925 | ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLCreateTables when LogSQLMassVirtualHosting is On. Ignoring."); |
877 | else | 926 | else |
878 | create_tables = ( flag ? 1 : 0); | 927 | create_tables = ( flag ? 1 : 0); |
879 | return NULL; | 928 | return NULL; |
@@ -994,6 +1043,16 @@ const char *set_log_sql_tcp_port(cmd_parms *parms, void *dummy, char *arg) | |||
994 | return NULL; | 1043 | return NULL; |
995 | } | 1044 | } |
996 | 1045 | ||
1046 | const char *add_log_sql_transfer_accept(cmd_parms *parms, void *dummy, char *arg) | ||
1047 | { | ||
1048 | char **addme; | ||
1049 | log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); | ||
1050 | |||
1051 | addme = push_array(cls->transfer_accept_list); | ||
1052 | *addme = pstrdup(cls->transfer_accept_list->pool, arg); | ||
1053 | return NULL; | ||
1054 | } | ||
1055 | |||
997 | const char *add_log_sql_transfer_ignore(cmd_parms *parms, void *dummy, char *arg) | 1056 | const char *add_log_sql_transfer_ignore(cmd_parms *parms, void *dummy, char *arg) |
998 | { | 1057 | { |
999 | char **addme; | 1058 | char **addme; |
@@ -1072,8 +1131,9 @@ const char *add_log_sql_cookie(cmd_parms *parms, void *dummy, char *arg) | |||
1072 | */ | 1131 | */ |
1073 | static void log_sql_child_init(server_rec *s, pool *p) | 1132 | static void log_sql_child_init(server_rec *s, pool *p) |
1074 | { | 1133 | { |
1075 | int retval; | 1134 | int retval; |
1076 | 1135 | ||
1136 | /* Open a link to the database */ | ||
1077 | retval = open_logdb_link(s); | 1137 | retval = open_logdb_link(s); |
1078 | if (retval == 0) | 1138 | if (retval == 0) |
1079 | ap_log_error(APLOG_MARK,ERRLEVEL,s,"mod_log_sql: child spawned but unable to open database link"); | 1139 | ap_log_error(APLOG_MARK,ERRLEVEL,s,"mod_log_sql: child spawned but unable to open database link"); |
@@ -1140,12 +1200,12 @@ void *log_sql_make_state(pool *p, server_rec *s) | |||
1140 | cls->preserve_file = "/tmp/sql-preserve"; | 1200 | cls->preserve_file = "/tmp/sql-preserve"; |
1141 | 1201 | ||
1142 | cls->transfer_ignore_list = make_array(p, 1, sizeof(char *)); | 1202 | cls->transfer_ignore_list = make_array(p, 1, sizeof(char *)); |
1203 | cls->transfer_accept_list = make_array(p, 1, sizeof(char *)); | ||
1143 | cls->remhost_ignore_list = make_array(p, 1, sizeof(char *)); | 1204 | cls->remhost_ignore_list = make_array(p, 1, sizeof(char *)); |
1144 | cls->notes_list = make_array(p, 1, sizeof(char *)); | 1205 | cls->notes_list = make_array(p, 1, sizeof(char *)); |
1145 | cls->hin_list = make_array(p, 1, sizeof(char *)); | 1206 | cls->hin_list = make_array(p, 1, sizeof(char *)); |
1146 | cls->hout_list = make_array(p, 1, sizeof(char *)); | 1207 | cls->hout_list = make_array(p, 1, sizeof(char *)); |
1147 | cls->cookie_list = make_array(p, 1, sizeof(char *)); | 1208 | cls->cookie_list = make_array(p, 1, sizeof(char *)); |
1148 | cls->table_made = 0; | ||
1149 | cls->cookie_name = NULL; | 1209 | cls->cookie_name = NULL; |
1150 | 1210 | ||
1151 | return (void *) cls; | 1211 | return (void *) cls; |
@@ -1177,6 +1237,9 @@ command_rec log_sql_cmds[] = { | |||
1177 | {"LogSQLMachineID", set_log_sql_machine_id, NULL, RSRC_CONF, TAKE1, | 1237 | {"LogSQLMachineID", set_log_sql_machine_id, NULL, RSRC_CONF, TAKE1, |
1178 | "Machine ID that the module will log, useful in web clusters to differentiate machines"} | 1238 | "Machine ID that the module will log, useful in web clusters to differentiate machines"} |
1179 | , | 1239 | , |
1240 | {"LogSQLRequestAccept", add_log_sql_transfer_accept, NULL, RSRC_CONF, ITERATE, | ||
1241 | "List of URIs to accept for logging. Accesses that don't match will not be logged"} | ||
1242 | , | ||
1180 | {"LogSQLRequestIgnore", add_log_sql_transfer_ignore, NULL, RSRC_CONF, ITERATE, | 1243 | {"LogSQLRequestIgnore", add_log_sql_transfer_ignore, NULL, RSRC_CONF, ITERATE, |
1181 | "List of URIs to ignore. Accesses that match will not be logged to database"} | 1244 | "List of URIs to ignore. Accesses that match will not be logged to database"} |
1182 | , | 1245 | , |
@@ -1240,18 +1303,18 @@ int log_sql_transaction(request_rec *orig) | |||
1240 | /* We handle mass virtual hosting differently. Dynamically determine the name | 1303 | /* We handle mass virtual hosting differently. Dynamically determine the name |
1241 | * of the table from the virtual server's name, and flag it for creation. | 1304 | * of the table from the virtual server's name, and flag it for creation. |
1242 | */ | 1305 | */ |
1243 | if ( massvirtual == 1 ) { | 1306 | if (massvirtual) { |
1244 | char *access_base = "access_"; | 1307 | char *access_base = "access_"; |
1245 | char *notes_base = "notes_"; | 1308 | char *notes_base = "notes_"; |
1246 | char *hout_base = "headout_"; | 1309 | char *hout_base = "headout_"; |
1247 | char *hin_base = "headin_"; | 1310 | char *hin_base = "headin_"; |
1248 | char *cookie_base = "cookies_"; | 1311 | char *cookie_base = "cookies_"; |
1249 | char *a_tablename; | 1312 | char *a_tablename; |
1250 | char *n_tablename; | 1313 | char *n_tablename; |
1251 | char *i_tablename; | 1314 | char *i_tablename; |
1252 | char *o_tablename; | 1315 | char *o_tablename; |
1253 | char *c_tablename; | 1316 | char *c_tablename; |
1254 | int i; | 1317 | unsigned int i; |
1255 | 1318 | ||
1256 | /* Find memory long enough to hold the table name + \0. */ | 1319 | /* Find memory long enough to hold the table name + \0. */ |
1257 | a_tablename = ap_pstrcat(orig->pool, access_base, ap_get_server_name(orig), NULL); | 1320 | a_tablename = ap_pstrcat(orig->pool, access_base, ap_get_server_name(orig), NULL); |
@@ -1308,7 +1371,7 @@ int log_sql_transaction(request_rec *orig) | |||
1308 | const char *unique_id; | 1371 | const char *unique_id; |
1309 | const char *formatted_item; | 1372 | const char *formatted_item; |
1310 | int i, j, length; | 1373 | int i, j, length; |
1311 | int result; | 1374 | int proceed; |
1312 | 1375 | ||
1313 | for (r = orig; r->next; r = r->next) { | 1376 | for (r = orig; r->next; r = r->next) { |
1314 | continue; | 1377 | continue; |
@@ -1317,16 +1380,29 @@ int log_sql_transaction(request_rec *orig) | |||
1317 | /* The following is a stolen upsetting mess of pointers, I'm sorry. | 1380 | /* The following is a stolen upsetting mess of pointers, I'm sorry. |
1318 | * Anyone with the motiviation and/or the time should feel free | 1381 | * Anyone with the motiviation and/or the time should feel free |
1319 | * to make this cleaner. :) */ | 1382 | * to make this cleaner. :) */ |
1320 | ptrptr2 = (char **) (cls->transfer_ignore_list->elts + (cls->transfer_ignore_list->nelts * cls->transfer_ignore_list->elt_size)); | 1383 | ptrptr2 = (char **) (cls->transfer_accept_list->elts + (cls->transfer_accept_list->nelts * cls->transfer_accept_list->elt_size)); |
1384 | |||
1385 | /* Go through each element of the accept list and compare it to the | ||
1386 | * request_uri. If we don't get a match, return without logging */ | ||
1387 | if ((r->uri) && (cls->transfer_accept_list->nelts)) { | ||
1388 | proceed = 0; | ||
1389 | for (ptrptr = (char **) cls->transfer_accept_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->transfer_accept_list->elt_size)) | ||
1390 | if (strstr(r->uri, *ptrptr)) { | ||
1391 | proceed = 1; | ||
1392 | break; | ||
1393 | } | ||
1394 | if (!proceed) | ||
1395 | return OK; | ||
1396 | } | ||
1321 | 1397 | ||
1322 | /* Go through each element of the ignore list and compare it to the | 1398 | /* Go through each element of the ignore list and compare it to the |
1323 | * request_uri. If we get a match, return without logging */ | 1399 | * request_uri. If we get a match, return without logging */ |
1400 | ptrptr2 = (char **) (cls->transfer_ignore_list->elts + (cls->transfer_ignore_list->nelts * cls->transfer_ignore_list->elt_size)); | ||
1324 | if (r->uri) { | 1401 | if (r->uri) { |
1325 | for (ptrptr = (char **) cls->transfer_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->transfer_ignore_list->elt_size)) { | 1402 | for (ptrptr = (char **) cls->transfer_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->transfer_ignore_list->elt_size)) |
1326 | if (strstr(r->uri, *ptrptr)) { | 1403 | if (strstr(r->uri, *ptrptr)) { |
1327 | return OK; | 1404 | return OK; |
1328 | } | 1405 | } |
1329 | } | ||
1330 | } | 1406 | } |
1331 | 1407 | ||
1332 | /* Go through each element of the ignore list and compare it to the | 1408 | /* Go through each element of the ignore list and compare it to the |
@@ -1334,11 +1410,10 @@ int log_sql_transaction(request_rec *orig) | |||
1334 | ptrptr2 = (char **) (cls->remhost_ignore_list->elts + (cls->remhost_ignore_list->nelts * cls->remhost_ignore_list->elt_size)); | 1410 | ptrptr2 = (char **) (cls->remhost_ignore_list->elts + (cls->remhost_ignore_list->nelts * cls->remhost_ignore_list->elt_size)); |
1335 | thehost = get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME); | 1411 | thehost = get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME); |
1336 | if (thehost) { | 1412 | if (thehost) { |
1337 | for (ptrptr = (char **) cls->remhost_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->remhost_ignore_list->elt_size)) { | 1413 | for (ptrptr = (char **) cls->remhost_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->remhost_ignore_list->elt_size)) |
1338 | if (strstr(thehost, *ptrptr)) { | 1414 | if (strstr(thehost, *ptrptr)) { |
1339 | return OK; | 1415 | return OK; |
1340 | } | 1416 | } |
1341 | } | ||
1342 | } | 1417 | } |
1343 | 1418 | ||
1344 | length = strlen(cls->transfer_log_format); | 1419 | length = strlen(cls->transfer_log_format); |
@@ -1530,7 +1605,7 @@ int log_sql_transaction(request_rec *orig) | |||
1530 | if (mysql_log == NULL) { | 1605 | if (mysql_log == NULL) { |
1531 | /* Unable to re-establish a DB link, so assume that it's really | 1606 | /* Unable to re-establish a DB link, so assume that it's really |
1532 | * gone and send the entry to the preserve file instead. | 1607 | * gone and send the entry to the preserve file instead. |
1533 | * This short-circuits safe_mysql_query during a db outage and therefore | 1608 | * This short-circuits safe_mysql_query() during a db outage and therefore |
1534 | * we don't keep logging the db error over and over. | 1609 | * we don't keep logging the db error over and over. |
1535 | */ | 1610 | */ |
1536 | preserve_entry(orig, access_query); | 1611 | preserve_entry(orig, access_query); |
@@ -1554,52 +1629,20 @@ int log_sql_transaction(request_rec *orig) | |||
1554 | /* ---> So as of here we have a non-null value of mysql_log. <--- */ | 1629 | /* ---> So as of here we have a non-null value of mysql_log. <--- */ |
1555 | /* ---> i.e. we have a good MySQL connection. <--- */ | 1630 | /* ---> i.e. we have a good MySQL connection. <--- */ |
1556 | 1631 | ||
1557 | |||
1558 | /* Make the tables if we're supposed to. */ | ||
1559 | if ((cls->table_made != 1) && (create_tables != 0)) { | ||
1560 | result = safe_create_tables(cls, orig); | ||
1561 | if (result != 0) | ||
1562 | ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: child attempted but failed to create one or more tables for %s", ap_get_server_name(orig)); | ||
1563 | else | ||
1564 | ap_log_error(APLOG_MARK,NOTICELEVEL,orig->server,"mod_log_sql: no problems creating tables for %s", ap_get_server_name(orig)); | ||
1565 | } | ||
1566 | |||
1567 | /* Make the access-table insert */ | 1632 | /* Make the access-table insert */ |
1568 | result = safe_mysql_query(orig, access_query); | 1633 | safe_mysql_query(orig, access_query); |
1569 | |||
1570 | /* It failed, but NOT because table didn't exist */ | ||
1571 | if ( (result != 0) && (result != 1146) ) | ||
1572 | preserve_entry(orig,access_query); | ||
1573 | |||
1574 | /* It failed because table didn't exist */ | ||
1575 | if (result == 1146) { | ||
1576 | ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: hmm, table didn't yet exist; creating"); | ||
1577 | result = safe_create_tables(cls, orig); | ||
1578 | if (result != 0) { | ||
1579 | ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: child attempted but failed to create one or more tables for %s, preserving query", ap_get_server_name(orig)); | ||
1580 | preserve_entry(orig,access_query); | ||
1581 | } else { | ||
1582 | ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: table successfully created, query will now be retried"); | ||
1583 | result = safe_mysql_query(orig, access_query); | ||
1584 | if (result != 0 ) { | ||
1585 | ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: giving up, preserving query"); | ||
1586 | preserve_entry(orig,access_query); | ||
1587 | return OK; | ||
1588 | } | ||
1589 | } | ||
1590 | } | ||
1591 | 1634 | ||
1592 | /* Log the optional notes, headers, etc. */ | 1635 | /* Log the optional notes, headers, etc. */ |
1593 | if ( note_query != NULL ) | 1636 | if (note_query) |
1594 | safe_mysql_query(orig, note_query); | 1637 | safe_mysql_query(orig, note_query); |
1595 | 1638 | ||
1596 | if ( hout_query != NULL ) | 1639 | if (hout_query) |
1597 | safe_mysql_query(orig, hout_query); | 1640 | safe_mysql_query(orig, hout_query); |
1598 | 1641 | ||
1599 | if ( hin_query != NULL ) | 1642 | if (hin_query) |
1600 | safe_mysql_query(orig, hin_query); | 1643 | safe_mysql_query(orig, hin_query); |
1601 | 1644 | ||
1602 | if ( cookie_query != NULL ) | 1645 | if (cookie_query) |
1603 | safe_mysql_query(orig, cookie_query); | 1646 | safe_mysql_query(orig, cookie_query); |
1604 | 1647 | ||
1605 | return OK; | 1648 | return OK; |
@@ -1634,3 +1677,46 @@ module sql_log_module = { | |||
1634 | #endif | 1677 | #endif |
1635 | 1678 | ||
1636 | }; | 1679 | }; |
1680 | |||
1681 | |||
1682 | |||
1683 | /* Make the tables if we're supposed to. */ | ||
1684 | /* | ||
1685 | if ((cls->table_made != 1) && (create_tables != 0)) { | ||
1686 | result = safe_create_tables(cls, orig); | ||
1687 | if (result != 0) | ||
1688 | ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: child attempted but failed to create one or more tables for %s", ap_get_server_name(orig)); | ||
1689 | else | ||
1690 | ap_log_error(APLOG_MARK,NOTICELEVEL,orig->server,"mod_log_sql: no problems creating tables for %s", ap_get_server_name(orig)); | ||
1691 | } | ||
1692 | */ | ||
1693 | |||
1694 | /* It failed, but NOT because table didn't exist */ | ||
1695 | /* | ||
1696 | if ( (result) && (result != ER_NO_SUCH_TABLE) ) | ||
1697 | preserve_entry(orig,access_query); | ||
1698 | */ | ||
1699 | |||
1700 | /* It failed because table didn't exist */ | ||
1701 | /* | ||
1702 | if (result == ER_NO_SUCH_TABLE) | ||
1703 | if (create_tables) { | ||
1704 | ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: access table doesn't exist...creating now"); | ||
1705 | if ((result = safe_create_tables(cls, orig))) { | ||
1706 | ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: child attempted but failed to create one or more tables for %s, preserving query", ap_get_server_name(orig)); | ||
1707 | preserve_entry(orig,access_query); | ||
1708 | } else { | ||
1709 | ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: table(s) successfully created - retrying insert"); | ||
1710 | if ((result = safe_mysql_query(orig, access_query))) { | ||
1711 | ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: giving up, preserving query"); | ||
1712 | preserve_entry(orig,access_query); | ||
1713 | return OK; | ||
1714 | } else | ||
1715 | ap_log_error(APLOG_MARK_ERRLEVEL,orig->server,"mod_log_sql: insert successful after table creation"); | ||
1716 | } | ||
1717 | } else { | ||
1718 | ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: access table doesn't exist...not allowed to create, giving up, preserving query"); | ||
1719 | preserve_entry(orig,access_query); | ||
1720 | return OK; | ||
1721 | } | ||
1722 | */ | ||