diff options
Diffstat (limited to 'mod_log_sql.c')
-rw-r--r-- | mod_log_sql.c | 208 |
1 files changed, 163 insertions, 45 deletions
diff --git a/mod_log_sql.c b/mod_log_sql.c index f02243e..d2c4d1d 100644 --- a/mod_log_sql.c +++ b/mod_log_sql.c | |||
@@ -16,7 +16,17 @@ | |||
16 | /* ---------* | 16 | /* ---------* |
17 | * INCLUDES * | 17 | * INCLUDES * |
18 | * ---------*/ | 18 | * ---------*/ |
19 | #include <time.h> | 19 | #include "config.h" |
20 | #if TIME_WITH_SYS_TIME | ||
21 | #include <sys/time.h> | ||
22 | #include <time.h> | ||
23 | #else | ||
24 | #if TM_IN_SYS_TIME | ||
25 | #include <sys/time.h> | ||
26 | #else | ||
27 | #include <time.h> | ||
28 | #endif | ||
29 | #endif | ||
20 | #include <stdio.h> | 30 | #include <stdio.h> |
21 | #include <stdlib.h> | 31 | #include <stdlib.h> |
22 | #include <string.h> | 32 | #include <string.h> |
@@ -52,6 +62,7 @@ MYSQL logsql_server, *logsql_server_p = NULL; | |||
52 | int logsql_massvirtual = 0; | 62 | int logsql_massvirtual = 0; |
53 | int logsql_createtables = 0; | 63 | int logsql_createtables = 0; |
54 | int logsql_forcepreserve = 0; | 64 | int logsql_forcepreserve = 0; |
65 | char *logsql_tabletype = NULL; | ||
55 | char *logsql_dbname = NULL; | 66 | char *logsql_dbname = NULL; |
56 | char *logsql_dbhost = NULL; | 67 | char *logsql_dbhost = NULL; |
57 | char *logsql_dbuser = NULL; | 68 | char *logsql_dbuser = NULL; |
@@ -289,7 +300,7 @@ static const char *extract_request_duration(request_rec *r, char *a) | |||
289 | { | 300 | { |
290 | char duration[22]; /* Long enough for 2^64 */ | 301 | char duration[22]; /* Long enough for 2^64 */ |
291 | 302 | ||
292 | ap_snprintf(duration, sizeof(duration), "%ld", time(NULL) - r->request_time); | 303 | ap_snprintf(duration, sizeof(duration), "%ld", (long) time(NULL) - r->request_time); |
293 | return pstrdup(r->pool, duration); | 304 | return pstrdup(r->pool, duration); |
294 | } | 305 | } |
295 | 306 | ||
@@ -494,7 +505,7 @@ static const char *extract_request_timestamp(request_rec *r, char *a) | |||
494 | { | 505 | { |
495 | char tstr[32]; | 506 | char tstr[32]; |
496 | 507 | ||
497 | ap_snprintf(tstr, 32, "%ld", time(NULL)); | 508 | ap_snprintf(tstr, 32, "%ld", (long) time(NULL)); |
498 | return pstrdup(r->pool, tstr); | 509 | return pstrdup(r->pool, tstr); |
499 | } | 510 | } |
500 | 511 | ||
@@ -815,6 +826,8 @@ int safe_create_tables(logsql_state *cls, request_rec *r) | |||
815 | char *create_hin = NULL; | 826 | char *create_hin = NULL; |
816 | char *create_cookies = NULL; | 827 | char *create_cookies = NULL; |
817 | 828 | ||
829 | char *type_suffix = NULL; | ||
830 | |||
818 | char *createprefix = "create table if not exists `"; | 831 | char *createprefix = "create table if not exists `"; |
819 | char *access_suffix = | 832 | char *access_suffix = |
820 | "` (id char(19),\ | 833 | "` (id char(19),\ |
@@ -858,12 +871,15 @@ int safe_create_tables(logsql_state *cls, request_rec *r) | |||
858 | item varchar(80),\ | 871 | item varchar(80),\ |
859 | val varchar(80))"; | 872 | val varchar(80))"; |
860 | 873 | ||
874 | if (logsql_tabletype) | ||
875 | type_suffix = ap_pstrcat( r->pool, " TYPE=", logsql_tabletype, NULL ); | ||
876 | |||
861 | /* Find memory long enough to hold the whole CREATE string + \0 */ | 877 | /* Find memory long enough to hold the whole CREATE string + \0 */ |
862 | create_access = ap_pstrcat(r->pool, createprefix, cls->transfer_table_name, access_suffix, NULL); | 878 | create_access = ap_pstrcat(r->pool, createprefix, cls->transfer_table_name, access_suffix, type_suffix, NULL); |
863 | create_notes = ap_pstrcat(r->pool, createprefix, cls->notes_table_name, notes_suffix, NULL); | 879 | create_notes = ap_pstrcat(r->pool, createprefix, cls->notes_table_name, notes_suffix, type_suffix, NULL); |
864 | create_hout = ap_pstrcat(r->pool, createprefix, cls->hout_table_name, headers_suffix, NULL); | 880 | create_hout = ap_pstrcat(r->pool, createprefix, cls->hout_table_name, headers_suffix, type_suffix, NULL); |
865 | create_hin = ap_pstrcat(r->pool, createprefix, cls->hin_table_name, headers_suffix, NULL); | 881 | create_hin = ap_pstrcat(r->pool, createprefix, cls->hin_table_name, headers_suffix, type_suffix, NULL); |
866 | create_cookies= ap_pstrcat(r->pool, createprefix, cls->cookie_table_name, cookies_suffix, NULL); | 882 | create_cookies= ap_pstrcat(r->pool, createprefix, cls->cookie_table_name, cookies_suffix, type_suffix, NULL); |
867 | 883 | ||
868 | #ifdef DEBUG | 884 | #ifdef DEBUG |
869 | ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_access); | 885 | ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_access); |
@@ -887,7 +903,8 @@ int safe_create_tables(logsql_state *cls, request_rec *r) | |||
887 | } | 903 | } |
888 | 904 | ||
889 | if ((create_results = safe_sql_query(r, create_hin))) { | 905 | if ((create_results = safe_sql_query(r, create_hin))) { |
890 | ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create header_out table"); | 906 | ap_log_error(APLOG_MARK, |
907 | ERRLEVEL,r->server,"mod_log_sql: failed to create header_out table"); | ||
891 | retval = create_results; | 908 | retval = create_results; |
892 | } | 909 | } |
893 | 910 | ||
@@ -936,6 +953,17 @@ const char *set_log_sql_create(cmd_parms *parms, void *dummy, int flag) | |||
936 | return NULL; | 953 | return NULL; |
937 | } | 954 | } |
938 | 955 | ||
956 | const char *set_log_sql_tabletype(cmd_parms *parms, void *dummy, char *arg) | ||
957 | { | ||
958 | /* These are the legal table types according to the MySQL docs: | ||
959 | * TYPE = {BDB | HEAP | ISAM | InnoDB | MERGE | MRG_MYISAM | MYISAM } | ||
960 | * However, for now the module does no checking. If MySQL is passed | ||
961 | * a table type it does not understand, it defaults to MyISAM. */ | ||
962 | |||
963 | logsql_tabletype = arg; | ||
964 | return NULL; | ||
965 | } | ||
966 | |||
939 | const char *set_log_sql_db(cmd_parms *parms, void *dummy, char *arg) | 967 | const char *set_log_sql_db(cmd_parms *parms, void *dummy, char *arg) |
940 | { | 968 | { |
941 | logsql_dbname = arg; | 969 | logsql_dbname = arg; |
@@ -1200,12 +1228,12 @@ void *log_sql_make_state(pool *p, server_rec *s) | |||
1200 | 1228 | ||
1201 | /* These defaults are overridable in the httpd.conf file. */ | 1229 | /* These defaults are overridable in the httpd.conf file. */ |
1202 | cls->transfer_table_name = NULL; /* No default b/c we want its absence to disable logging */ | 1230 | cls->transfer_table_name = NULL; /* No default b/c we want its absence to disable logging */ |
1203 | cls->transfer_log_format = "AbHhmRSsTUuv"; | 1231 | cls->transfer_log_format = NULL; |
1204 | cls->notes_table_name = "notes"; | 1232 | cls->notes_table_name = NULL; |
1205 | cls->hin_table_name = "headers_in"; | 1233 | cls->hin_table_name = NULL; |
1206 | cls->hout_table_name = "headers_out"; | 1234 | cls->hout_table_name = NULL; |
1207 | cls->cookie_table_name = "cookies"; | 1235 | cls->cookie_table_name = NULL; |
1208 | cls->preserve_file = "/tmp/sql-preserve"; | 1236 | cls->preserve_file = NULL; |
1209 | 1237 | ||
1210 | cls->transfer_ignore_list = make_array(p, 1, sizeof(char *)); | 1238 | cls->transfer_ignore_list = make_array(p, 1, sizeof(char *)); |
1211 | cls->transfer_accept_list = make_array(p, 1, sizeof(char *)); | 1239 | cls->transfer_accept_list = make_array(p, 1, sizeof(char *)); |
@@ -1219,6 +1247,106 @@ void *log_sql_make_state(pool *p, server_rec *s) | |||
1219 | return (void *) cls; | 1247 | return (void *) cls; |
1220 | } | 1248 | } |
1221 | 1249 | ||
1250 | static void *log_sql_merge_state(pool *p, void *basev, void *addv) | ||
1251 | { | ||
1252 | /* Make room for the merged state */ | ||
1253 | logsql_state *merged = | ||
1254 | (logsql_state*)ap_pcalloc(p, sizeof(logsql_state)); | ||
1255 | |||
1256 | /* Fetch the two states to merge */ | ||
1257 | logsql_state *parent = (logsql_state *) basev; | ||
1258 | logsql_state *child = (logsql_state *) addv; | ||
1259 | |||
1260 | /* Child can override these, otherwise they default to parent's choice. | ||
1261 | * If the parent didn't set them, create reasonable defaults for the | ||
1262 | * ones that should have such default settings. Leave the others null. */ | ||
1263 | |||
1264 | merged->transfer_table_name = child->transfer_table_name ? | ||
1265 | child->transfer_table_name : parent->transfer_table_name; | ||
1266 | /* No default for transfer_table_name because we want its absence | ||
1267 | * to disable logging. */ | ||
1268 | |||
1269 | |||
1270 | merged->transfer_log_format = child->transfer_log_format ? | ||
1271 | child->transfer_log_format : parent->transfer_log_format; | ||
1272 | if (!merged->transfer_log_format) | ||
1273 | merged->transfer_log_format = "AbHhmRSsTUuv"; | ||
1274 | |||
1275 | |||
1276 | merged->preserve_file = child->preserve_file ? | ||
1277 | child->preserve_file : parent->preserve_file; | ||
1278 | if (!merged->preserve_file) | ||
1279 | merged->preserve_file = "/tmp/sql-preserve"; | ||
1280 | |||
1281 | |||
1282 | merged->notes_table_name = child->notes_table_name ? | ||
1283 | child->notes_table_name : parent->notes_table_name; | ||
1284 | if (!merged->notes_table_name) | ||
1285 | merged->notes_table_name = "notes"; | ||
1286 | |||
1287 | |||
1288 | merged->hin_table_name = child->hin_table_name ? | ||
1289 | child->hin_table_name : parent->hin_table_name; | ||
1290 | if (!merged->hin_table_name) | ||
1291 | merged->hin_table_name = "headers_in"; | ||
1292 | |||
1293 | |||
1294 | merged->hout_table_name = child->hout_table_name ? | ||
1295 | child->hout_table_name : parent->hout_table_name; | ||
1296 | if (!merged->hout_table_name) | ||
1297 | merged->hout_table_name = "headers_out"; | ||
1298 | |||
1299 | |||
1300 | merged->cookie_table_name = child->cookie_table_name ? | ||
1301 | child->cookie_table_name : parent->cookie_table_name; | ||
1302 | if (!merged->cookie_table_name) | ||
1303 | merged->cookie_table_name = "cookies"; | ||
1304 | |||
1305 | |||
1306 | merged->transfer_ignore_list = child->transfer_ignore_list ? | ||
1307 | child->transfer_ignore_list : parent->transfer_ignore_list; | ||
1308 | |||
1309 | merged->transfer_accept_list = child->transfer_accept_list ? | ||
1310 | child->transfer_accept_list : parent->transfer_accept_list; | ||
1311 | |||
1312 | merged->remhost_ignore_list = child->remhost_ignore_list ? | ||
1313 | child->remhost_ignore_list : parent->remhost_ignore_list; | ||
1314 | |||
1315 | merged->notes_list = child->notes_list ? | ||
1316 | child->notes_list : parent->notes_list ; | ||
1317 | |||
1318 | merged->hin_list = child->hin_list ? | ||
1319 | child->hin_list : parent->hin_list ; | ||
1320 | |||
1321 | merged->hout_list = child->hout_list ? | ||
1322 | child->hout_list : parent->hout_list ; | ||
1323 | |||
1324 | merged->cookie_list = child->cookie_list ? | ||
1325 | child->cookie_list : parent->cookie_list ; | ||
1326 | |||
1327 | merged->cookie_name = child->cookie_name ? | ||
1328 | child->cookie_name : parent->cookie_name ; | ||
1329 | |||
1330 | return (void*) merged; | ||
1331 | |||
1332 | /* Here is how mod_log_config does it: */ | ||
1333 | |||
1334 | /* | ||
1335 | multi_log_state *base = (multi_log_state *) basev; | ||
1336 | multi_log_state *add = (multi_log_state *) addv; | ||
1337 | |||
1338 | add->server_config_logs = base->config_logs; | ||
1339 | if (!add->default_format) { | ||
1340 | add->default_format_string = base->default_format_string; | ||
1341 | add->default_format = base->default_format; | ||
1342 | } | ||
1343 | add->formats = ap_overlay_tables(p, base->formats, add->formats); | ||
1344 | |||
1345 | return add; | ||
1346 | */ | ||
1347 | } | ||
1348 | |||
1349 | |||
1222 | 1350 | ||
1223 | /* Setup of the available httpd.conf configuration commands. | 1351 | /* Setup of the available httpd.conf configuration commands. |
1224 | * Structure: command, function called, NULL, where available, how many arguments, verbose description | 1352 | * Structure: command, function called, NULL, where available, how many arguments, verbose description |
@@ -1245,7 +1373,7 @@ command_rec log_sql_cmds[] = { | |||
1245 | {"LogSQLMachineID", set_log_sql_machine_id, NULL, RSRC_CONF, TAKE1, | 1373 | {"LogSQLMachineID", set_log_sql_machine_id, NULL, RSRC_CONF, TAKE1, |
1246 | "Machine ID that the module will log, useful in web clusters to differentiate machines"} | 1374 | "Machine ID that the module will log, useful in web clusters to differentiate machines"} |
1247 | , | 1375 | , |
1248 | {"LogSQLRequestAccept", add_log_sql_transfer_accept, NULL, RSRC_CONF, ITERATE, | 1376 | {"LogSQLRequestAccept", add_log_sql_transfer_accept, NULL, RSRC_CONF, ITERATE, |
1249 | "List of URIs to accept for logging. Accesses that don't match will not be logged"} | 1377 | "List of URIs to accept for logging. Accesses that don't match will not be logged"} |
1250 | , | 1378 | , |
1251 | {"LogSQLRequestIgnore", add_log_sql_transfer_ignore, NULL, RSRC_CONF, ITERATE, | 1379 | {"LogSQLRequestIgnore", add_log_sql_transfer_ignore, NULL, RSRC_CONF, ITERATE, |
@@ -1277,6 +1405,9 @@ command_rec log_sql_cmds[] = { | |||
1277 | , | 1405 | , |
1278 | {"LogSQLSocketFile", set_log_sql_socket_file, NULL, RSRC_CONF, TAKE1, | 1406 | {"LogSQLSocketFile", set_log_sql_socket_file, NULL, RSRC_CONF, TAKE1, |
1279 | "Name of the file to employ for socket connections to database"} | 1407 | "Name of the file to employ for socket connections to database"} |
1408 | , | ||
1409 | {"LogSQLTableType", set_log_sql_tabletype, NULL, RSRC_CONF, TAKE1, | ||
1410 | "What kind of table to create (MyISAM, InnoDB...) when creating tables"} | ||
1280 | , | 1411 | , |
1281 | {"LogSQLTCPPort", set_log_sql_tcp_port, NULL, RSRC_CONF, TAKE1, | 1412 | {"LogSQLTCPPort", set_log_sql_tcp_port, NULL, RSRC_CONF, TAKE1, |
1282 | "Port number to use for TCP connections to database, defaults to 3306 if not set"} | 1413 | "Port number to use for TCP connections to database, defaults to 3306 if not set"} |
@@ -1322,37 +1453,24 @@ int log_sql_transaction(request_rec *orig) | |||
1322 | char *i_tablename; | 1453 | char *i_tablename; |
1323 | char *o_tablename; | 1454 | char *o_tablename; |
1324 | char *c_tablename; | 1455 | char *c_tablename; |
1325 | unsigned int i; | ||
1326 | 1456 | ||
1327 | /* Find memory long enough to hold the table name + \0. */ | 1457 | /* Determine the hostname and convert it to all-lower-case. |
1328 | a_tablename = ap_pstrcat(orig->pool, access_base, ap_get_server_name(orig), NULL); | 1458 | * Also change any dots to underscores. |
1329 | n_tablename = ap_pstrcat(orig->pool, notes_base, ap_get_server_name(orig), NULL); | 1459 | */ |
1330 | i_tablename = ap_pstrcat(orig->pool, hin_base, ap_get_server_name(orig), NULL); | 1460 | char *p; |
1331 | o_tablename = ap_pstrcat(orig->pool, hout_base, ap_get_server_name(orig), NULL); | 1461 | char *servname = (char *)ap_get_server_name(orig); |
1332 | c_tablename = ap_pstrcat(orig->pool, cookie_base, ap_get_server_name(orig), NULL); | 1462 | for (p = servname; *p != '\0'; p++) { |
1333 | 1463 | *p = tolower((unsigned char) *p); | |
1334 | /* Transform any dots to underscores */ | 1464 | if (*p == '.') *p = '_'; |
1335 | for (i = 0; i < strlen(a_tablename); i++) { | ||
1336 | if (a_tablename[i] == '.') | ||
1337 | a_tablename[i] = '_'; | ||
1338 | } | ||
1339 | for (i = 0; i < strlen(n_tablename); i++) { | ||
1340 | if (n_tablename[i] == '.') | ||
1341 | n_tablename[i] = '_'; | ||
1342 | } | ||
1343 | for (i = 0; i < strlen(i_tablename); i++) { | ||
1344 | if (i_tablename[i] == '.') | ||
1345 | i_tablename[i] = '_'; | ||
1346 | } | ||
1347 | for (i = 0; i < strlen(o_tablename); i++) { | ||
1348 | if (o_tablename[i] == '.') | ||
1349 | o_tablename[i] = '_'; | ||
1350 | } | ||
1351 | for (i = 0; i < strlen(c_tablename); i++) { | ||
1352 | if (c_tablename[i] == '.') | ||
1353 | c_tablename[i] = '_'; | ||
1354 | } | 1465 | } |
1355 | 1466 | ||
1467 | /* Find memory long enough to hold the table name + \0. */ | ||
1468 | a_tablename = ap_pstrcat(orig->pool, access_base, servname, NULL); | ||
1469 | n_tablename = ap_pstrcat(orig->pool, notes_base, servname, NULL); | ||
1470 | i_tablename = ap_pstrcat(orig->pool, hin_base, servname, NULL); | ||
1471 | o_tablename = ap_pstrcat(orig->pool, hout_base, servname, NULL); | ||
1472 | c_tablename = ap_pstrcat(orig->pool, cookie_base, servname, NULL); | ||
1473 | |||
1356 | /* Tell this virtual server its transfer table name, and | 1474 | /* Tell this virtual server its transfer table name, and |
1357 | * turn on create_tables, which is implied by massvirtual. | 1475 | * turn on create_tables, which is implied by massvirtual. |
1358 | */ | 1476 | */ |
@@ -1667,7 +1785,7 @@ module sql_log_module = { | |||
1667 | NULL, /* create per-dir config */ | 1785 | NULL, /* create per-dir config */ |
1668 | NULL, /* merge per-dir config */ | 1786 | NULL, /* merge per-dir config */ |
1669 | log_sql_make_state, /* create server config */ | 1787 | log_sql_make_state, /* create server config */ |
1670 | NULL, /* merge server config */ | 1788 | log_sql_merge_state, /* merge server config */ |
1671 | log_sql_cmds, /* config directive table */ | 1789 | log_sql_cmds, /* config directive table */ |
1672 | NULL, /* [9] content handlers */ | 1790 | NULL, /* [9] content handlers */ |
1673 | NULL, /* [2] URI-to-filename translation */ | 1791 | NULL, /* [2] URI-to-filename translation */ |