From 80673c37abcedb421c04193f50e0cd53a6ac01c4 Mon Sep 17 00:00:00 2001 From: Christopher Powell Date: Thu, 27 Jun 2002 20:09:17 +0000 Subject: Lots of changes & bugfixes as requested on the list. Pre-1 of 1.17. --- CHANGELOG | 20 +++++-- INSTALL | 25 ++++----- LICENSE | 164 ++++++++++++++++++++++++++++++++++++++++------------------ mod_log_sql.c | 76 ++++++++++++++++++--------- 4 files changed, 193 insertions(+), 92 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 68d3247..27a4535 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -$Id: CHANGELOG,v 1.13 2002/05/24 20:52:39 helios Exp $ +$Id: CHANGELOG,v 1.14 2002/06/27 20:09:17 helios Exp $ TODO: @@ -10,6 +10,9 @@ TODO: * port to Apache 2.x * does determining table name in massvirtual mode upon every request cause performance degradation? If so fix. +* LogSQLRotateLogs directive with daily/monthly/weekly/etc. +* new format char: IP as bigint? +* socket-based middleman daemon with configurable conns? CHANGES: @@ -44,7 +47,18 @@ CHANGES: * Config directives used to begin with MySQL, now begin with LogSQL. This is for database inspecificity. In your httpd.conf just do a search-and-replace. - +* More robust table-creation code with error checking. [The race condition + that several users have reported may still exist, but this will go a long + way toward debugging the condition.] +* Fixed bug whereby a MySQL connection was abandoned on reopen; the old + connection is now properly closed first. +* Minor: remind user not to set createtables when massvirtual is on. +* If Apache started but MySQL was unavailable, the module would do + everything it was supposed to (preserve entries, etc.) but not notify + the sysadmin. Added a log message to alert sysadmin if MySQL is + unreachable at startup. +* Migrated to the Artistic License (as used by Perl). + 1.16: * Moved all the user DEFINEs inside the .c file -- splitting them @@ -87,7 +101,7 @@ CHANGES: * Reduced sleep time on a retry to 1/4 second from 1/2 second. * Confirmed that this module will compile with -pedantic ... but not with -ansi. :-) - + 1.15: * Vastly improved error reporting is a lot clearer about lost db diff --git a/INSTALL b/INSTALL index 03adc35..7c48c21 100644 --- a/INSTALL +++ b/INSTALL @@ -1,4 +1,4 @@ -$Id: INSTALL,v 1.8 2002/05/14 21:47:14 helios Exp $ +$Id: INSTALL,v 1.9 2002/06/27 20:09:17 helios Exp $ Requirements @@ -65,26 +65,19 @@ For folks interested in using this module as an Apache DSO: EXAMPLE: # /usr/sbin/apxs -i -c -L/usr/lib/mysql -lmysqlclient -lz mod_log_sql.c - You should see something like this: + You should see something similar to this: - gcc -fpic -DSHARED_MODULE -I/usr/local/Apache/include -c mod_log_sql.c - ld -Bshareable -o mod_log_sql.so mod_log_sql.o - cp mod_log_sql.so /mod_log_sql.so - chmod 755 /mod_log_sql.so - [activating module blah in /path/to/apache/etc/httpd.conf] + gcc -fpic -DSHARED_MODULE -I/usr/local/apache/include -c mod_log_mysql.c + gcc -shared -o mod_log_mysql.so mod_log_mysql.o -L/usr/local/lib/mysql/ -lmysqlclient -lz + cp mod_log_mysql.so /usr/local/apache/libexec/mod_log_mysql.so + chmod 755 /usr/local/apache/libexec/mod_log_mysql.so -4) Add the following stanzas to your httpd.conf file. Put the second stanza +4) Add the following lines to your httpd.conf file. Put the second line somewhere after the ClearModuleList directive. - - LoadModule mysql_log_module modules/mod_log_sql.so - - - - - AddModule mod_log_sql.c - + LoadModule mysql_log_module libexec/mod_log_sql.so + AddModule mod_log_sql.c 5) Now go to step (9) in the instructions below to configure httpd.conf... diff --git a/LICENSE b/LICENSE index 5d855ea..1b82b9d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,55 +1,121 @@ -$Id: LICENSE,v 1.3 2002/05/14 21:50:51 helios Exp $ +$Id: LICENSE,v 1.4 2002/06/27 20:09:17 helios Exp $ Copyright (c) 2002 Christopher B. Powell. All rights reserved. Portions copyright (c) 2000 The Apache Software Foundation. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in - the documentation and/or other materials provided with the - distribution. - -3. The end-user documentation included with the redistribution, - if any, must include the following acknowledgment: - "This product includes software developed by the - Apache Software Foundation (http://www.apache.org/) - and by Christopher Powell, mod_log_mysql Module Maintainer - (http://www.grubbybaby.com/mod_log_mysql/)." - Alternately, this acknowledgment may appear in the software itself, - if and wherever such third-party acknowledgments normally appear. - -4. The names "mod_log_mysql" and "mod_log_sql" must - not be used to endorse or promote products derived from this - software without prior written permission. For written - permission, please contact . - -5. Products derived from this software may not be called - "mod_log_mysql" or "mod_log_sql", nor may "mod_log_mysql" or - "mod_log_sql" appear in their names, without prior written permission - of Christopher B. Powell. - -6. Redistributions of any form whatsoever must retain the following - acknowledgment: "This product includes software developed by - Christopher B. Powell for use in the - mod_log_mysql project (http://www.grubbybaby.com/mod_log_mysql/). - -THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESSED OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR -ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. + +Preamble + +The intent of this document is to state the conditions under which a +Package may be copied, such that the Copyright Holder maintains some +semblance of artistic control over the development of the package, +while giving the users of the package the right to use and distribute +the Package in a more-or-less customary fashion, plus the right to make +reasonable modifications. + + +Definitions: + +* "Package" refers to the collection of files distributed by the + Copyright Holder, and derivatives of that collection of files created + through textual modification. + +* "Standard Version" refers to such a Package if it has not been + modified, or has been modified in accordance with the wishes of the + Copyright Holder. + +* "Copyright Holder" is Christopher B. Powell, . + +* "You" is you, if you're thinking about copying or distributing this + Package. + +* "Reasonable copying fee" is whatever you can justify on the basis of + media cost, duplication charges, time of people involved, and so on. + (You will not be required to justify it to the Copyright Holder, but + only to the computing community at large as a market that must bear the + fee.) + +* "Freely Available" means that no fee is charged for the item itself, + though there may be fees involved in handling the item. It also means + that recipients of the item may redistribute it under the same + conditions they received it. + + +1. You may make and give away verbatim copies of the source form of the +Standard Version of this Package without restriction, provided that you +duplicate all of the original copyright notices and associated +disclaimers. + +2. You may apply bug fixes, portability fixes and other modifications +derived from the Public Domain or from the Copyright Holder. A Package +modified in such a way shall still be considered the Standard Version. + +3. You may otherwise modify your copy of this Package in any way, +provided that you insert a prominent notice in each changed file +stating how and when you changed that file, and provided that you do at +least ONE of the following: + + a) place your modifications in the Public Domain or otherwise make + them Freely Available, such as by posting said modifications to + Usenet or an equivalent medium, or placing the modifications on a + major archive site such as ftp.uu.net, or by allowing the + Copyright Holder to include your modifications in the Standard + Version of the Package. + + b) use the modified Package only within your corporation or + organization. + + c) rename any non-standard executables so the names do not + conflict with standard executables, which must also be provided, + and provide a separate manual page for each non-standard + executable that clearly documents how it differs from the Standard + Version. + + d) make other distribution arrangements with the Copyright Holder. + +4. You may distribute the programs of this Package in object code or +executable form, provided that you do at least ONE of the following: + + a) distribute a Standard Version of the executables and library + files, together with instructions (in the manual page or + equivalent) on where to get the Standard Version. + + b) accompany the distribution with the machine-readable source of + the Package with your modifications. + + c) accompany any non-standard executables with their corresponding + Standard Version executables, giving the non-standard executables + non-standard names, and clearly documenting the differences in + manual pages (or equivalent), together with instructions on where + to get the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +5. You may charge a reasonable copying fee for any distribution of this +Package. You may charge any fee you choose for support of this Package. +You may not charge a fee for this Package itself. However, you may +distribute this Package in aggregate with other (possibly commercial) +programs as part of a larger (possibly commercial) software +distribution provided that you do not advertise this Package as a +product of your own. + +6. The scripts and library files supplied as input to or produced as +output from the programs of this Package do not automatically fall +under the copyright of this Package, but belong to whomever generated +them, and may be sold commercially, and may be aggregated with this +Package. + +7. C or perl subroutines supplied by you and linked into this Package +shall not be considered part of this Package. + +8. The name of the Copyright Holder may not be used to endorse or +promote products derived from this software without specific prior +written permission. + +9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF +MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + +The End diff --git a/mod_log_sql.c b/mod_log_sql.c index ecdfcf0..db9b3a3 100644 --- a/mod_log_sql.c +++ b/mod_log_sql.c @@ -1,4 +1,4 @@ -/* $Id: mod_log_sql.c,v 1.14 2002/05/24 20:52:39 helios Exp $ */ +/* $Id: mod_log_sql.c,v 1.15 2002/06/27 20:09:17 helios Exp $ */ /* --------* * DEFINES * @@ -574,11 +574,13 @@ void preserve_entry(request_rec *r, const char *query) /* */ /* Parms: request record, SQL insert statement */ /* Returns: 0 (OK) on success */ -/* mysql return code on error */ +/* -1 if have no log handle */ +/* actual MySQL return code on error */ /*-----------------------------------------------------*/ int safe_mysql_query(request_rec *r, const char *query) { int retval; + unsigned int real_error; struct timespec delay, remainder; int ret; void (*handler) (int); @@ -591,19 +593,22 @@ int safe_mysql_query(request_rec *r, const char *query) if (mysql_log != NULL) retval = mysql_query(mysql_log, query); else - return 1; + return -1; /* If we ran the query and it returned an error, try to be graceful. * (The module thought it had a valid mysql_log connection but the query - * might have failed, so we have to check.) + * might have failed, so we have to be extra-safe and check.) */ if ( retval != 0 ) { log_sql_state *cls = get_module_config(r->server->module_config, &mysql_log_module); + + real_error = mysql_errno(mysql_log); /* 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: %s", MYSQL_ERROR(mysql_log)); - + 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(); @@ -630,7 +635,8 @@ int safe_mysql_query(request_rec *r, const char *query) /* If this one also failed, log that and append to our local offline file */ if ( retval != 0 ) { - ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: second attempt failed, API said: %s", MYSQL_ERROR(mysql_log)); + 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)); preserve_entry(r, query); ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: entry preserved in %s", cls->preserve_file); } else { @@ -658,7 +664,10 @@ const char *set_log_sql_massvirtual(cmd_parms *parms, void *dummy, int flag) const char *set_log_sql_create(cmd_parms *parms, void *dummy, int flag) { - create_tables = ( flag ? 1 : 0); + if (massvirtual != 0) + ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLCreateTables when LogSQLMassVirtualHosting is On. Ignoring."); + else + create_tables = ( flag ? 1 : 0); return NULL; } @@ -841,6 +850,9 @@ static void log_sql_child_init(server_rec *s, pool *p) int retval; retval = open_logdb_link(); + if (retval == 0) + 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"); @@ -1052,7 +1064,7 @@ int log_sql_transaction(request_rec *orig) char *create_notes = NULL; char *create_hout = NULL; char *create_hin = NULL; - int create_results_access, create_results_notes, create_results_hout, create_results_hin; + int create_results; for (r = orig; r->next; r = r->next) { continue; @@ -1266,10 +1278,10 @@ int log_sql_transaction(request_rec *orig) create_hin = ap_pstrcat(orig->pool, createprefix, cls->hin_table_name, headers_suffix, NULL); #ifdef DEBUG - ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"create string: %s", create_access); - ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"create string: %s", create_notes); - ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"create string: %s", create_hout); - ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"create string: %s", create_hin); + ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: create string: %s", create_access); + ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: create string: %s", create_notes); + ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: create string: %s", create_hout); + ap_log_error(APLOG_MARK,DEBUGLEVEL,orig->server,"mod_log_sql: create string: %s", create_hin); #endif } @@ -1278,7 +1290,7 @@ int log_sql_transaction(request_rec *orig) 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,"insert string: %s", access_query); + ap_log_error(APLOG_MARK,DEBUGLEVEL,r->server,"mod_log_sql: access string: %s", access_query); #endif @@ -1291,7 +1303,9 @@ int log_sql_transaction(request_rec *orig) 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. - * Note that we don't keep logging the db error over and over. */ + * This short-circuits safe_mysql_query during a db outage and therefore + * we don't keep logging the db error over and over. + */ preserve_entry(orig, access_query); if ( note_query != NULL ) preserve_entry(orig, note_query); @@ -1313,21 +1327,35 @@ int log_sql_transaction(request_rec *orig) /* Make the tables if we're supposed to. */ if ((cls->table_made != 1) && (create_tables != 0)) { - create_results_access = safe_mysql_query(orig, create_access); - create_results_notes = safe_mysql_query(orig, create_notes); - create_results_hin = safe_mysql_query(orig, create_hin); - create_results_hout = safe_mysql_query(orig, create_hout); + + /* Assume it will be made successfully...*/ + cls->table_made = 1; - if ( (create_results_access == 0) && (create_results_notes == 0) && (create_results_hin == 0) && (create_results_hout == 0) ) - cls->table_made = 1; - else - ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: failed to create all tables, see preserve file"); + if ((create_results = safe_mysql_query(orig, create_access)) != 0) { + cls->table_made = 0; + ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: failed to create access table, see preserve file"); + } + + if ((create_results = safe_mysql_query(orig, create_notes)) != 0) { + cls->table_made = 0; + ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: failed to create notes table, see preserve file"); + } + + if ((create_results = safe_mysql_query(orig, create_hin)) != 0) { + cls->table_made = 0; + ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: failed to create header_out table, see preserve file"); + } + + if ((create_results = safe_mysql_query(orig, create_hout)) != 0) { + cls->table_made = 0; + ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: failed to create header_in table, see preserve file"); + } } /* Make the access-table insert */ safe_mysql_query(orig, access_query); - /* If notes are available to log, make the notes-table insert */ + /* Log the optional notes, headers, etc. */ if ( note_query != NULL ) safe_mysql_query(orig, note_query); -- cgit