From da2aa667865606ade6a47d060ab12c851231933c Mon Sep 17 00:00:00 2001 From: Christopher Powell Date: Thu, 14 Nov 2002 03:51:37 +0000 Subject: Monster changes en route to 1.17. Esp. with new documentation. --- (limited to 'mod_log_sql.c') diff --git a/mod_log_sql.c b/mod_log_sql.c index a0cceb2..ba60089 100644 --- a/mod_log_sql.c +++ b/mod_log_sql.c @@ -1,21 +1,19 @@ -/* $Id: mod_log_sql.c,v 1.16 2002/09/04 18:46:00 helios Exp $ */ +/* $Id: mod_log_sql.c,v 1.17 2002/11/14 03:51:35 helios Exp $ */ /* --------* * DEFINES * * --------*/ -/* The enduser probably won't modify these */ +/* The enduser may wish to modify this */ +#undef DEBUG + +/* The enduser won't modify these */ #define MYSQL_ERROR(mysql) ((mysql)?(mysql_error(mysql)):"MySQL server has gone away") #define ERRLEVEL APLOG_ERR|APLOG_NOERRNO #define WARNINGLEVEL APLOG_WARNING|APLOG_NOERRNO #define NOTICELEVEL APLOG_NOTICE|APLOG_NOERRNO #define DEBUGLEVEL APLOG_DEBUG|APLOG_NOERRNO -/* The enduser may wish to modify these */ -#define WANT_SSL_LOGGING -#undef DEBUG - - /* ---------* * INCLUDES * * ---------*/ @@ -41,7 +39,7 @@ * -------------*/ /* Declare ourselves so the configuration routines can find and know us. */ -module mysql_log_module; +module sql_log_module; /* The contents of these are known 'Apache wide' and are not variable * on a per-virtual-server basis. Every virtual server 'knows' the @@ -51,18 +49,21 @@ MYSQL sql_server, *mysql_log = NULL; int massvirtual = 0; int create_tables = 0; +int force_preserve = 0; char *db_name = NULL; char *db_host = NULL; char *db_user = NULL; char *db_pwd = NULL; +char *mach_id = NULL; char *socket_file = "/tmp/mysql.sock"; +unsigned int tcp_port = 3306; typedef const char *(*item_key_func) (request_rec *, char *); -/* But the contents of this structure will vary by virtual server. +/* But the contents of this structure will vary by virtual server. * This permits each virtual server to vary its configuration slightly - * for per-server customization. - * + * for per-server customization. + * * Each child process has its own segregated copy of this structure. */ typedef struct { @@ -73,9 +74,11 @@ typedef struct { array_header *notes_list; array_header *hout_list; array_header *hin_list; + array_header *cookie_list; char *notes_table_name; char *hout_table_name; char *hin_table_name; + char *cookie_table_name; char *transfer_table_name; char *transfer_log_format; char *preserve_file; @@ -133,7 +136,7 @@ static const char *extract_remote_user(request_rec *r, char *a) static const char *extract_ssl_keysize(request_rec *r, char *a) { char *result = NULL; - + if (ap_ctx_get(r->connection->client->ctx, "ssl") != NULL) { result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER_USEKEYSIZE"); #ifdef DEBUG @@ -150,7 +153,7 @@ static const char *extract_ssl_keysize(request_rec *r, char *a) static const char *extract_ssl_maxkeysize(request_rec *r, char *a) { char *result = NULL; - + if (ap_ctx_get(r->connection->client->ctx, "ssl") != NULL) { result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER_ALGKEYSIZE"); #ifdef DEBUG @@ -167,7 +170,7 @@ static const char *extract_ssl_maxkeysize(request_rec *r, char *a) static const char *extract_ssl_cipher(request_rec *r, char *a) { char *result = NULL; - + if (ap_ctx_get(r->connection->client->ctx, "ssl") != NULL) { result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER"); #ifdef DEBUG @@ -225,6 +228,7 @@ static const char *extract_bytes_sent(request_rec *r, char *a) } } +/* static const char *extract_header_in(request_rec *r, char *a) { return table_get(r->headers_in, a); @@ -241,6 +245,7 @@ static const char *extract_header_out(request_rec *r, char *a) } return table_get(r->err_headers_out, a); } +*/ static const char *extract_request_time(request_rec *r, char *a) { @@ -278,6 +283,14 @@ static const char *extract_virtual_host(request_rec *r, char *a) return ap_get_server_name(r); } +static const char *extract_machine_id(request_rec *r, char *a) +{ + if (!mach_id) + return "-"; + else + return mach_id; +} + static const char *extract_server_port(request_rec *r, char *a) { char portnum[22]; @@ -309,7 +322,7 @@ static const char *extract_referer(request_rec *r, char *a) static const char *extract_agent(request_rec *r, char *a) { const char *tempag; - + tempag = table_get(r->headers_in, "User-Agent"); if (!tempag) { @@ -325,14 +338,14 @@ static const char *extract_cookie(request_rec *r, char *a) char *cookieend; char *isvalid; char *cookiebuf; - - log_sql_state *cls = get_module_config(r->server->module_config, &mysql_log_module); - + + log_sql_state *cls = get_module_config(r->server->module_config, &sql_log_module); + if (cls->cookie_name != NULL) { #ifdef DEBUG ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"watching for cookie '%s'", cls->cookie_name); #endif - + /* Fetch out the cookie header */ cookiestr = (char *)table_get(r->headers_in, "cookie2"); if (cookiestr != NULL) { @@ -346,7 +359,7 @@ static const char *extract_cookie(request_rec *r, char *a) isvalid += strlen(cls->cookie_name) + 1; /* Duplicate it into the pool */ cookiebuf = ap_pstrdup(r->pool, isvalid); - /* Segregate just this cookie out of the string + /* Segregate just this cookie out of the string * with a terminating nul at the first semicolon */ cookieend = strchr(cookiebuf, ';'); if (cookieend != NULL) @@ -354,7 +367,7 @@ static const char *extract_cookie(request_rec *r, char *a) return cookiebuf; } } - + cookiestr = (char *)table_get(r->headers_in, "cookie"); if (cookiestr != NULL) { #ifdef DEBUG @@ -370,7 +383,7 @@ static const char *extract_cookie(request_rec *r, char *a) return cookiebuf; } } - + cookiestr = table_get(r->headers_out, "set-cookie"); if (cookiestr != NULL) { #ifdef DEBUG @@ -387,10 +400,81 @@ static const char *extract_cookie(request_rec *r, char *a) } } } - - return "-"; + + return "-"; } +static const char *extract_specific_cookie(request_rec *r, char *a) +{ + const char *cookiestr; + char *cookieend; + char *isvalid; + char *cookiebuf; + + if (a != NULL) { + #ifdef DEBUG + ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"watching for cookie '%s'", a); + #endif + + /* Fetch out the cookie header */ + cookiestr = (char *)table_get(r->headers_in, "cookie2"); + if (cookiestr != NULL) { + #ifdef DEBUG + ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"Cookie2: [%s]", cookiestr); + #endif + /* Does the cookie string contain one with our name? */ + isvalid = strstr(cookiestr, a); + if (isvalid != NULL) { + /* Move past the cookie name and equal sign */ + isvalid += strlen(a) + 1; + /* Duplicate it into the pool */ + cookiebuf = ap_pstrdup(r->pool, isvalid); + /* Segregate just this cookie out of the string + * with a terminating nul at the first semicolon */ + cookieend = strchr(cookiebuf, ';'); + if (cookieend != NULL) + *cookieend = '\0'; + return cookiebuf; + } + } + + cookiestr = (char *)table_get(r->headers_in, "cookie"); + if (cookiestr != NULL) { + #ifdef DEBUG + ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"Cookie: [%s]", cookiestr); + #endif + isvalid = strstr(cookiestr, a); + if (isvalid != NULL) { + isvalid += strlen(a) + 1; + cookiebuf = ap_pstrdup(r->pool, isvalid); + cookieend = strchr(cookiebuf, ';'); + if (cookieend != NULL) + *cookieend = '\0'; + return cookiebuf; + } + } + + cookiestr = table_get(r->headers_out, "set-cookie"); + if (cookiestr != NULL) { + #ifdef DEBUG + ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"Set-Cookie: [%s]", cookiestr); + #endif + isvalid = strstr(cookiestr, a); + if (isvalid != NULL) { + isvalid += strlen(a) + 1; + cookiebuf = ap_pstrdup(r->pool, isvalid); + cookieend = strchr(cookiebuf, ';'); + if (cookieend != NULL) + *cookieend = '\0'; + return cookiebuf; + } + } + } + + return "-"; +} + + static const char *extract_request_timestamp(request_rec *r, char *a) { char tstr[32]; @@ -399,13 +483,13 @@ static const char *extract_request_timestamp(request_rec *r, char *a) return pstrdup(r->pool, tstr); } +/* static const char *extract_note(request_rec *r, char *a) { return ap_table_get(r->notes, a); - - /*ap_table_do(extract_table, r, r->notes, NULL);*/ - + } +*/ static const char *extract_env_var(request_rec *r, char *a) { @@ -415,7 +499,7 @@ static const char *extract_env_var(request_rec *r, char *a) static const char *extract_unique_id(request_rec *r, char *a) { const char *tempid; - + tempid = ap_table_get(r->subprocess_env, "UNIQUE_ID"); if (!tempid) return "-"; @@ -437,32 +521,30 @@ struct log_sql_item_list { { 'A', extract_agent, "agent", 1, 1 }, { 'b', extract_bytes_sent, "bytes_sent", 0, 0 }, - { 'c', extract_cookie, "cookie", 0, 1 }, - { 'e', extract_env_var, "env_var", 0, 1 }, - { 'f', extract_request_file, "request_file", 0, 1 }, + { 'c', extract_cookie, "cookie", 0, 1 }, + { 'e', extract_env_var, "env_var", 0, 1 }, + { 'f', extract_request_file, "request_file", 0, 1 }, { 'H', extract_request_protocol, "request_protocol", 0, 1 }, { 'h', extract_remote_host, "remote_host", 0, 1 }, - { 'i', extract_header_in, "header_in", 0, 1 }, { 'I', extract_unique_id, "id", 0, 1 }, { 'l', extract_remote_logname, "remote_logname", 0, 1 }, { 'm', extract_request_method, "request_method", 0, 1 }, - { 'n', extract_note, "note", 0, 1 }, - { 'o', extract_header_out, "header_out", 0, 1 }, - { 'P', extract_child_pid, "child_pid", 0, 0 }, - { 'p', extract_server_port, "server_port", 0, 0 }, - { 'R', extract_referer, "referer", 1, 1 }, - { 'r', extract_request_line, "request_line", 1, 1 }, - { 'S', extract_request_timestamp, "time_stamp", 0, 0 }, - { 's', extract_status, "status", 1, 0 }, - { 'T', extract_request_duration, "request_duration", 1, 0 }, - { 't', extract_request_time, "request_time", 0, 1 }, - { 'u', extract_remote_user, "remote_user", 0, 1 }, - { 'U', extract_request_uri, "request_uri", 1, 1 }, - { 'v', extract_virtual_host, "virtual_host", 0, 1 }, + { 'M', extract_machine_id, "machine_id", 0, 1 }, + { 'P', extract_child_pid, "child_pid", 0, 0 }, + { 'p', extract_server_port, "server_port", 0, 0 }, + { 'R', extract_referer, "referer", 1, 1 }, + { 'r', extract_request_line, "request_line", 1, 1 }, + { 'S', extract_request_timestamp, "time_stamp", 0, 0 }, + { 's', extract_status, "status", 1, 0 }, + { 'T', extract_request_duration, "request_duration", 1, 0 }, + { 't', extract_request_time, "request_time", 0, 1 }, + { 'u', extract_remote_user, "remote_user", 0, 1 }, + { 'U', extract_request_uri, "request_uri", 1, 1 }, + { 'v', extract_virtual_host, "virtual_host", 0, 1 }, #ifdef WANT_SSL_LOGGING - { 'q', extract_ssl_keysize, "ssl_keysize", 0, 1 }, - { 'Q', extract_ssl_maxkeysize, "ssl_maxkeysize", 0, 1 }, - { 'z', extract_ssl_cipher, "ssl_cipher", 0, 1 }, + { 'q', extract_ssl_keysize, "ssl_keysize", 0, 1 }, + { 'Q', extract_ssl_maxkeysize, "ssl_maxkeysize", 0, 1 }, + { 'z', extract_ssl_cipher, "ssl_cipher", 0, 1 }, #endif {'\0'} }; @@ -479,7 +561,7 @@ const char *escape_query(const char *from_str, pool *p) char *to_str; unsigned long length = strlen(from_str); unsigned long retval; - + /* Pre-allocate a new string that could hold twice the original, which would only * happen if the whole original string was 'dangerous' characters. */ @@ -487,20 +569,20 @@ const char *escape_query(const char *from_str, pool *p) if (!to_str) { return from_str; } - + if (!mysql_log) { /* Well, I would have liked to use the current database charset. mysql is * unavailable, however, so I fall back to the slightly less respectful * mysql_escape_string() function that uses the default charset. */ retval = mysql_escape_string(to_str, from_str, length); - } else { + } else { /* MySQL is available, so I'll go ahead and respect the current charset when * I perform the escape. */ retval = mysql_real_escape_string(mysql_log, to_str, from_str, length); } - + if (retval) return to_str; else @@ -508,24 +590,37 @@ const char *escape_query(const char *from_str, pool *p) } } -int open_logdb_link() +int open_logdb_link(server_rec* s) { - /* Returns 2 if already connected, 1 if successful, 0 if unsuccessful */ - - if (mysql_log != NULL) { + /* Returns: + 3 if preserve forced + 2 if already connected + 1 if successful + 0 if unsuccessful + */ + + if (force_preserve) + return 3; + + if (mysql_log != NULL) return 2; - } if (db_name) { mysql_init(&sql_server); - mysql_log = mysql_real_connect(&sql_server, db_host, db_user, db_pwd, db_name, 0, socket_file, 0); + mysql_log = mysql_real_connect(&sql_server, db_host, db_user, db_pwd, db_name, tcp_port, socket_file, 0); - if (mysql_log != NULL) { + if (mysql_log) { return 1; } else { + #ifdef DEBUG + ap_log_error(APLOG_MARK,DEBUGLEVEL,s,"mod_log_sql: database connection error: %s",MYSQL_ERROR(&sql_server)); + ap_log_error(APLOG_MARK,DEBUGLEVEL,s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'", + db_host, tcp_port, db_name, db_user, socket_file); + #endif return 0; } } + return 0; } @@ -536,13 +631,13 @@ static int trace(void *data, const char *key, const char *val) request_rec *r = (request_rec *)data; fp = pfopen(r->pool, "/tmp/trace", "a"); - + if (fp) { fprintf(fp, "Field '%s' == '%s'\n", key, val); } - + pfclose(r->pool, fp); - + return TRUE; } #endif @@ -557,8 +652,8 @@ const char *extract_table(void *data, const char *key, const char *val) void preserve_entry(request_rec *r, const char *query) { FILE *fp; - log_sql_state *cls = get_module_config(r->server->module_config, &mysql_log_module); - + log_sql_state *cls = get_module_config(r->server->module_config, &sql_log_module); + fp = pfopen(r->pool, cls->preserve_file, "a"); if (fp == NULL) ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: attempted append of local preserve file but failed."); @@ -567,7 +662,7 @@ void preserve_entry(request_rec *r, const char *query) pfclose(r->pool, fp); #ifdef DEBUG ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: entry preserved in %s", cls->preserve_file); - #endif + #endif } } @@ -588,32 +683,32 @@ unsigned int safe_mysql_query(request_rec *r, const char *query) struct timespec delay, remainder; int ret; void (*handler) (int); - + /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */ - handler = signal(SIGPIPE, SIG_IGN); + handler = signal(SIGPIPE, SIG_IGN); /* First attempt for the query */ - if (mysql_log != NULL) + if (mysql_log != NULL) retval = mysql_query(mysql_log, query); else return 1; - + if ( retval != 0 ) { /* If we ran the query and it returned an error, try to be robust. * (After all, the module thought it had a valid mysql_log connection but the query * could have failed for a number of reasons, so we have to be extra-safe and check.) */ - - log_sql_state *cls = get_module_config(r->server->module_config, &mysql_log_module); + + log_sql_state *cls = get_module_config(r->server->module_config, &sql_log_module); real_error = mysql_errno(mysql_log); /* What really happened? */ - + /* Something went wrong, so start by trying to restart the db link. */ 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)); mysql_close(mysql_log); mysql_log = NULL; - open_logdb_link(); + open_logdb_link(r->server); if (mysql_log == NULL) { /* still unable to link */ signal(SIGPIPE, handler); @@ -639,13 +734,13 @@ unsigned int safe_mysql_query(request_rec *r, const char *query) real_error = mysql_errno(mysql_log); 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)); retval = real_error; - } else + } else ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: second attempt successful"); } /* Restore SIGPIPE to its original handler function */ signal(SIGPIPE, handler); - + return retval; } @@ -661,18 +756,20 @@ int safe_create_tables(log_sql_state *cls, request_rec *r) { int retval; unsigned int create_results; - char *create_access = NULL; + char *create_access = NULL; char *create_notes = NULL; char *create_hout = NULL; char *create_hin = NULL; - - char *createprefix = "create table if not exists "; + char *create_cookies = NULL; + + char *createprefix = "create table if not exists `"; char *access_suffix = - " (id char(19),\ - agent varchar(255),\ - bytes_sent int unsigned,\ + "` (id char(19),\ + agent varchar(255),\ + bytes_sent int unsigned,\ child_pid smallint unsigned,\ cookie varchar(255),\ + machine_id varchar(25),\ request_file varchar(255),\ referer varchar(255),\ remote_host varchar(50),\ @@ -680,7 +777,7 @@ int safe_create_tables(log_sql_state *cls, request_rec *r) remote_user varchar(50),\ request_duration smallint unsigned,\ request_line varchar(255),\ - request_method varchar(6),\ + request_method varchar(10),\ request_protocol varchar(10),\ request_time char(28),\ request_uri varchar(50),\ @@ -691,58 +788,71 @@ int safe_create_tables(log_sql_state *cls, request_rec *r) status smallint unsigned,\ time_stamp int unsigned,\ virtual_host varchar(50))"; - - char *notes_suffix = - " (id char(19),\ + + char *notes_suffix = + "` (id char(19),\ item varchar(80),\ val varchar(80))"; - - char *headers_suffix = - " (id char(19),\ + + char *headers_suffix = + "` (id char(19),\ item varchar(80),\ val varchar(80))"; - + + char *cookies_suffix = + "` (id char(19),\ + item varchar(80),\ + val varchar(80))"; + /* Find memory long enough to hold the whole CREATE string + \0 */ - create_access = ap_pstrcat(r->pool, createprefix, cls->transfer_table_name, access_suffix, NULL); - create_notes = ap_pstrcat(r->pool, createprefix, cls->notes_table_name, notes_suffix, NULL); - create_hout = ap_pstrcat(r->pool, createprefix, cls->hout_table_name, headers_suffix, NULL); - create_hin = ap_pstrcat(r->pool, createprefix, cls->hin_table_name, headers_suffix, NULL); - + create_access = ap_pstrcat(r->pool, createprefix, cls->transfer_table_name, access_suffix, NULL); + create_notes = ap_pstrcat(r->pool, createprefix, cls->notes_table_name, notes_suffix, NULL); + create_hout = ap_pstrcat(r->pool, createprefix, cls->hout_table_name, headers_suffix, NULL); + create_hin = ap_pstrcat(r->pool, createprefix, cls->hin_table_name, headers_suffix, NULL); + create_cookies= ap_pstrcat(r->pool, createprefix, cls->cookie_table_name, cookies_suffix, NULL); + #ifdef DEBUG ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_access); ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_notes); ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_hout); ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_hin); + ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: create string: %s", create_cookies); #endif /* Assume that things worked unless told otherwise */ cls->table_made = 1; retval = 0; - + if ((create_results = safe_mysql_query(r, create_access)) != 0) { cls->table_made = 0; ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create access table"); retval = create_results; } - + if ((create_results = safe_mysql_query(r, create_notes)) != 0) { cls->table_made = 0; ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create notes table"); - retval = create_results; + retval = create_results; } - + if ((create_results = safe_mysql_query(r, create_hin)) != 0) { cls->table_made = 0; ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create header_out table"); retval = create_results; } - + if ((create_results = safe_mysql_query(r, create_hout)) != 0) { cls->table_made = 0; ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create header_in table"); retval = create_results; } - + + if ((create_results = safe_mysql_query(r, create_cookies)) != 0) { + cls->table_made = 0; + ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create cookies table"); + retval = create_results; + } + return retval; } @@ -757,6 +867,18 @@ const char *set_log_sql_massvirtual(cmd_parms *parms, void *dummy, int flag) return NULL; } +const char *set_log_sql_force_preserve(cmd_parms *parms, void *dummy, int flag) +{ + force_preserve = ( flag ? 1 : 0); + return NULL; +} + +const char *set_log_sql_machine_id(cmd_parms *parms, void *dummy, char *arg) +{ + mach_id = arg; + return NULL; +} + const char *set_log_sql_create(cmd_parms *parms, void *dummy, int flag) { if (massvirtual != 0) @@ -774,7 +896,7 @@ const char *set_log_sql_db(cmd_parms *parms, void *dummy, char *arg) const char *set_log_sql_cookie(cmd_parms *parms, void *dummy, char *arg) { - log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); + log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); cls->cookie_name = arg; return NULL; @@ -783,7 +905,7 @@ const char *set_log_sql_cookie(cmd_parms *parms, void *dummy, char *arg) const char *set_log_sql_preserve_file(cmd_parms *parms, void *dummy, char *arg) { /* char *pfile; */ - log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); + log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); /* pfile = ap_pstrcat(parms->pool, "/tmp/", arg, NULL); */ cls->preserve_file = arg; @@ -806,7 +928,7 @@ const char *set_log_sql_info(cmd_parms *parms, void *dummy, char *host, char *us const char *set_log_sql_transfer_table(cmd_parms *parms, void *dummy, char *arg) { - log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); + log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); if (massvirtual != 0) ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLTransferLogTable when LogSQLMassVirtualHosting is On. Ignoring."); @@ -815,9 +937,20 @@ const char *set_log_sql_transfer_table(cmd_parms *parms, void *dummy, char *arg) return NULL; } +const char *set_log_sql_cookie_table(cmd_parms *parms, void *dummy, char *arg) +{ + log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); + + if (massvirtual != 0) + ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLCookieLogTable when LogSQLMassVirtualHosting is On. Ignoring."); + else + cls->cookie_table_name = arg; + return NULL; +} + const char *set_log_sql_notes_table(cmd_parms *parms, void *dummy, char *arg) { - log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); + log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); if (massvirtual != 0) ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLNotesLogTable when LogSQLMassVirtualHosting is On. Ignoring."); @@ -828,7 +961,7 @@ const char *set_log_sql_notes_table(cmd_parms *parms, void *dummy, char *arg) const char *set_log_sql_hin_table(cmd_parms *parms, void *dummy, char *arg) { - log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); + log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); if (massvirtual != 0) ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLHeadersInLogTable when LogSQLMassVirtualHosting is On. Ignoring."); @@ -839,7 +972,7 @@ const char *set_log_sql_hin_table(cmd_parms *parms, void *dummy, char *arg) const char *set_log_sql_hout_table(cmd_parms *parms, void *dummy, char *arg) { - log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); + log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); if (massvirtual != 0) ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLHeadersOutLogTable when LogSQLMassVirtualHosting is On. Ignoring."); @@ -850,7 +983,7 @@ const char *set_log_sql_hout_table(cmd_parms *parms, void *dummy, char *arg) const char *set_log_sql_transfer_log_format(cmd_parms *parms, void *dummy, char *arg) { - log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); + log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); cls->transfer_log_format = arg; return NULL; @@ -863,10 +996,17 @@ const char *set_log_sql_socket_file(cmd_parms *parms, void *dummy, char *arg) return NULL; } +const char *set_log_sql_tcp_port(cmd_parms *parms, void *dummy, char *arg) +{ + tcp_port = (unsigned int)atoi(arg); + + return NULL; +} + const char *add_log_sql_referer_ignore(cmd_parms *parms, void *dummy, char *arg) { char **addme; - log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); + log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); addme = push_array(cls->referer_ignore_list); *addme = pstrdup(cls->referer_ignore_list->pool, arg); @@ -876,7 +1016,7 @@ const char *add_log_sql_referer_ignore(cmd_parms *parms, void *dummy, char *arg) const char *add_log_sql_transfer_ignore(cmd_parms *parms, void *dummy, char *arg) { char **addme; - log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); + log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); addme = push_array(cls->transfer_ignore_list); *addme = pstrdup(cls->transfer_ignore_list->pool, arg); @@ -886,7 +1026,7 @@ const char *add_log_sql_transfer_ignore(cmd_parms *parms, void *dummy, char *arg const char *add_log_sql_remhost_ignore(cmd_parms *parms, void *dummy, char *arg) { char **addme; - log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); + log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); addme = push_array(cls->remhost_ignore_list); *addme = pstrdup(cls->remhost_ignore_list->pool, arg); @@ -896,7 +1036,7 @@ const char *add_log_sql_remhost_ignore(cmd_parms *parms, void *dummy, char *arg) const char *add_log_sql_note(cmd_parms *parms, void *dummy, char *arg) { char **addme; - log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); + log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); addme = push_array(cls->notes_list); *addme = pstrdup(cls->notes_list->pool, arg); @@ -906,7 +1046,7 @@ const char *add_log_sql_note(cmd_parms *parms, void *dummy, char *arg) const char *add_log_sql_hout(cmd_parms *parms, void *dummy, char *arg) { char **addme; - log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); + log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); addme = push_array(cls->hout_list); *addme = pstrdup(cls->hout_list->pool, arg); @@ -916,13 +1056,22 @@ const char *add_log_sql_hout(cmd_parms *parms, void *dummy, char *arg) const char *add_log_sql_hin(cmd_parms *parms, void *dummy, char *arg) { char **addme; - log_sql_state *cls = get_module_config(parms->server->module_config, &mysql_log_module); + log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); addme = push_array(cls->hin_list); *addme = pstrdup(cls->hin_list->pool, arg); return NULL; } +const char *add_log_sql_cookie(cmd_parms *parms, void *dummy, char *arg) +{ + char **addme; + log_sql_state *cls = get_module_config(parms->server->module_config, &sql_log_module); + + addme = push_array(cls->cookie_list); + *addme = pstrdup(cls->cookie_list->pool, arg); + return NULL; +} @@ -932,7 +1081,7 @@ const char *add_log_sql_hin(cmd_parms *parms, void *dummy, char *arg) *------------------------------------------------------------*/ -/* +/* * This function is called during server initialisation when an heavy-weight * process (such as a child) is being initialised. As with the * module-initialisation function, any information that needs to be recorded @@ -943,19 +1092,20 @@ const char *add_log_sql_hin(cmd_parms *parms, void *dummy, char *arg) static void log_sql_child_init(server_rec *s, pool *p) { int retval; - - retval = open_logdb_link(); + + retval = open_logdb_link(s); if (retval == 0) - ap_log_error(APLOG_MARK,ERRLEVEL,s,"mod_log_sql: child spawned but unable to open database link"); - + ap_log_error(APLOG_MARK,ERRLEVEL,s,"mod_log_sql: child spawned but unable to open database link"); + #ifdef DEBUG - if (retval > 0) { - ap_log_error(APLOG_MARK,DEBUGLEVEL,s,"mod_log_sql: open_logdb_link successful"); - } + if ( (retval == 1) || (retval == 2) ) + ap_log_error(APLOG_MARK,DEBUGLEVEL,s,"mod_log_sql: open_logdb_link successful"); + if (retval == 3) + ap_log_error(APLOG_MARK,DEBUGLEVEL,s,"mod_log_sql: open_logdb_link said that preservation is forced"); #endif } -/* +/* * This function is called when an heavy-weight process (such as a child) is * being run down or destroyed. As with the child-initialisation function, * any information that needs to be recorded must be in static cells, since @@ -973,15 +1123,15 @@ static void log_sql_child_exit(server_rec *s, pool *p) void *log_sql_initializer(server_rec *main_server, pool *p) { server_rec *s; - - log_sql_state main_conf = ap_get_module_config(main_server->module_config, &mysql_log_module); + + log_sql_state main_conf = ap_get_module_config(main_server->module_config, &sql_log_module); for (server_rec *s = main_server; s; s = s->next) { - conf = ap_get_module_config(s->module_config, &mysql_log_module); + conf = ap_get_module_config(s->module_config, &sql_log_module); if (conf->transfer_log_format == NULL && s != main_server) { *conf = *main_conf; } - + } */ @@ -996,26 +1146,28 @@ void *log_sql_initializer(server_rec *main_server, pool *p) */ void *log_sql_make_state(pool *p, server_rec *s) { - + log_sql_state *cls = (log_sql_state *) ap_palloc(p, sizeof(log_sql_state)); - cls->transfer_table_name = NULL; - cls->transfer_log_format = NULL; + /* These defaults are overridable in the httpd.conf file. */ + cls->transfer_table_name = NULL; /* No default b/c we want its absence to disable logging */ + cls->transfer_log_format = "AbHhmRSsTUuv"; cls->notes_table_name = "notes"; cls->hin_table_name = "headers_in"; cls->hout_table_name = "headers_out"; - + cls->cookie_table_name = "cookies"; + cls->preserve_file = "/tmp/sql-preserve"; + cls->referer_ignore_list = make_array(p, 1, sizeof(char *)); cls->transfer_ignore_list = make_array(p, 1, sizeof(char *)); cls->remhost_ignore_list = make_array(p, 1, sizeof(char *)); cls->notes_list = make_array(p, 1, sizeof(char *)); cls->hin_list = make_array(p, 1, sizeof(char *)); cls->hout_list = make_array(p, 1, sizeof(char *)); + cls->cookie_list = make_array(p, 1, sizeof(char *)); cls->table_made = 0; - - cls->preserve_file = "/tmp/sql-preserve"; cls->cookie_name = NULL; - + return (void *) cls; } @@ -1036,9 +1188,15 @@ command_rec log_sql_cmds[] = { {"LogSQLHeadersInLogTable", set_log_sql_hin_table, NULL, RSRC_CONF, TAKE1, "The database table that holds the inbound headers"} , + {"LogSQLCookieLogTable", set_log_sql_cookie_table, NULL, RSRC_CONF, TAKE1, + "The database table that holds the cookie info"} + , {"LogSQLTransferLogFormat", set_log_sql_transfer_log_format, NULL, RSRC_CONF, TAKE1, "Instruct the module what information to log to the database transfer log"} , + {"LogSQLMachineID", set_log_sql_machine_id, NULL, RSRC_CONF, TAKE1, + "Machine ID that the module will log, useful in web clusters to differentiate machines"} + , {"LogSQLRefererIgnore", add_log_sql_referer_ignore, NULL, RSRC_CONF, ITERATE, "List of referers to ignore. Accesses that match will not be logged to database"} , @@ -1052,7 +1210,7 @@ command_rec log_sql_cmds[] = { "The name of the database database for logging"} , {"LogSQLWhichCookie", set_log_sql_cookie, NULL, RSRC_CONF, TAKE1, - "The CookieName that you want logged when using the 'c' config directive"} + "The single cookie that you want logged in the access_log when using the 'c' config directive"} , {"LogSQLLoginInfo", set_log_sql_info, NULL, RSRC_CONF, TAKE3, "The database host, user-id and password for logging"} @@ -1063,33 +1221,42 @@ command_rec log_sql_cmds[] = { {"LogSQLMassVirtualHosting", set_log_sql_massvirtual, NULL, RSRC_CONF, FLAG, "Activates option(s) useful for ISPs performing mass virutal hosting"} , + {"LogSQLForcePreserve", set_log_sql_force_preserve, NULL, RSRC_CONF, FLAG, + "Forces logging to preserve file and bypasses database"} + , {"LogSQLPreserveFile", set_log_sql_preserve_file, NULL, RSRC_CONF, TAKE1, "Name of the file to use for data preservation during database downtime"} , {"LogSQLSocketFile", set_log_sql_socket_file, NULL, RSRC_CONF, TAKE1, "Name of the file to employ for socket connections to database"} , + {"LogSQLTCPPort", set_log_sql_tcp_port, NULL, RSRC_CONF, TAKE1, + "Port number to use for TCP connections to database, defaults to 3306 if not set"} + , {"LogSQLWhichNotes", add_log_sql_note, NULL, RSRC_CONF, ITERATE, - "Members of the 'notes' that you would like to log"} + "Notes that you would like to log in a separate table"} , {"LogSQLWhichHeadersOut", add_log_sql_hout, NULL, RSRC_CONF, ITERATE, - "Members of the 'headers out' that you would like to log"} + "Outbound headers that you would like to log in a separate table"} , {"LogSQLWhichHeadersIn", add_log_sql_hin, NULL, RSRC_CONF, ITERATE, - "Members of the 'headers in' that you would like to log"} + "Inbound headers that you would like to log in a separate table"} + , + {"LogSQLWhichCookies", add_log_sql_cookie, NULL, RSRC_CONF, ITERATE, + "The cookie(s) that you would like to log in a separate table"} , {NULL} }; - + /* Routine to perform the actual construction and execution of the relevant * INSERT statements. */ int log_sql_transaction(request_rec *orig) { char **ptrptr, **ptrptr2; - log_sql_state *cls = get_module_config(orig->server->module_config, &mysql_log_module); + log_sql_state *cls = get_module_config(orig->server->module_config, &sql_log_module); const char *access_query; request_rec *r; @@ -1101,36 +1268,43 @@ int log_sql_transaction(request_rec *orig) char *notes_base = "notes_"; char *hout_base = "headout_"; char *hin_base = "headin_"; + char *cookie_base = "cookies_"; char *a_tablename; char *n_tablename; char *i_tablename; char *o_tablename; + char *c_tablename; int i; - + /* Find memory long enough to hold the table name + \0. */ a_tablename = ap_pstrcat(orig->pool, access_base, ap_get_server_name(orig), NULL); n_tablename = ap_pstrcat(orig->pool, notes_base, ap_get_server_name(orig), NULL); i_tablename = ap_pstrcat(orig->pool, hin_base, ap_get_server_name(orig), NULL); o_tablename = ap_pstrcat(orig->pool, hout_base, ap_get_server_name(orig), NULL); - - /* Transform any dots or dashes to underscores */ + c_tablename = ap_pstrcat(orig->pool, cookie_base, ap_get_server_name(orig), NULL); + + /* Transform any dots to underscores */ for (i = 0; i < strlen(a_tablename); i++) { - if ( (a_tablename[i] == '.') || (a_tablename[i] == '-') ) + if (a_tablename[i] == '.') a_tablename[i] = '_'; } for (i = 0; i < strlen(n_tablename); i++) { - if ( (n_tablename[i] == '.') || (n_tablename[i] == '-') ) + if (n_tablename[i] == '.') n_tablename[i] = '_'; } for (i = 0; i < strlen(i_tablename); i++) { - if ( (i_tablename[i] == '.') || (i_tablename[i] == '-') ) + if (i_tablename[i] == '.') i_tablename[i] = '_'; } for (i = 0; i < strlen(o_tablename); i++) { - if ( (o_tablename[i] == '.') || (o_tablename[i] == '-') ) + if (o_tablename[i] == '.') o_tablename[i] = '_'; } - + for (i = 0; i < strlen(c_tablename); i++) { + if (c_tablename[i] == '.') + c_tablename[i] = '_'; + } + /* Tell this virtual server its transfer table name, and * turn on create_tables, which is implied by massvirtual. */ @@ -1138,9 +1312,10 @@ int log_sql_transaction(request_rec *orig) cls->notes_table_name = n_tablename; cls->hout_table_name = o_tablename; cls->hin_table_name = i_tablename; + cls->cookie_table_name = c_tablename; create_tables = 1; } - + /* Do we have enough info to log? */ if ( cls->transfer_table_name == NULL ) { return DECLINED; @@ -1152,11 +1327,12 @@ int log_sql_transaction(request_rec *orig) char *note_query = NULL; char *hin_query = NULL; char *hout_query = NULL; + char *cookie_query = NULL; const char *unique_id; const char *formatted_item; int i, j, length; int result; - + for (r = orig; r->next; r = r->next) { continue; } @@ -1188,10 +1364,6 @@ int log_sql_transaction(request_rec *orig) } } - /* If not specified by the user, use the default format */ - if (cls->transfer_log_format == NULL) { - cls->transfer_log_format = "AbHhmRSsTUuv"; - } length = strlen(cls->transfer_log_format); /* Iterate through the format characters and set up the INSERT string according to @@ -1205,20 +1377,20 @@ int log_sql_transaction(request_rec *orig) /* Yes, this key is one of the configured keys. * Call the key's function and put the returned value into 'formatted_item' */ formatted_item = log_sql_item_keys[j].func(log_sql_item_keys[j].want_orig_default ? orig : r, ""); - + /* Massage 'formatted_item' for proper SQL eligibility... */ if (!formatted_item) { formatted_item = ""; } else if (formatted_item[0] == '-' && formatted_item[1] == '\0' && !log_sql_item_keys[j].string_contents) { - /* If apache tried to log a '-' character for a numeric field, convert that to a zero + /* If apache tried to log a '-' character for a numeric field, convert that to a zero * because the database expects a numeral and will reject the '-' character. */ formatted_item = "0"; } - + /* Append the fieldname and value-to-insert to the appropriate strings, quoting stringvals with ' as appropriate */ fields = pstrcat(r->pool, fields, (i > 0 ? "," : ""), log_sql_item_keys[j].sql_field_name, NULL); - + values = pstrcat(r->pool, values, (i > 0 ? "," : ""), (log_sql_item_keys[j].string_contents ? "'" : ""), escape_query(formatted_item, r->pool), @@ -1230,129 +1402,181 @@ int log_sql_transaction(request_rec *orig) } } - /* Work through the list of notes defined by LogSQLNotesToLog */ + /* Work through the list of notes defined by LogSQLWhichNotes */ i = 0; unique_id = extract_unique_id(r, ""); - + ptrptr2 = (char **) (cls->notes_list->elts + (cls->notes_list->nelts * cls->notes_list->elt_size)); for (ptrptr = (char **) cls->notes_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->notes_list->elt_size)) { /* If the specified note (*ptrptr) exists for the current request... */ if ((theitem = ap_table_get(r->notes, *ptrptr))) { - itemsets = ap_pstrcat(r->pool, itemsets, + itemsets = ap_pstrcat(r->pool, itemsets, (i > 0 ? "," : ""), "('", unique_id, "','", - escape_query(*ptrptr, r->pool), - "','", + escape_query(*ptrptr, r->pool), + "','", escape_query(theitem, r->pool), - "')", + "')", NULL); - i++; + i++; } } if ( itemsets != "" ) { - note_query = ap_pstrcat(r->pool, "insert into ", cls->notes_table_name, " (id, item, val) values ", itemsets, NULL); + note_query = ap_pstrcat(r->pool, "insert into `", cls->notes_table_name, "` (id, item, val) values ", itemsets, NULL); #ifdef DEBUG ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: note string: %s", note_query); #endif } - - /* Work through the list of headers-out defined by LogSQLHeadersOutToLog */ + + /* Work through the list of headers-out defined by LogSQLWhichHeadersOut*/ i = 0; itemsets = ""; - + ptrptr2 = (char **) (cls->hout_list->elts + (cls->hout_list->nelts * cls->hout_list->elt_size)); for (ptrptr = (char **) cls->hout_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->hout_list->elt_size)) { - /* If the specified note (*ptrptr) exists for the current request... */ + /* If the specified header (*ptrptr) exists for the current request... */ if ((theitem = ap_table_get(r->headers_out, *ptrptr))) { - itemsets = ap_pstrcat(r->pool, itemsets, + itemsets = ap_pstrcat(r->pool, itemsets, (i > 0 ? "," : ""), "('", unique_id, "','", - escape_query(*ptrptr, r->pool), - "','", + escape_query(*ptrptr, r->pool), + "','", escape_query(theitem, r->pool), - "')", + "')", NULL); - i++; + i++; } } if ( itemsets != "" ) { - hout_query = ap_pstrcat(r->pool, "insert into ", cls->hout_table_name, " (id, item, val) values ", itemsets, NULL); + hout_query = ap_pstrcat(r->pool, "insert into `", cls->hout_table_name, "` (id, item, val) values ", itemsets, NULL); #ifdef DEBUG ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: header_out string: %s", hout_query); #endif } - - /* Work through the list of headers-in defined by LogSQLHeadersInToLog */ + + /* Work through the list of headers-in defined by LogSQLWhichHeadersIn */ i = 0; itemsets = ""; - + ptrptr2 = (char **) (cls->hin_list->elts + (cls->hin_list->nelts * cls->hin_list->elt_size)); for (ptrptr = (char **) cls->hin_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->hin_list->elt_size)) { - /* If the specified note (*ptrptr) exists for the current request... */ + /* If the specified header (*ptrptr) exists for the current request... */ if ((theitem = ap_table_get(r->headers_in, *ptrptr))) { - itemsets = ap_pstrcat(r->pool, itemsets, + itemsets = ap_pstrcat(r->pool, itemsets, (i > 0 ? "," : ""), "('", unique_id, "','", - escape_query(*ptrptr, r->pool), - "','", + escape_query(*ptrptr, r->pool), + "','", escape_query(theitem, r->pool), - "')", + "')", NULL); - i++; + i++; } } if ( itemsets != "" ) { - hin_query = ap_pstrcat(r->pool, "insert into ", cls->hin_table_name, " (id, item, val) values ", itemsets, NULL); + hin_query = ap_pstrcat(r->pool, "insert into `", cls->hin_table_name, "` (id, item, val) values ", itemsets, NULL); #ifdef DEBUG ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: header_in string: %s", hin_query); #endif } - + + + /* Work through the list of cookies defined by LogSQLWhichCookies */ + i = 0; + itemsets = ""; + + ptrptr2 = (char **) (cls->cookie_list->elts + (cls->cookie_list->nelts * cls->cookie_list->elt_size)); + for (ptrptr = (char **) cls->cookie_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->cookie_list->elt_size)) { + /* If the specified cookie (*ptrptr) exists for the current request... */ + if ( strncmp((theitem = extract_specific_cookie(r, *ptrptr)), "-", 1) ) { + itemsets = ap_pstrcat(r->pool, itemsets, + (i > 0 ? "," : ""), + "('", + unique_id, + "','", + escape_query(*ptrptr, r->pool), + "','", + escape_query(theitem, r->pool), + "')", + NULL); + i++; + } + + } + if ( itemsets != "" ) { + cookie_query = ap_pstrcat(r->pool, "insert into `", cls->cookie_table_name, "` (id, item, val) values ", itemsets, NULL); + #ifdef DEBUG + ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: cookie string: %s", cookie_query); + #endif + } + + /* Set up the actual INSERT statement */ - access_query = ap_pstrcat(r->pool, "insert into ", cls->transfer_table_name, " (", fields, ") values (", values, ")", NULL); + access_query = ap_pstrcat(r->pool, "insert into `", cls->transfer_table_name, "` (", fields, ") values (", values, ")", NULL); #ifdef DEBUG ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: access string: %s", access_query); #endif - + + /* If the person activated force-preserve, go ahead and push all the entries + * into the preserve file, then return. + */ + if (force_preserve) { + #ifdef DEBUG + ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: preservation forced"); + #endif + preserve_entry(orig, access_query); + if ( note_query != NULL ) + preserve_entry(orig, note_query); + if ( hin_query != NULL ) + preserve_entry(orig, hin_query); + if ( hout_query != NULL ) + preserve_entry(orig, hout_query); + if ( cookie_query != NULL ) + preserve_entry(orig, cookie_query); + return OK; + } + /* How's our mysql link integrity? */ if (mysql_log == NULL) { /* Make a try to establish the link */ - open_logdb_link(); - + open_logdb_link(r->server); + if (mysql_log == NULL) { /* Unable to re-establish a DB link, so assume that it's really - * gone and send the entry to the preserve file instead. + * gone and send the entry to the preserve file instead. * This short-circuits safe_mysql_query during a db outage and therefore - * we don't keep logging the db error over and over. + * we don't keep logging the db error over and over. */ preserve_entry(orig, access_query); - if ( note_query != NULL ) + if ( note_query != NULL ) preserve_entry(orig, note_query); if ( hin_query != NULL ) preserve_entry(orig, hin_query); if ( hout_query != NULL ) preserve_entry(orig, hout_query); - + if ( cookie_query != NULL ) + preserve_entry(orig, cookie_query); + return OK; } else { /* Whew, we got the DB link back */ ap_log_error(APLOG_MARK,NOTICELEVEL,orig->server,"mod_log_sql: child established database connection"); } } - - + + /* ---> So as of here we have a non-null value of mysql_log. <--- */ /* ---> i.e. we have a good MySQL connection. <--- */ - + /* Make the tables if we're supposed to. */ if ((cls->table_made != 1) && (create_tables != 0)) { @@ -1362,14 +1586,14 @@ int log_sql_transaction(request_rec *orig) else ap_log_error(APLOG_MARK,NOTICELEVEL,orig->server,"mod_log_sql: no problems creating tables for %s", ap_get_server_name(orig)); } - + /* Make the access-table insert */ result = safe_mysql_query(orig, access_query); - + /* It failed, but NOT because table didn't exist */ if ( (result != 0) && (result != 1146) ) preserve_entry(orig,access_query); - + /* It failed because table didn't exist */ if (result == 1146) { ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: hmm, table didn't yet exist; creating"); @@ -1387,17 +1611,20 @@ int log_sql_transaction(request_rec *orig) } } } - + /* Log the optional notes, headers, etc. */ if ( note_query != NULL ) safe_mysql_query(orig, note_query); - + if ( hout_query != NULL ) safe_mysql_query(orig, hout_query); - + if ( hin_query != NULL ) safe_mysql_query(orig, hin_query); - + + if ( cookie_query != NULL ) + safe_mysql_query(orig, cookie_query); + return OK; } } @@ -1406,7 +1633,7 @@ int log_sql_transaction(request_rec *orig) /* The configuration array that sets up the hooks into the module. */ -module mysql_log_module = { +module sql_log_module = { STANDARD_MODULE_STUFF, NULL, /* module initializer */ NULL, /* create per-dir config */ @@ -1428,5 +1655,5 @@ module mysql_log_module = { log_sql_child_exit, /* process exit/cleanup */ NULL /* [1] post read-request */ #endif - + }; -- cgit v0.9.2