summaryrefslogtreecommitdiffstats
path: root/mod_log_sql.c
diff options
context:
space:
mode:
Diffstat (limited to 'mod_log_sql.c')
-rw-r--r--mod_log_sql.c208
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;
52int logsql_massvirtual = 0; 62int logsql_massvirtual = 0;
53int logsql_createtables = 0; 63int logsql_createtables = 0;
54int logsql_forcepreserve = 0; 64int logsql_forcepreserve = 0;
65char *logsql_tabletype = NULL;
55char *logsql_dbname = NULL; 66char *logsql_dbname = NULL;
56char *logsql_dbhost = NULL; 67char *logsql_dbhost = NULL;
57char *logsql_dbuser = NULL; 68char *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
956const 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
939const char *set_log_sql_db(cmd_parms *parms, void *dummy, char *arg) 967const 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
1250static 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 */