From 478975f1c8767c7ae2abb284ecda41185df32f11 Mon Sep 17 00:00:00 2001 From: Christopher Powell Date: Tue, 10 Dec 2002 19:43:21 +0000 Subject: Changes on route to 1.18 release (better table creation logic and workarounds for delayed insert kluge). --- diff --git a/CHANGELOG b/CHANGELOG index f18509c..66151e7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -$Id: CHANGELOG,v 1.17 2002/11/14 22:52:53 helios Exp $ +$Id: CHANGELOG,v 1.18 2002/12/10 19:43:21 helios Exp $ TODO: * Rethink documentation flow and rewrite? @@ -15,11 +15,28 @@ TODO: * socket-based middleman daemon with configurable conns? * ignore by cookie - CHANGES: -1.17: +1.18: +* Delayed inserts (a MySQL extension) are now available at compile-time. + THIS IS UGLY because there seems to be a bug in the way MySQL returns + errors on failed INSERT DELAYED queries. See the FAQ. +* Reworked the Makefile a tad. +* Added stdlib.h to the includes, some systems need it for atoi(). Added + string.h to the includes just to be safe. +* Reworked table creation (again). Inserts are attempted and tables + are made only on ER_NO_SUCH_TABLE. This should solve all the multiple- + creation-attempt issues as well as reduce overhead. +* safe_mysql_query reworked; it now can be counted on to preserve_entry() + if the query doesn't succeed. (Before, preserve_entry() was called + separately.) +* Always return SIGPIPE to handler before leaving safe_mysql_query(). +* New directive LogSQLRequestAccept, another filter for excluding things + from being logged. +* Alphabetized the directives in the reference section of the docs. +* Reorganized the FAQ by section. +1.17: * Renamed the module mod_log_sql to conform to the project goal of database-inspecificity. * Added capability of logging Notes field. This is useful for folks using diff --git a/Documentation/documentation.lyx b/Documentation/documentation.lyx index 50fceba..69f09ae 100644 --- a/Documentation/documentation.lyx +++ b/Documentation/documentation.lyx @@ -1254,8 +1254,7 @@ which logs all the information required to be compatible with the Combined \layout Standard If you don't choose to log everything that is available, that's fine. - The unused columns in your table will have simply contain NULL and do not - cause issues. + Fields in the unused columns in your table will simply contain NULL. \layout Standard Some of the @@ -1297,10 +1296,18 @@ LogSQLMachineID \end_inset -Instructing the module what NOT to log +Instructing the module what NOT to log using filtering directives \layout Standard -Two +One +\begin_inset Quotes eld +\end_inset + +accept +\begin_inset Quotes erd +\end_inset + + and two \begin_inset Quotes eld \end_inset @@ -1308,12 +1315,59 @@ ignore \begin_inset Quotes srd \end_inset - directives allow you to specify things that the module should not log. + directives allow you to fine-tune what the module should not log. These are very handy for keeping your database as uncluttered as possible and keeping your statistics free of unneeded numbers. + Think of each one as a gatekeeper. \layout Standard -You are able to tell the module what to exclude based on + +\emph on +It is important to remember that each of these three directives is purely + optional. + mod_log_sql's default is to log everything. + +\layout Standard + +When a request comes in, the contents of +\noun on +LogSQLRequestAccept +\noun default +are evaluated first. + This optional, +\begin_inset Quotes eld +\end_inset + +blanket +\begin_inset Quotes erd +\end_inset + + directive lets you specify that only certain things are to be accepted + for logging, and everything else discarded. + Because it is evaluated before +\noun on +LogSQLRequestIgnore +\noun default +and +\noun on +LogSQLRemhostIgnore +\noun default +it can halt logging before those two filtering directives +\begin_inset Quotes eld +\end_inset + +get their chance. +\begin_inset Quotes erd +\end_inset + + +\layout Standard + +Once a request makes it past +\noun on +LogSQLRequestAccept +\noun default +, it still can be excluded based on \noun on LogSQLRemhostIgnore \noun default @@ -1348,7 +1402,7 @@ You can specify a series of strings after each directive. Do not use any type of globbing or regular-expression syntax -- each string is considered a match \emph on - if it is a substring of the larger request or remote-host, and the comarison + if it is a substring of the larger request or remote-host; the comarison is case-sensitive. \emph default @@ -1441,7 +1495,81 @@ Tree.Gif \begin_inset Quotes erd \end_inset - would still get logged. + would still get logged because of case sensitivity. +\layout Standard + +A summary of the decision flow: +\layout Enumerate + +If +\noun on +LogSQLRequestAccept +\noun default + exists and a request does not match anything in that list, it is discarded. +\layout Enumerate + +If a request matches anything in the +\noun on +LogSQLRequestIgnore +\noun default +list, it is discarded. +\layout Enumerate + +If a reqiest matches anything in the +\noun on +LogSQLRemhostIgnore +\noun default + list, it is discarded. +\layout Enumerate + +Otherwise the request is logged. +\layout Standard + +This means that you can have a series of directives similar to the following: +\layout LyX-Code + +LogSQLRequestAccept *.html *.gif *.jpg +\layout LyX-Code + +LogSQLRequestIgnore statistics.html bluedot.jpg +\layout Standard + +So the first line instructs the module to +\series bold +only +\series default + log files with html, gif and jpg suffixes; requests for +\begin_inset Quotes eld +\end_inset + +formail.cgi +\begin_inset Quotes erd +\end_inset + + and +\begin_inset Quotes eld +\end_inset + +shopping-cart.pl +\begin_inset Quotes erd +\end_inset + + will never be considered for logging. + ( +\begin_inset Quotes eld +\end_inset + +LeftArrow.JPG +\begin_inset Quotes erd +\end_inset + + will also never be considered for logging -- remember, the comparison is + +\series bold +case sensitive +\series default +.) The second line prunes the list further -- you never want to log requests + for those two objects. \layout Standard Tip: if you want to match all the hosts in your domain such as @@ -1620,83 +1748,6 @@ LogSQLTransferLogFormat machine and thereby analyze the front-end loadbalancing algorithm. \layout Subsubsection -Using the same database for production and test -\layout Standard - -Although suboptimal, it is not uncommon to use the same backend database - for the -\begin_inset Quotes eld -\end_inset - -production -\begin_inset Quotes erd -\end_inset - - webservers as well as the -\begin_inset Quotes eld -\end_inset - -test -\begin_inset Quotes erd -\end_inset - - webservers (budgetary constraints, rackspace limits, etc.). - Furthermore, an administrator in this situation may be unable to use -\noun on -LogSQLRemhostIgnore -\noun default -to exclude requests from the test servers -- perhaps the generated entries - are genuinely useful for analytical or QA purposes, but their value after - analysis is minimal. -\layout Standard - -It is wasteful and potentially confusing to permit this internal test data - to clutter the database, and a solution to the problem is the proper use - of the -\noun on -LogSQLMachineID -\noun default -directive. - Assume a scenario where the production webservers have IDs like -\begin_inset Quotes eld -\end_inset - -web01, -\begin_inset Quotes erd -\end_inset - - -\begin_inset Quotes eld -\end_inset - -web02, -\begin_inset Quotes erd -\end_inset - - and so on -- and the test webservers have IDs like -\begin_inset Quotes eld -\end_inset - -test01, -\begin_inset Quotes erd -\end_inset - - -\begin_inset Quotes eld -\end_inset - -test02, -\begin_inset Quotes erd -\end_inset - - etc. - Because entries in the log database are distinguished by their source machine, - an administrator may purge unneeded test data from the access log as follows: -\layout LyX-Code - -delete from access_log where machine_id like 'test%'; -\layout Subsubsection - \begin_inset LatexCommand \label{secMulTable} @@ -2399,13 +2450,95 @@ LogSQLTransferLogTable.) \layout Subsubsection +Using the same database for production and test +\layout Standard + +Although suboptimal, it is not uncommon to use the same backend database + for the +\begin_inset Quotes eld +\end_inset + +production +\begin_inset Quotes erd +\end_inset + + webservers as well as the +\begin_inset Quotes eld +\end_inset + +test +\begin_inset Quotes erd +\end_inset + + webservers (budgetary constraints, rackspace limits, etc.). + Furthermore, an administrator in this situation may be unable to use +\noun on +LogSQLRemhostIgnore +\noun default +to exclude requests from the test servers -- perhaps the generated entries + are genuinely useful for analytical or QA purposes, but their value after + analysis is minimal. +\layout Standard + +It is wasteful and potentially confusing to permit this internal test data + to clutter the database, and a solution to the problem is the proper use + of the +\noun on +LogSQLMachineID +\noun default +directive. + Assume a scenario where the production webservers have IDs like +\begin_inset Quotes eld +\end_inset + +web01, +\begin_inset Quotes erd +\end_inset + + +\begin_inset Quotes eld +\end_inset + +web02, +\begin_inset Quotes erd +\end_inset + + and so on -- and the test webservers have IDs like +\begin_inset Quotes eld +\end_inset + +test01, +\begin_inset Quotes erd +\end_inset + + +\begin_inset Quotes eld +\end_inset + +test02, +\begin_inset Quotes erd +\end_inset + + etc. + Because entries in the log database are distinguished by their source machine, + an administrator may purge unneeded test data from the access log as follows: +\layout LyX-Code + +delete from access_log where machine_id like 'test%'; +\layout Subsubsection + + +\begin_inset LatexCommand \label{sub:DelayedIns} + +\end_inset + Optimizing for a busy database \layout Standard A busy MySQL database will have SELECT statements running concurrently with INSERT and UPDATE statements. A long-running SELECT can block INSERTs, therefore will block mod_log_sql. - This can be solved by compiling mod_log_sql for + This may be solved by compiling mod_log_sql for \begin_inset Quotes eld \end_inset @@ -2454,6 +2587,8 @@ There is additional overhead for the server to handle a separate thread for each table on which you use INSERT DELAYED. \layout Standard + +\series bold The MySQL documentation concludes, \begin_inset Quotes eld \end_inset @@ -2463,7 +2598,15 @@ This means that you should only use INSERT DELAYED when you are really sure \begin_inset Quotes erd \end_inset + Furthermore, the current state of error return from a failed INSERT DELAYED + seems to be in flux, and may behave in unpredictable ways between different + MySQL versions. + See section +\begin_inset LatexCommand \ref{sub:DelayedInsFAQ} + +\end_inset + in the FAQ -- you have been warned. \layout Standard If you are experiencing issues which could be solved by delayed inserts, @@ -2499,246 +2642,297 @@ context listed with each entry informs you of this. \layout Subsubsection -LogSQLDatabase +LogSQLCookieLogTable \layout LyX-Code - -\series bold -MANDATORY +Syntax: LogSQLCookieLogTable table-name \layout LyX-Code -Syntax: LogSQLDatabase database +Example: LogSQLCookieLogTable cookie_log \layout LyX-Code -Example: LogSQLDatabase loggingdb +Default: cookies \layout LyX-Code -Context: main server config -\layout Quote +Context: virtual host +\layout Standard -Defines the database that is used for logging. - +Defines which table is used for logging of cookies. + Working in conjunction with +\noun on +LogSQLWhichCookies +\noun default +, you can log many of each request's associated cookies to a separate table. + For meaningful data retrieval the cookie table is keyed to the access table + by the unique request ID supplied by the standard Apache module mod_unique_id. +\layout Standard + +Note that you must create the table (see create-tables.sql, included in the + package), or +\noun on +LogSQLCreateTables +\noun default + must be set to \begin_inset Quotes eld \end_inset -database +on \begin_inset Quotes erd \end_inset - must be a valid db on the MySQL host defined in +. +\layout Subsubsection + +LogSQLCreateTables +\layout LyX-Code + +Syntax: LogSQLCreateTables flag +\layout LyX-Code + +Example: LogSQLCreateTables On +\layout LyX-Code + +Default: Off +\layout LyX-Code + +Context: main server config +\layout Standard + +mod_log_sql has the ability to create its tables on-the-fly. + The advantage to this is convenience: you don't have to execute any SQL + by hand to prepare the table. + This is especially helpful for people with lots of virtual hosts (who should + also see the +\noun on +LogSQLMassVirtualHosting +\noun default + directive). +\layout Standard + +There is a slight disadvantage: if you wish to activate this feature, then + the userid specified in \noun on LogSQLLoginInfo \noun default + must have CREATE privileges on the database. + In an absolutely paranoid, locked-down situation you may only want to grant + your mod_log_sql user INSERT privileges on the database; in that situation + you are unable to take advantage of +\noun on +LogSQLCreateTables +\noun default . - -\layout Quote + But most people -- even the very security-conscious -- will find that granting + CREATE on the logging database is reasonable. +\layout Standard This is defined only once in the httpd.conf file. \layout Subsubsection -LogSQLLoginInfo +LogSQLDatabase \layout LyX-Code \series bold MANDATORY -\series default - \layout LyX-Code -Syntax: LogSQLLoginInfo host user password +Syntax: LogSQLDatabase database \layout LyX-Code -Example: LogSQLLoginInfo foobar.baz.com logwriter passw0rd +Example: LogSQLDatabase loggingdb \layout LyX-Code Context: main server config -\layout Quote - -Defines the general parameters of the MySQL host to which you will be logging. - -\begin_inset Quotes eld -\end_inset - -host -\begin_inset Quotes erd -\end_inset +\layout Standard - is the hostname or IP address of the MySQL machine. +Defines the database that is used for logging. \begin_inset Quotes eld \end_inset -user +database \begin_inset Quotes erd \end_inset - is the MySQL userid (not a Unix userid!) with INSERT privileges on the - table defined in + must be a valid db on the MySQL host defined in \noun on -LogSQLTransferLogTable +LogSQLLoginInfo \noun default . -\begin_inset Quotes eld -\end_inset - -password -\begin_inset Quotes erd -\end_inset - - is that user's password. - -\layout Quote +\layout Standard This is defined only once in the httpd.conf file. \layout Subsubsection -LogSQLTCPPort +LogSQLForcePreserve \layout LyX-Code -Syntax: LogSQLTCPPort portnumber +Syntax: LogSQLForcePreserve Flag \layout LyX-Code -Example: LogSQLTCPPort 3309 +Example: LogSQLPreserveFile on \layout LyX-Code -Default: 3306 +Default: off \layout LyX-Code Context: main server config -\layout Quote +\layout Standard -Your database may listen on a different port than the default. - If so, use this directive to instruct the module which port to use. - This directive only applies if the database is on a different machine connected - via TCP/IP. -\layout Quote +You may need to perform debugging on your database and specifically want + mod_log_sql to make no attempts to log to it. + This directive instructs the module to send all its log entries directly + to the preserve file and to make no database INSERT attempts. +\layout Standard + +This is presumably a directive for temporary use only; it could be dangerous + if you set it and forget it, as all your entries will simply pile up in + the preserve file. +\layout Standard This is defined only once in the httpd.conf file. \layout Subsubsection -LogSQLSocketFile +LogSQLHeadersInLogTable \layout LyX-Code -Syntax: LogSQLSocketFile filename +Syntax: LogSQLHeadersInLogTable table-name \layout LyX-Code -Example: LogSQLSocketFile /tmp/mysql.sock +Example: LogSQLHeadersInLogTable headers \layout LyX-Code -Default: /var/lib/mysql/mysql.sock +Default: headers_in \layout LyX-Code -Context: main server config -\layout Quote +Context: virtual host +\layout Standard -At Apache runtime you can specify the MySQL socket file to use. - Set this once in your main server config to override the default value. - This value is irrelevant if your database resides on a separate machine. -\layout Quote +Defines which table is used for logging of inbound headers. + Working in conjunction with +\noun on +LogSQLWhichHeadersIn +\noun default +, you can log many of each request's associated headers to a separate table. + For meaningful data retrieval the headers table is keyed to the access + table by the unique request ID supplied by the standard Apache module mod_uniqu +e_id. +\layout Standard -mod_log_sql will automatically employ the socket for db communications if - the database resides on the local host. - If the db resides on a separate host the module will automatically use - TCP/IP. - This is a function of the MySQL API and is not user-configurable. -\layout Quote +Note that you must create the table (see create-tables.sql, included in the + package), or +\noun on +LogSQLCreateTables +\noun default + must be set to +\begin_inset Quotes eld +\end_inset -This is defined only once in the httpd.conf file. +on +\begin_inset Quotes erd +\end_inset + +. \layout Subsubsection -LogSQLPreserveFile +LogSQLHeadersOutLogTable \layout LyX-Code -Syntax: LogSQLPreserveFile filename +Syntax: LogSQLHeadersOutLogTable table-name \layout LyX-Code -Example: LogSQLPreserveFile offline-preserve +Example: LogSQLHeadersOutLogTable headers \layout LyX-Code -Default: /tmp/sql-preserve +Default: headers_out \layout LyX-Code Context: virtual host -\layout Quote - -mod_log_sql writes queries to this local preserve file in the event that - it cannot reach the database, and thus ensures that your high-availability - web frontend does not lose logs during a temporary database outage. - This could happen for a number of reasons: the database goes offline, the - network breaks, etc. - You will not lose entries since the module has this backup. - The file consists of a series of SQL statements that can be imported into - your database at your convenience; furthermore, because the SQL queries - contain the access timestamps you do not need to worry about out-of-order - data after the import, which is done in a simple manner: -\layout LyX-Code - -# mysql -uadminuser -p mydbname < /tmp/sql-preserve -\layout Quote +\layout Standard -If you do not define -\noun on -LogSQLPreserveFile -\noun default - then all virtual servers will log to the same default preserve file (/tmp/sql-p -reserve). - You can redefine this on a virtual-host basis in order to segregate your - preserve files if you desire. - Note that segregation is not usually necessary, as the SQL statements that - are written to the preserve file already distinguish between different - virtual hosts if you include the 'v' character in your +Defines which table is used for logging of outbound headers. + Working in conjunction with \noun on -LogSQLTransferLogFormat +LogSQLWhichHeadersOut \noun default - directive. - It is only necessary to segregate preserve-files by virualhost if you also - segregate access logs by virtualhost. -\layout Quote +, you can log many of each request's associated headers to a separate table. + For meaningful data retrieval the headers table is keyed to the access + table by the unique request ID supplied by the standard Apache module mod_uniqu +e_id. +\layout Standard -The module will log to Apache's +Note that you must create the table (see create-tables.sql, included in the + package), or \noun on -ErrorLog +LogSQLCreateTables \noun default - when it notices a database outage, and upon database return. - You will therefore know when the preserve file is being used, although - it is your responsibility to import the file. -\layout Quote + must be set to +\begin_inset Quotes eld +\end_inset -The file does not need to be created in advance. - It is safe to remove or rename the file without interrupting Apache, as - the module closes the filehandle immediately after completing the write. - The file is created with the user & group ID of the running Apache process - (e.g. - 'nobody' on many Linux distributions). +on +\begin_inset Quotes erd +\end_inset + +. \layout Subsubsection -LogSQLForcePreserve +LogSQLLoginInfo \layout LyX-Code -Syntax: LogSQLForcePreserve Flag + +\series bold +MANDATORY +\series default + \layout LyX-Code -Example: LogSQLPreserveFile on +Syntax: LogSQLLoginInfo host user password \layout LyX-Code -Default: off +Example: LogSQLLoginInfo foobar.baz.com logwriter passw0rd \layout LyX-Code Context: main server config -\layout Quote +\layout Standard -You may need to perform debugging on your database and specifically want - mod_log_sql to make no attempts to log to it. - This directive instructs the module to send all its log entries directly - to the preserve file and to make no database INSERT attempts. -\layout Quote +Defines the general parameters of the MySQL host to which you will be logging. + +\begin_inset Quotes eld +\end_inset -This is presumably a directive for temporary use only; it could be dangerous - if you set it and forget it, as all your entries will simply pile up in - the preserve file. -\layout Quote +host +\begin_inset Quotes erd +\end_inset + + is the hostname or IP address of the MySQL machine. + +\begin_inset Quotes eld +\end_inset + +user +\begin_inset Quotes erd +\end_inset + + is the MySQL userid (not a Unix userid!) with INSERT privileges on the + table defined in +\noun on +LogSQLTransferLogTable +\noun default +. + +\begin_inset Quotes eld +\end_inset + +password +\begin_inset Quotes erd +\end_inset + + is that user's password. + +\layout Standard This is defined only once in the httpd.conf file. \layout Subsubsection @@ -2753,7 +2947,7 @@ Example: LogSQLMachineID web01 \layout LyX-Code Context: main server config -\layout Quote +\layout Standard If you have a farm of webservers then you may wish to know which particular machine made each entry; this is useful for analyzing your loadbalancing @@ -2792,53 +2986,7 @@ LogSQLMachineID \end_inset etc. -\layout Quote - -This is defined only once in the httpd.conf file. -\layout Subsubsection - -LogSQLCreateTables -\layout LyX-Code - -Syntax: LogSQLCreateTables flag -\layout LyX-Code - -Example: LogSQLCreateTables On -\layout LyX-Code - -Default: Off -\layout LyX-Code - -Context: main server config -\layout Quote - -mod_log_sql has the ability to create its tables on-the-fly. - The advantage to this is convenience: you don't have to execute any SQL - by hand to prepare the table. - This is especially helpful for people with lots of virtual hosts (who should - also see the -\noun on -LogSQLMassVirtualHosting -\noun default - directive). -\layout Quote - -There is a slight disadvantage: if you wish to activate this feature, then - the userid specified in -\noun on -LogSQLLoginInfo -\noun default - must have CREATE privileges on the database. - In an absolutely paranoid, locked-down situation you may only want to grant - your mod_log_sql user INSERT privileges on the database; in that situation - you are unable to take advantage of -\noun on -LogSQLCreateTables -\noun default -. - But most people -- even the very security-conscious -- will find that granting - CREATE on the logging database is reasonable. -\layout Quote +\layout Standard This is defined only once in the httpd.conf file. \layout Subsubsection @@ -2856,7 +3004,7 @@ Default: Off \layout LyX-Code Context: main server config -\layout Quote +\layout Standard If you administer a site hosting many, many virtual hosts then this option will appeal to you. @@ -2865,7 +3013,6 @@ If you administer a site hosting many, many virtual hosts then this option LogSQLMassVirtualHosting \noun default then several things happen: -\begin_deeper \layout Itemize the on-the-fly table creation feature is activated automatically @@ -2881,8 +3028,7 @@ which, in turn, means that each virtual host logs to its own segregated Because there is no data shared between virtual servers you can grant your users access to the tables they need; they will be unable to view others' data. -\end_deeper -\layout Quote +\layout Standard This is a huge boost in convenience for sites with many virtual servers. Activating @@ -2891,64 +3037,239 @@ LogSQLMassVirtualHosting \noun default obviates the need to create every virtual server's table and provides more granular security possibilities. -\layout Quote +\layout Standard + +You are advised to investigate the use of Apache's +\noun on +UseCanonicalName On +\noun default +directive with this directive in order to ensure that each virtual host + maps to one table namespace. +\layout Standard This is defined only once in the httpd.conf file. + \layout Subsubsection -LogSQLTransferLogTable +LogSQLNotesLogTable +\layout LyX-Code + +Syntax: LogSQLNotesLogTable table-name \layout LyX-Code +Example: LogSQLNotesLogTable notes_log +\layout LyX-Code -\series bold -MANDATORY (unless +Default: notes +\layout LyX-Code + +Context: virtual host +\layout Standard + +Defines which table is used for logging of notes. + Working in conjunction with \noun on -LogSQLMassVirtualHosting +LogSQLWhichNotes \noun default - is -\begin_inset Quotes eld -\end_inset +, you can log many of each request's associated notes to a separate table. + For meaningful data retrieval the notes table is keyed to the access table + by the unique request ID supplied by the standard Apache module mod_unique_id. +\layout Standard -on -\begin_inset Quotes erd -\end_inset +Note that you must create the table (see create-tables.sql, included in the + package), or +\noun on +LogSQLCreateTables +\noun default + must be set to ``on''. + +\layout Subsubsection -) +LogSQLPreserveFile \layout LyX-Code -Syntax: LogSQLTransferLogTable table-name +Syntax: LogSQLPreserveFile filename \layout LyX-Code -Example: LogSQLTransferLogTable access_log_table +Example: LogSQLPreserveFile offline-preserve +\layout LyX-Code + +Default: /tmp/sql-preserve \layout LyX-Code Context: virtual host -\layout Quote +\layout Standard -Defines which table is used for logging of Apache's transfers; this is analogous - to Apache's TransferLog directive. - table-name must be a valid table within the database defined in +mod_log_sql writes queries to this local preserve file in the event that + it cannot reach the database, and thus ensures that your high-availability + web frontend does not lose logs during a temporary database outage. + This could happen for a number of reasons: the database goes offline, the + network breaks, etc. + You will not lose entries since the module has this backup. + The file consists of a series of SQL statements that can be imported into + your database at your convenience; furthermore, because the SQL queries + contain the access timestamps you do not need to worry about out-of-order + data after the import, which is done in a simple manner: +\layout LyX-Code + +# mysql -uadminuser -p mydbname < /tmp/sql-preserve +\layout Standard + +If you do not define \noun on -LogSQLDatabase +LogSQLPreserveFile \noun default -. -\layout Quote + then all virtual servers will log to the same default preserve file (/tmp/sql-p +reserve). + You can redefine this on a virtual-host basis in order to segregate your + preserve files if you desire. + Note that segregation is not usually necessary, as the SQL statements that + are written to the preserve file already distinguish between different + virtual hosts if you include the 'v' character in your +\noun on +LogSQLTransferLogFormat +\noun default + directive. + It is only necessary to segregate preserve-files by virualhost if you also + segregate access logs by virtualhost. +\layout Standard -This directive is not necessary if you declare +The module will log to Apache's \noun on -LogSQLMassVirtualHosting On +ErrorLog \noun default -, since that directive activates dynamically-named tables. - If you attempt to use + when it notices a database outage, and upon database return. + You will therefore know when the preserve file is being used, although + it is your responsibility to import the file. +\layout Standard + +The file does not need to be created in advance. + It is safe to remove or rename the file without interrupting Apache, as + the module closes the filehandle immediately after completing the write. + The file is created with the user & group ID of the running Apache process + (e.g. + 'nobody' on many Linux distributions). +\layout Subsubsection + +LogSQLRemhostIgnore +\layout LyX-Code + +Syntax: LogSQLRemhostIgnore host1 host2 host3 ... + hostN +\layout LyX-Code + +Example: LogSQLRemhostIgnore localnet.com +\layout LyX-Code + +Context: virtual host +\layout Standard + +Lists a series of strings that, if present in the REMOTE_HOST, will cause + that request to +\series bold +not +\series default + be logged. + This directive is useful for cutting down on log clutter when you are certain + that you want to ignore requests from certain hosts, such as your own internal + network machines. + See section +\begin_inset LatexCommand \ref{sub:Ignore} + +\end_inset + + for some tips for using this directive. +\layout Standard + +Each string is separated by a space, and no regular expressions or globbing + are allowed. + Each string is evaluated as a substring of the REMOTE_HOST using strstr(). + The comparison is case sensitive. +\layout Subsubsection + +LogSQLRequestAccept +\layout LyX-Code + +Syntax: LogSQLRequestAccept req1 req2 req3 ... + reqN +\layout LyX-Code + +Example: LogSQLRequestAccept .html .php .jpg +\layout LyX-Code + +Default: if not specified, all requests are +\begin_inset Quotes eld +\end_inset + +accepted +\begin_inset Quotes erd +\end_inset + + +\layout LyX-Code + +Context: virtual host +\layout Standard + +Lists a series of strings that, if present in the URI, will permit that + request to be +\series bold + +\series default +considered for logging (depending on additional filtering by the +\begin_inset Quotes eld +\end_inset + +ignore +\begin_inset Quotes erd +\end_inset + + directives). + Any request that fails to match one of the \noun on -LogSQLTransferLogTable +LogSQLRequestAccept \noun default - at the same time a warning will be logged and it will be ignored, since +entries will be discarded. +\layout Standard + +This directive is useful for cutting down on log clutter when you are certain + that you only want to log certain kinds of requests, and just blanket-ignore + everything else. + See section +\begin_inset LatexCommand \ref{sub:Ignore} + +\end_inset + + for some tips for using this directive. +\layout Standard + +Each string is separated by a space, and no regular expressions or globbing + are allowed. + Each string is evaluated as a substring of the URI using strstr(). + The comparison is case sensitive. +\layout Standard + +This directive is completely optional. + It is more general than +\noun on +LogSQLRequestIgnore +\noun default +and +\noun on +\noun default +is evaluated before \noun on -LogSQLMassVirtualHosting + LogSQLRequestIgnore \noun default - takes priority. +. + If this directive is not used, +\series bold +all +\series default + requests are accepted and passed on to the other filtering directives. + Therefore, only use this directive if you have a specific reason to do + so. \layout Subsubsection LogSQLRequestIgnore @@ -2962,7 +3283,7 @@ Example: LogSQLRequestIgnore root.exe cmd.exe default.ida favicon.ico \layout LyX-Code Context: virtual host -\layout Quote +\layout Standard Lists a series of strings that, if present in the URI, will cause that request to @@ -2982,7 +3303,7 @@ logged. \end_inset for some tips for using this directive. -\layout Quote +\layout Standard Each string is separated by a space, and no regular expressions or globbing are allowed. @@ -2990,40 +3311,58 @@ Each string is separated by a space, and no regular expressions or globbing The comparison is case sensitive. \layout Subsubsection -LogSQLRemhostIgnore +LogSQLSocketFile \layout LyX-Code -Syntax: LogSQLRemhostIgnore host1 host2 host3 ... - hostN +Syntax: LogSQLSocketFile filename \layout LyX-Code -Example: LogSQLRemhostIgnore localnet.com +Example: LogSQLSocketFile /tmp/mysql.sock \layout LyX-Code -Context: virtual host -\layout Quote +Default: /var/lib/mysql/mysql.sock +\layout LyX-Code -Lists a series of strings that, if present in the REMOTE_HOST, will cause - that request to -\series bold -NOT -\series default - be logged. - This directive is useful for cutting down on log clutter when you are certain - that you want to ignore requests from certain hosts, such as your own internal - network machines. - See section -\begin_inset LatexCommand \ref{sub:Ignore} +Context: main server config +\layout Standard -\end_inset +At Apache runtime you can specify the MySQL socket file to use. + Set this once in your main server config to override the default value. + This value is irrelevant if your database resides on a separate machine. +\layout Standard - for some tips for using this directive. -\layout Quote +mod_log_sql will automatically employ the socket for db communications if + the database resides on the local host. + If the db resides on a separate host the module will automatically use + TCP/IP. + This is a function of the MySQL API and is not user-configurable. +\layout Standard -Each string is separated by a space, and no regular expressions or globbing - are allowed. - Each string is evaluated as a substring of the REMOTE_HOST using strstr(). - The comparison is case sensitive. +This is defined only once in the httpd.conf file. +\layout Subsubsection + +LogSQLTCPPort +\layout LyX-Code + +Syntax: LogSQLTCPPort portnumber +\layout LyX-Code + +Example: LogSQLTCPPort 3309 +\layout LyX-Code + +Default: 3306 +\layout LyX-Code + +Context: main server config +\layout Standard + +Your database may listen on a different port than the default. + If so, use this directive to instruct the module which port to use. + This directive only applies if the database is on a different machine connected + via TCP/IP. +\layout Standard + +This is defined only once in the httpd.conf file. \layout Subsubsection @@ -3044,7 +3383,7 @@ Default: AbHhmRSsTUuv \layout LyX-Code Context: virtual host -\layout Quote +\layout Standard Each character in the format-string defines an attribute of the request that you wish to log. @@ -4193,7 +4532,7 @@ for this to take effect. LogSQLMachineID \noun default for this to take effect. -\layout Quote +\layout Standard If you have compiled mod_log_sql with SSL logging capability, you also can use these: @@ -4390,6 +4729,61 @@ smallint unsigned \layout Subsubsection +LogSQLTransferLogTable +\layout LyX-Code + + +\series bold +MANDATORY (unless +\noun on +LogSQLMassVirtualHosting +\noun default + is +\begin_inset Quotes eld +\end_inset + +on +\begin_inset Quotes erd +\end_inset + +) +\layout LyX-Code + +Syntax: LogSQLTransferLogTable table-name +\layout LyX-Code + +Example: LogSQLTransferLogTable access_log_table +\layout LyX-Code + +Context: virtual host +\layout Standard + +Defines which table is used for logging of Apache's transfers; this is analogous + to Apache's TransferLog directive. + table-name must be a valid table within the database defined in +\noun on +LogSQLDatabase +\noun default +. +\layout Standard + +This directive is not necessary if you declare +\noun on +LogSQLMassVirtualHosting On +\noun default +, since that directive activates dynamically-named tables. + If you attempt to use +\noun on +LogSQLTransferLogTable +\noun default + at the same time a warning will be logged and it will be ignored, since + +\noun on +LogSQLMassVirtualHosting +\noun default + takes priority. +\layout Subsubsection + LogSQLWhichCookie \layout LyX-Code @@ -4403,12 +4797,12 @@ Default: None \layout LyX-Code Context: virtual host -\layout Quote +\layout Standard In HTTP, cookies have names to distinguish them from each other. Using mod_usertrack, for example, you can give your user-tracking cookies a name with the CookieName directive. -\layout Quote +\layout Standard You must include a 'c' character in \noun on @@ -4421,7 +4815,7 @@ LogSQLWhichCookie tells mod_log_sql which cookie to log. This is necessary because you will usually be setting and receiving more than one cookie from a client; this cookie designates which one to log. -\layout Quote +\layout Standard Note: although this was intended for people who are using mod_usertrack to set user-tracking cookies, you aren't restricted in any way. @@ -4444,7 +4838,7 @@ Default: None \layout LyX-Code Context: virtual host -\layout Quote +\layout Standard Defines the list of cookies you would like logged. This works in conjunction with @@ -4460,7 +4854,7 @@ LogSQLTransferLogFormat string. The feature is activated simply by including this directive, upon which you will begin populating the separate cookie table with data. -\layout Quote +\layout Standard Note that you must have already created the table (see create-tables.sql, included in the package), or @@ -4492,7 +4886,7 @@ Default: None \layout LyX-Code Context: virtual host -\layout Quote +\layout Standard Defines the list of inbound headers you would like logged. This works in conjunction with @@ -4508,7 +4902,7 @@ LogSQLTransferLogFormat string. The feature is activated simply by including this directive, upon which you will begin populating the separate inbound-headers table with data. -\layout Quote +\layout Standard Note that you must have already created the table (see create-tables.sql, included in the package), or @@ -4540,7 +4934,7 @@ Default: None \layout LyX-Code Context: virtual host -\layout Quote +\layout Standard Defines the list of outbound headers you would like logged. This works in conjunction with @@ -4556,7 +4950,7 @@ LogSQLTransferLogFormat string. The feature is activated simply by including this directive, upon which you will begin populating the separate outbound-headers table with data. -\layout Quote +\layout Standard Note that you must have already created the table (see create-tables.sql, included in the package), or @@ -4588,7 +4982,7 @@ Default: None \layout LyX-Code Context: virtual host -\layout Quote +\layout Standard Defines the list of notes you would like logged. This works in conjunction with @@ -4604,7 +4998,7 @@ LogSQLTransferLogFormat string. The feature is activated simply by including this directive, upon which you will begin populating the separate notes table with data. -\layout Quote +\layout Standard Note that you must have already created the table (see create-tables.sql, included in the package), or @@ -4620,177 +5014,14 @@ on \end_inset . -\layout Subsubsection - -LogSQLCookieLogTable -\layout LyX-Code - -Syntax: LogSQLCookieLogTable table-name -\layout LyX-Code - -Example: LogSQLCookieLogTable cookie_log -\layout LyX-Code - -Default: cookies -\layout LyX-Code - -Context: virtual host -\layout Quote - -Defines which table is used for logging of cookies. - Working in conjunction with -\noun on -LogSQLWhichCookies -\noun default -, you can log many of each request's associated cookies to a separate table. - For meaningful data retrieval the cookie table is keyed to the access table - by the unique request ID supplied by the standard Apache module mod_unique_id. -\layout Quote - -Note that you must create the table (see create-tables.sql, included in the - package), or -\noun on -LogSQLCreateTables -\noun default - must be set to -\begin_inset Quotes eld -\end_inset - -on -\begin_inset Quotes erd -\end_inset - -. -\layout Subsubsection - -LogSQLHeadersInLogTable -\layout LyX-Code - -Syntax: LogSQLHeadersInLogTable table-name -\layout LyX-Code - -Example: LogSQLHeadersInLogTable headers -\layout LyX-Code - -Default: headers_in -\layout LyX-Code - -Context: virtual host -\layout Quote - -Defines which table is used for logging of inbound headers. - Working in conjunction with -\noun on -LogSQLWhichHeadersIn -\noun default -, you can log many of each request's associated headers to a separate table. - For meaningful data retrieval the headers table is keyed to the access - table by the unique request ID supplied by the standard Apache module mod_uniqu -e_id. -\layout Quote - -Note that you must create the table (see create-tables.sql, included in the - package), or -\noun on -LogSQLCreateTables -\noun default - must be set to -\begin_inset Quotes eld -\end_inset - -on -\begin_inset Quotes erd -\end_inset - -. -\layout Subsubsection - -LogSQLHeadersOutLogTable -\layout LyX-Code - -Syntax: LogSQLHeadersOutLogTable table-name -\layout LyX-Code - -Example: LogSQLHeadersOutLogTable headers -\layout LyX-Code - -Default: headers_out -\layout LyX-Code - -Context: virtual host -\layout Quote - -Defines which table is used for logging of outbound headers. - Working in conjunction with -\noun on -LogSQLWhichHeadersOut -\noun default -, you can log many of each request's associated headers to a separate table. - For meaningful data retrieval the headers table is keyed to the access - table by the unique request ID supplied by the standard Apache module mod_uniqu -e_id. -\layout Quote - -Note that you must create the table (see create-tables.sql, included in the - package), or -\noun on -LogSQLCreateTables -\noun default - must be set to -\begin_inset Quotes eld -\end_inset - -on -\begin_inset Quotes erd -\end_inset - -. -\layout Subsubsection - -LogSQLNotesLogTable -\layout LyX-Code - -Syntax: LogSQLNotesLogTable table-name -\layout LyX-Code - -Example: LogSQLNotesLogTable notes_log -\layout LyX-Code - -Default: notes -\layout LyX-Code - -Context: virtual host -\layout Quote - -Defines which table is used for logging of notes. - Working in conjunction with -\noun on -LogSQLWhichNotes -\noun default -, you can log many of each request's associated notes to a separate table. - For meaningful data retrieval the notes table is keyed to the access table - by the unique request ID supplied by the standard Apache module mod_unique_id. -\layout Quote - -Note that you must create the table (see create-tables.sql, included in the - package), or -\noun on -LogSQLCreateTables -\noun default - must be set to -\begin_inset Quotes eld -\end_inset - -on -\begin_inset Quotes erd -\end_inset - -. \layout Section FAQ \layout Subsection +General module questions +\layout Subsubsection + \begin_inset LatexCommand \label{sub:why} @@ -5349,7 +5580,7 @@ http://freshmeat.net As you can see, there are myriad possibilities that can be constructed with the wonderful SQL SELECT statement. Logging to an SQL database can be really quite useful! -\layout Subsection +\layout Subsubsection Why use MySQL? Are there alternatives? \layout Standard @@ -5372,7 +5603,7 @@ That being said, there are alternatives. \end_inset . -\layout Subsection +\layout Subsubsection Is this code production-ready? \layout Standard @@ -5381,12 +5612,121 @@ By all accounts it is. It is known to work without a problem on many-thousands-of-hits-per-day webservers. Does that mean it is 100% bug free? Well, no software is. - But it is well-tested and /believed/ to be fully compatible with production + But it is well-tested and believed to be fully compatible with production environments. (The usual disclaimers apply. This software is provided without warranty of any kind.) +\layout Subsubsection + +Who's using mod_log_sql? +\layout Standard + +Good question! It would be great to find out! If you are a production-level + mod_log_sql user, please contact +\begin_inset LatexCommand \url[the maintainer, Chris Powell]{(chris@grubbybaby.com)} + +\end_inset + + so that you can be mentioned here. +\layout Subsubsection + +Why doesn't the module also replace the Apache ErrorLog? +\layout Standard + +There are circumstances when that would be quite unwise -- for example, + if Apache could not reach the MySQL server for some reason and needed to + log that fact. + Without a text-based error log you'd never know anything was wrong, because + Apache would be trying to log a database connection error to the database... + you get the point. +\layout Standard + +Error logs are usually not very high-traffic and are really best left as + text files on a web server machine. +\layout Subsubsection + +Does mod_log_sql work with Apache 2.x? +\layout Standard + +As of this writing, no. + The Apache Group significantly altered the module API with the release + of Apache 2.0. + All modules written for 1.3, including mod_log_sql, will not work with 2.0. +\layout Standard + +mod_log_sql will eventually be ported to Apache 2.x, but not immediately. + It is going to take some time, and there are other features that have higher + priority. + Please sign up for the announcements list (on the main website) or monitor + the website for updates to learn when the port (and other releases) are + available. +\layout Standard + +If you're a *NIX user, stick with Apache 1.3.x for now. + Major modules like mod_ssl and PHP are not even ready for 2.0 yet, and the + main benefits in 2.0 are for Win32 users anyway. + Apache 1.3.x is rock-stable and performs equally well on *NIX as 2.0. +\layout Subsubsection + +Does mod_log_sql connect to MySQL via TCP/IP or a socket? +\layout Standard + +It depends! This is not determined by mod_log_sql. + mod_log_sql relies on a connection command that is supplied in the MySQL + API, and that command is somewhat intelligent. + How it works: +\layout Itemize + +if the specified MySQL database is on the same machine, the connection command + uses a socket to communicate with MySQL +\layout Itemize + +if the specified MySQL database is on a different machine, mod_log_sql connects + using TCP/IP. + +\layout Standard + +You don't have any control of which methodology is used. + You can fine-tune some of the configuration, however. + The +\noun on +LogSQLSocketFile +\noun default + runtime configuration directive overrides the default of +\begin_inset Quotes eld +\end_inset + +/var/lib/mysql/mysql.sock +\begin_inset Quotes erd +\end_inset + + for socket-based connections, whereas the +\noun on +LogSQLTCPPort +\noun default + command allows to you override the default TCP port of 3306 for TCP/IP + connections. +\layout Subsubsection + +I have discovered a bug. + Who can I contact? +\layout Standard + +Please contact +\begin_inset LatexCommand \url[the maintainer]{(chris@grubbybaby.com)} + +\end_inset + +! Your comments, suggestions, bugfixes, bug catches, and usage testimonials + are always welcome. + As free software, mod_log_sql is intended to be a community effort -- any + code contributions or other ideas will be fully and openly credited, of + course. \layout Subsection +Performance and Tuning +\layout Subsubsection + How well does it perform? \layout Standard @@ -5525,14 +5865,14 @@ mysql> delete from access_log where agent like 'ApacheBench%'; \layout LyX-Code mysql> optimize table access_log; -\layout Subsection +\layout Subsubsection Do I need to be worried about all the running MySQL children? Will holding open \emph on n \emph default - Apache -> MySQL connections consume a lot of memory? + Apache-to-MySQL connections consume a lot of memory? \layout Standard Short answer: you shouldn't be worried. @@ -5564,8 +5904,8 @@ ps -aufxw 30 children each... \layout Standard -Fortunately the cost reported by 'ps -aufxw' is indeed deceptive due to - an OS memory-management feature called +Fortunately the cost reported by 'ps -aufxw' is deceptive. + This is due to an OS memory-management feature called \begin_inset Quotes eld \end_inset @@ -5573,7 +5913,6 @@ copy-on-write. \begin_inset Quotes erd \end_inset - This is a memory-management technique used by Unix-based systems. When you have a number of identical child processes (e.g. Apache, MySQL), it would appear in \begin_inset Quotes eld @@ -5597,7 +5936,8 @@ read-only fashion. The OS can get away with this because the majority of memory pages for one child are identical across all children. - + Instead of thinking of each child as a rubber stamp of the others, think + of each child as a basket of links to a common memory area. \layout Standard A memory page is only duplicated when it needs to be written to, hence @@ -5655,9 +5995,17 @@ do not occupy 880MB of RAM. \layout Standard -The bottom line: although tangible, there is not much memory cost associated - with spawning off extra httpd or mysqld children. -\layout Subsection +The bottom line: although there is a cost to spawn extra httpd or mysqld + children, that cost is not as great as +\begin_inset Quotes eld +\end_inset + +ps +\begin_inset Quotes erd +\end_inset + + would lead you to believe. +\layout Subsubsection My database cannot handle all the open connections from mod_log_sql, is there anything I can do? @@ -5708,7 +6056,7 @@ performance than the alternatives because it dispenses with the overhead associated with rapid connection cycling, and it doesn't attempt to shoehorn all the database traffic through a single extra daemon or proxy process. -\layout Subsection +\layout Subsubsection My webservers cannot handle all the traffic that my site receives, is there anything I can do? @@ -5718,20 +6066,193 @@ If you have exhausted all the tuning possibilities on your existing server, it is probably time you evaluated the benefits of clustering two or more webservers together in a load-balanced fashion. In fact, users of such a setup are mod_log_sql's target audience! -\layout Subsection +\layout Subsubsection -Who's using mod_log_sql? +Why do I occasionally see a +\begin_inset Quotes eld +\end_inset + +lost connection to MySQL server +\begin_inset Quotes erd +\end_inset + + message in my error-log? \layout Standard -Good question! It would be great to find out! If you are a production-level - mod_log_sql user, please contact -\begin_inset LatexCommand \url[the maintainer, Chris Powell]{(chris@grubbybaby.com)} +This message may appear every now and then in your Apache error log, especially + on very lightly loaded servers. + This doesn't mean that anything is necessarily wrong. + Within each httpd child process, mod_log_sql will open (and keep open) + a connection to the MySQL server. + MySQL, however, will close connections that haven't been used in a while; + the default timeout is 8 hours. + When this occurs, mod_log_sql will notice and re-open the connection. + That event is what is being logged, and looks like this: +\layout LyX-Code + +[Tue Nov 12 19:04:10 2002] [error] mod_log_sql: first attempt failed, +\layout LyX-Code + + API said: error 2013, Lost connection to MySQL server during query +\layout LyX-Code + +[Tue Nov 12 19:04:10 2002] [error] mod_log_sql: reconnect successful +\layout LyX-Code + +[Tue Nov 12 19:04:10 2002] [error] mod_log_sql: second attempt successful +\layout Standard + +Reference: +\begin_inset LatexCommand \url[MySQL documentation]{(http://www.mysql.com/documentation/mysql/bychapter/manual_Problems.html#Gone_away)} \end_inset - so that you can be mentioned here. + +\layout Subsubsection + + +\begin_inset LatexCommand \label{sub:DelayedInsFAQ} + +\end_inset + +What is the issue with activating delayed inserts? +\layout Standard + +There are several. +\layout Enumerate + +INSERT DELAYED is a specific syntax to MySQL and is not supported by any + other database. + Ergo, why is it needed, and what MySQL deficiency is it working around? + INSERT DELAYED is a kluge. +\layout Enumerate + +The MySQL documentation is unclear whether INSERT DELAYED is even necessary + for an optimized database. + It says, +\begin_inset Quotes eld +\end_inset + +The DELAYED option for the INSERT statement is a MySQL-specific option that + is very useful if you have clients that can't wait for the INSERT to complete. +\begin_inset Quotes erd +\end_inset + + But then it goes on to say, +\begin_inset Quotes eld +\end_inset + +Note that as MyISAM tables supports concurrent SELECT and INSERT, if there + is no free blocks in the middle of the data file, you very seldom need + to use INSERT DELAYED with MyISAM. +\begin_inset Quotes erd +\end_inset + + +\layout Enumerate + +Because INSERT DELAYED returns without waiting for the data to be written, + a hard kill of your MySQL database at the right (wrong?) moment could lose + those logfile entries. +\layout Enumerate + +As of MySQL version 3.23.52, the error return functions disagree after a failed + INSERT DELAYED: mysql_errno() always returns 0, even if mysql_error() returns + a textual error. + I have reported this bug to the MySQL folks. + However, we have no way of knowing what solution they will adopt to fix + this, and with the worst case solution mod_log_sql would not be able to + tell if anything went wrong with a delayed insert. +\layout Standard + +If after understanding these problems you still wish to enable delayed inserts, + section +\begin_inset LatexCommand \ref{sub:DelayedIns} + +\end_inset + + discusses how. \layout Subsection + +\begin_inset Quotes eld +\end_inset + +How do I...? +\begin_inset Quotes erd +\end_inset + + -- accomplishing certain tasks +\layout Subsubsection + +I am using LogSQLMassVirtualHosting, and sometimes a single VirtualHost + gets logged to two different tables. + How do I prevent that? +\layout Standard + +Proper usage of the Apache runtime +\noun on +ServerName +\noun default + directive and the directive +\noun on +UseCanonicalName On +\noun default +(or +\noun on +DNS +\noun default +) are necessary to prevent this problem. + +\begin_inset Quotes eld +\end_inset + +On +\begin_inset Quotes erd +\end_inset + + is the default for +\noun on +UseCanonicalName +\noun default +, and specifies that self-referential URLs are generated from the +\noun on +ServerName +\noun default +part of your VirtualHost: +\layout Quote + +With UseCanonicalName on (and in all versions prior to 1.3) Apache will use + the ServerName and Port directives to construct the canonical name for + the server. + With UseCanonicalName off Apache will form self-referential URLs using + the hostname and port supplied by the client if any are supplied (otherwise + it will use the canonical name, as defined above). + [From +\begin_inset LatexCommand \url[the Apache documentation]{http://httpd.apache.org/docs/mod/core.html#usecanonicalname} + +\end_inset + +] +\layout Standard + +The module inherits Apache's +\begin_inset Quotes eld +\end_inset + +knowledge +\begin_inset Quotes erd +\end_inset + + about the server name being accessed. + As long as those two directives are properly configured, mod_log_sql will + log to only one table per virtual host while using +\noun on +LogSQLMassVirtualHosting +\noun default +. +\layout Subsubsection + How do I extract the data in a format that my analysis tool can understand? \layout Standard @@ -5790,22 +6311,7 @@ rm -f /var/log/httpd/templog \layout Standard See? Easy. -\layout Subsection - -Why doesn't the module also replace the Apache ErrorLog? -\layout Standard - -There are circumstances when that would be quite unwise -- for example, - if Apache could not reach the MySQL server for some reason and needed to - log that fact. - Without a text-based error log you'd never know anything was wrong, because - Apache would be trying to log a database connection error to the database... - you get the point. -\layout Standard - -Error logs are usually not very high-traffic and are really best left as - text files on a web server machine. -\layout Subsection +\layout Subsubsection \begin_inset LatexCommand \label{sec:cookie} @@ -6007,7 +6513,7 @@ ool-18e4.dyn.optonline.net.130051007102700823 \layout LyX-Code -\layout Subsection +\layout Subsubsection What if I want to log more than one cookie? What is the difference between LogSQLWhichCookie and LogSQLWhichCookies? @@ -6077,7 +6583,7 @@ LogSQLWhichCookies \noun default can coexist without conflict because they operate on entireley different tables, but you're better off choosing the one you need. -\layout Subsection +\layout Subsubsection What are the SSL logging features, and how do I activate them? \layout Standard @@ -6091,6 +6597,7 @@ need to compile SSL support into mod_log_sql in order to simply use it with You only need to compile SSL support into mod_log_sql if you want to log SSL-specific data such as the cipher type used, or the keysize that was negotiated. + If that information is unimportant to you, you can ignore this FAQ. \layout Standard By adding certain characters to your @@ -6349,128 +6856,4 @@ RC4-MD5 \layout LyX-Code -\layout Subsection - -Does mod_log_sql connect to MySQL via TCP/IP or a socket? -\layout Standard - -It depends! This is not determined by mod_log_sql. - mod_log_sql relies on a connection command that is supplied in the MySQL - API, and that command is somewhat intelligent. - How it works: -\layout Itemize - -if the specified MySQL database is on the same machine, the connection command - uses a socket to communicate with MySQL -\layout Itemize - -if the specified MySQL database is on a different machine, mod_log_sql connects - using TCP/IP. - -\layout Standard - -You don't have any control of which methodology is used. - You can fine-tune some of the configuration, however. - The -\noun on -LogSQLSocketFile -\noun default - runtime configuration directive overrides the default of -\begin_inset Quotes eld -\end_inset - -/var/lib/mysql/mysql.sock -\begin_inset Quotes erd -\end_inset - - for socket-based connections, whereas the -\noun on -LogSQLTCPPort -\noun default - command allows to you override the default TCP port of 3306 for TCP/IP - connections. -\layout Subsection - -Why do I occasionally see a -\begin_inset Quotes eld -\end_inset - -lost connection to MySQL server -\begin_inset Quotes erd -\end_inset - - message in my error-log? -\layout Standard - -This message may appear every now and then in your Apache error log, especially - on very lightly loaded servers. - This doesn't mean that anything is necessarily wrong. - Within each httpd child process, mod_log_sql will open (and keep open) - a connection to the MySQL server. - MySQL, however, will close connections that haven't been used in a while; - the default timeout is 8 hours. - When this occurs, mod_log_sql will notice and re-open the connection. - That event is what is being logged, and looks like this: -\layout LyX-Code - -[Tue Nov 12 19:04:10 2002] [error] mod_log_sql: first attempt failed, -\layout LyX-Code - - API said: error 2013, Lost connection to MySQL server during query -\layout LyX-Code - -[Tue Nov 12 19:04:10 2002] [error] mod_log_sql: reconnect successful -\layout LyX-Code - -[Tue Nov 12 19:04:10 2002] [error] mod_log_sql: second attempt successful - -\layout LyX-Code - -\layout Standard - -Reference: -\begin_inset LatexCommand \url[MySQL documentation]{(http://www.mysql.com/documentation/mysql/bychapter/manual_Problems.html#Gone_away)} - -\end_inset - - -\layout Subsection - -Does mod_log_sql work with Apache 2.x? -\layout Standard - -As of this writing, no. - The Apache Group significantly altered the module API with the release - of Apache 2.0. - All modules written for 1.3, including mod_log_sql, will not work with 2.0. -\layout Standard - -mod_log_sql will eventually be ported to Apache 2.x, but not immediately. - It is going to take some time, and there are other features that have higher - priority. - Please sign up for the announcements list (on the main website) or monitor - the website for updates to learn when the port (and other releases) are - available. -\layout Standard - -If you're a *NIX user, stick with Apache 1.3.x for now. - Major modules like mod_ssl and PHP are not even ready for 2.0 yet, and the - main benefits in 2.0 are for Win32 users anyway. - Apache 1.3.x is rock-stable and performs equally well on *NIX as 2.0. -\layout Subsection - -I have discovered a bug. - Who can I contact? -\layout Standard - -Please contact -\begin_inset LatexCommand \url[the maintainer]{(chris@grubbybaby.com)} - -\end_inset - -! Your comments, suggestions, bugfixes, bug catches, and usage testimonials - are always welcome. - As free software, mod_log_sql is intended to be a community effort -- any - code contributions or other ideas will be fully and openly credited, of - course. \the_end diff --git a/Makefile b/Makefile index d2effa0..6f69b50 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.17 2002/11/27 07:13:58 helios Exp $ +# $Id: Makefile,v 1.18 2002/12/10 19:43:21 helios Exp $ ########################################################################### # Important: @@ -13,7 +13,7 @@ MYSQLLIBS = /usr/lib MYSQLHDRS = /usr/include/mysql #MODSSLHDRS = /usr/local/src/apache_1.3.27-dso/src/modules/ssl -DB1HDRS = /usr/include/db1 +#DB1HDRS = /usr/include/db1 ########################################################################### # Don't uncomment this without reading the "Optimizing for a busy database" diff --git a/create_tables.sql b/create_tables.sql index 430d1a7..bc19a10 100644 --- a/create_tables.sql +++ b/create_tables.sql @@ -1,10 +1,10 @@ create table access_log ( - id char(19) , + id char(19) , agent varchar(255) , bytes_sent int unsigned , child_pid smallint unsigned, cookie varchar(255), - machine_id varchar(25), + machine_id varchar(25), request_file varchar(255), referer varchar(255) , remote_host varchar(50) , @@ -47,4 +47,4 @@ create table cookies ( id char(19), item varchar(80), val varchar(80) -); \ No newline at end of file +); diff --git a/mod_log_sql.c b/mod_log_sql.c index 3fc7ace..117111b 100644 --- a/mod_log_sql.c +++ b/mod_log_sql.c @@ -1,11 +1,11 @@ -/* $Id: mod_log_sql.c,v 1.19 2002/11/27 07:13:58 helios Exp $ */ +/* $Id: mod_log_sql.c,v 1.20 2002/12/10 19:43:21 helios Exp $ */ /* --------* * DEFINES * * --------*/ /* The enduser may wish to modify this */ -#define DEBUG +#undef DEBUG /* The enduser won't modify these */ #define MYSQL_ERROR(mysql) ((mysql)?(mysql_error(mysql)):"MySQL server has gone away") @@ -20,11 +20,13 @@ #include #include #include +#include #include "httpd.h" #include "http_config.h" #include "http_log.h" #include "http_core.h" #include "mysql.h" +#include "mysqld_error.h" #if MODULE_MAGIC_NUMBER >= 19980324 /* M_M_N is defined in /usr/local/Apache/include/ap_mmn.h, 19990320 as of this writing. */ #include "ap_compat.h" @@ -73,8 +75,8 @@ typedef const char *(*item_key_func) (request_rec *, char *); * Each child process has its own segregated copy of this structure. */ typedef struct { - int table_made; array_header *transfer_ignore_list; + array_header *transfer_accept_list; array_header *remhost_ignore_list; array_header *notes_list; array_header *hout_list; @@ -94,6 +96,9 @@ typedef struct { /* -----------------* * HELPER FUNCTIONS * * -----------------*/ + +int safe_create_tables(log_sql_state *cls, request_rec *r); + static char *format_integer(pool *p, int i) { char dummy[40]; @@ -484,7 +489,7 @@ static const char *extract_request_timestamp(request_rec *r, char *a) { char tstr[32]; - snprintf(tstr, 32, "%ld", time(NULL)); + ap_snprintf(tstr, 32, "%ld", time(NULL)); return pstrdup(r->pool, tstr); } @@ -665,73 +670,123 @@ void preserve_entry(request_rec *r, const char *query) /* Parms: request record, SQL insert statement */ /* Returns: 0 (OK) on success */ /* 1 if have no log handle */ -/* actual MySQL return code on error */ +/* 2 if insert delayed failed (kluge) */ +/* the actual MySQL return code on error */ /*-----------------------------------------------------*/ unsigned int safe_mysql_query(request_rec *r, const char *query) { - unsigned int retval; - unsigned int real_error; + int retval; struct timespec delay, remainder; int ret; void (*handler) (int); - + log_sql_state *cls; + unsigned int real_error; + #ifdef WANT_DELAYED_MYSQL_INSERT + char *real_error_str; + #endif /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */ handler = signal(SIGPIPE, SIG_IGN); /* First attempt for the query */ - if (mysql_log != NULL) - retval = mysql_query(mysql_log, query); - else - return 1; + if (!mysql_log) { + signal(SIGPIPE, handler); + return 1; + } else if (!(retval = mysql_query(mysql_log, query))) { + signal(SIGPIPE, handler); + return 0; + } - 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, &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(r->server); - - if (mysql_log == NULL) { /* still unable to link */ - signal(SIGPIPE, handler); - ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: reconnect failed, unable to reach database. SQL logging stopped until child regains a db connection."); - ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: log entries are being preserved in %s", cls->preserve_file); - return 1; - } else - ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: reconnect successful"); - - /* First sleep for a tiny amount of time. */ - delay.tv_sec = 0; - delay.tv_nsec = 250000000; /* max is 999999999 (nine nines) */ - ret = nanosleep(&delay, &remainder); - if (ret && errno != EINTR) - ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: nanosleep unsuccessful"); - - /* Then make our second attempt */ - retval = mysql_query(mysql_log,query); - - /* If this one also failed, log that and append to our local offline file */ - if ( retval != 0 ) - { - 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 - ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: second attempt successful"); + /* 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.) */ + #ifdef WANT_DELAYED_MYSQL_INSERT + real_error_str = MYSQL_ERROR(mysql_log); + #else + real_error = mysql_errno(mysql_log); + #endif + + /* Check to see if the error is "nonexistent table" */ + #ifdef WANT_DELAYED_MYSQL_INSERT + if ((strstr(real_error_str, "Table")) && (strstr(real_error_str,"doesn't exist"))) { + #else + if (real_error == ER_NO_SUCH_TABLE) { + #endif + if (create_tables) { + ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: table doesn't exist...creating now"); + cls = get_module_config(r->server->module_config, &sql_log_module); + if (safe_create_tables(cls, r)) { + ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: child attempted but failed to create one or more tables for %s, preserving query", ap_get_server_name(r)); + preserve_entry(r, query); + retval = mysql_errno(mysql_log); + } else { + ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: tables successfully created - retrying query"); + if (mysql_query(mysql_log, query)) { + ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: giving up, preserving query"); + preserve_entry(r, query); + retval = mysql_errno(mysql_log); + } else + ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: query successful after table creation"); + retval = 0; + } + } else { + ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql, table doesn't exist, creation denied by configuration, preserving query"); + preserve_entry(r, query); + retval = ER_NO_SUCH_TABLE; + } + /* Restore SIGPIPE to its original handler function */ + signal(SIGPIPE, handler); + return retval; } + /* Handle all other types of errors */ + + cls = get_module_config(r->server->module_config, &sql_log_module); + + /* Something went wrong, so start by trying to restart the db link. */ + #ifdef WANT_DELAYED_MYSQL_INSERT + real_error = 2; + #else + real_error = mysql_errno(mysql_log); + #endif + 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(r->server); + + if (mysql_log == NULL) { /* still unable to link */ + signal(SIGPIPE, handler); + ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: reconnect failed, unable to reach database. SQL logging stopped until child regains a db connection."); + ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: log entries are being preserved in %s", cls->preserve_file); + return 1; + } else + ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: db reconnect successful"); + + /* First sleep for a tiny amount of time. */ + delay.tv_sec = 0; + delay.tv_nsec = 250000000; /* max is 999999999 (nine nines) */ + ret = nanosleep(&delay, &remainder); + if (ret && errno != EINTR) + ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: nanosleep unsuccessful"); + + /* Then make our second attempt */ + retval = mysql_query(mysql_log,query); + + /* If this one also failed, log that and append to our local offline file */ + if (retval) { + #ifdef WANT_DELAYED_MYSQL_INSERT + real_error = 2; + #else + real_error = mysql_errno(mysql_log); + #endif + ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: second attempt failed, API said: error %d, \"%s\" -- preserving", real_error, MYSQL_ERROR(mysql_log)); + preserve_entry(r, query); + retval = real_error; + } 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; } @@ -811,35 +866,29 @@ int safe_create_tables(log_sql_state *cls, request_rec *r) #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; + if ((create_results = safe_mysql_query(r, create_access))) { 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; + if ((create_results = safe_mysql_query(r, create_notes))) { ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create notes table"); retval = create_results; } - if ((create_results = safe_mysql_query(r, create_hin)) != 0) { - cls->table_made = 0; + if ((create_results = safe_mysql_query(r, create_hin))) { 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; + if ((create_results = safe_mysql_query(r, create_hout))) { 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; + if ((create_results = safe_mysql_query(r, create_cookies))) { ap_log_error(APLOG_MARK,ERRLEVEL,r->server,"mod_log_sql: failed to create cookies table"); retval = create_results; } @@ -872,8 +921,8 @@ const char *set_log_sql_machine_id(cmd_parms *parms, void *dummy, char *arg) const char *set_log_sql_create(cmd_parms *parms, void *dummy, int flag) { - if (massvirtual != 0) - ap_log_error(APLOG_MARK,WARNINGLEVEL,parms->server,"mod_log_sql: do not set LogSQLCreateTables when LogSQLMassVirtualHosting is On. Ignoring."); + if (massvirtual) + 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; @@ -994,6 +1043,16 @@ const char *set_log_sql_tcp_port(cmd_parms *parms, void *dummy, char *arg) return NULL; } +const char *add_log_sql_transfer_accept(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->transfer_accept_list); + *addme = pstrdup(cls->transfer_accept_list->pool, arg); + return NULL; +} + const char *add_log_sql_transfer_ignore(cmd_parms *parms, void *dummy, char *arg) { char **addme; @@ -1072,8 +1131,9 @@ const char *add_log_sql_cookie(cmd_parms *parms, void *dummy, char *arg) */ static void log_sql_child_init(server_rec *s, pool *p) { - int retval; + int retval; + /* Open a link to the database */ 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"); @@ -1140,12 +1200,12 @@ void *log_sql_make_state(pool *p, server_rec *s) cls->preserve_file = "/tmp/sql-preserve"; cls->transfer_ignore_list = make_array(p, 1, sizeof(char *)); + cls->transfer_accept_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->cookie_name = NULL; return (void *) cls; @@ -1177,6 +1237,9 @@ command_rec log_sql_cmds[] = { {"LogSQLMachineID", set_log_sql_machine_id, NULL, RSRC_CONF, TAKE1, "Machine ID that the module will log, useful in web clusters to differentiate machines"} , + {"LogSQLRequestAccept", add_log_sql_transfer_accept, NULL, RSRC_CONF, ITERATE, + "List of URIs to accept for logging. Accesses that don't match will not be logged"} + , {"LogSQLRequestIgnore", add_log_sql_transfer_ignore, NULL, RSRC_CONF, ITERATE, "List of URIs to ignore. Accesses that match will not be logged to database"} , @@ -1240,18 +1303,18 @@ int log_sql_transaction(request_rec *orig) /* We handle mass virtual hosting differently. Dynamically determine the name * of the table from the virtual server's name, and flag it for creation. */ - if ( massvirtual == 1 ) { + if (massvirtual) { char *access_base = "access_"; - char *notes_base = "notes_"; - char *hout_base = "headout_"; - char *hin_base = "headin_"; + 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; + unsigned 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); @@ -1308,7 +1371,7 @@ int log_sql_transaction(request_rec *orig) const char *unique_id; const char *formatted_item; int i, j, length; - int result; + int proceed; for (r = orig; r->next; r = r->next) { continue; @@ -1317,16 +1380,29 @@ int log_sql_transaction(request_rec *orig) /* The following is a stolen upsetting mess of pointers, I'm sorry. * Anyone with the motiviation and/or the time should feel free * to make this cleaner. :) */ - ptrptr2 = (char **) (cls->transfer_ignore_list->elts + (cls->transfer_ignore_list->nelts * cls->transfer_ignore_list->elt_size)); + ptrptr2 = (char **) (cls->transfer_accept_list->elts + (cls->transfer_accept_list->nelts * cls->transfer_accept_list->elt_size)); + + /* Go through each element of the accept list and compare it to the + * request_uri. If we don't get a match, return without logging */ + if ((r->uri) && (cls->transfer_accept_list->nelts)) { + proceed = 0; + for (ptrptr = (char **) cls->transfer_accept_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->transfer_accept_list->elt_size)) + if (strstr(r->uri, *ptrptr)) { + proceed = 1; + break; + } + if (!proceed) + return OK; + } /* Go through each element of the ignore list and compare it to the * request_uri. If we get a match, return without logging */ + ptrptr2 = (char **) (cls->transfer_ignore_list->elts + (cls->transfer_ignore_list->nelts * cls->transfer_ignore_list->elt_size)); if (r->uri) { - for (ptrptr = (char **) cls->transfer_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->transfer_ignore_list->elt_size)) { + for (ptrptr = (char **) cls->transfer_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->transfer_ignore_list->elt_size)) if (strstr(r->uri, *ptrptr)) { return OK; } - } } /* Go through each element of the ignore list and compare it to the @@ -1334,11 +1410,10 @@ int log_sql_transaction(request_rec *orig) ptrptr2 = (char **) (cls->remhost_ignore_list->elts + (cls->remhost_ignore_list->nelts * cls->remhost_ignore_list->elt_size)); thehost = get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME); if (thehost) { - for (ptrptr = (char **) cls->remhost_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->remhost_ignore_list->elt_size)) { + for (ptrptr = (char **) cls->remhost_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->remhost_ignore_list->elt_size)) if (strstr(thehost, *ptrptr)) { return OK; } - } } length = strlen(cls->transfer_log_format); @@ -1530,7 +1605,7 @@ 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. - * This short-circuits safe_mysql_query during a db outage and therefore + * 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); @@ -1554,52 +1629,20 @@ int log_sql_transaction(request_rec *orig) /* ---> 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)) { - result = safe_create_tables(cls, orig); - if (result != 0) - ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: child attempted but failed to create one or more tables for %s", ap_get_server_name(orig)); - 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"); - result = safe_create_tables(cls, orig); - if (result != 0) { - ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: child attempted but failed to create one or more tables for %s, preserving query", ap_get_server_name(orig)); - preserve_entry(orig,access_query); - } else { - ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: table successfully created, query will now be retried"); - result = safe_mysql_query(orig, access_query); - if (result != 0 ) { - ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: giving up, preserving query"); - preserve_entry(orig,access_query); - return OK; - } - } - } + safe_mysql_query(orig, access_query); /* Log the optional notes, headers, etc. */ - if ( note_query != NULL ) + if (note_query) safe_mysql_query(orig, note_query); - if ( hout_query != NULL ) + if (hout_query) safe_mysql_query(orig, hout_query); - if ( hin_query != NULL ) + if (hin_query) safe_mysql_query(orig, hin_query); - if ( cookie_query != NULL ) + if (cookie_query) safe_mysql_query(orig, cookie_query); return OK; @@ -1634,3 +1677,46 @@ module sql_log_module = { #endif }; + + + +/* Make the tables if we're supposed to. */ +/* +if ((cls->table_made != 1) && (create_tables != 0)) { + result = safe_create_tables(cls, orig); + if (result != 0) + ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: child attempted but failed to create one or more tables for %s", ap_get_server_name(orig)); + else + ap_log_error(APLOG_MARK,NOTICELEVEL,orig->server,"mod_log_sql: no problems creating tables for %s", ap_get_server_name(orig)); +} +*/ + +/* It failed, but NOT because table didn't exist */ +/* +if ( (result) && (result != ER_NO_SUCH_TABLE) ) + preserve_entry(orig,access_query); +*/ + +/* It failed because table didn't exist */ +/* +if (result == ER_NO_SUCH_TABLE) + if (create_tables) { + ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: access table doesn't exist...creating now"); + if ((result = safe_create_tables(cls, orig))) { + ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: child attempted but failed to create one or more tables for %s, preserving query", ap_get_server_name(orig)); + preserve_entry(orig,access_query); + } else { + ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: table(s) successfully created - retrying insert"); + if ((result = safe_mysql_query(orig, access_query))) { + ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: giving up, preserving query"); + preserve_entry(orig,access_query); + return OK; + } else + ap_log_error(APLOG_MARK_ERRLEVEL,orig->server,"mod_log_sql: insert successful after table creation"); + } + } else { + ap_log_error(APLOG_MARK,ERRLEVEL,orig->server,"mod_log_sql: access table doesn't exist...not allowed to create, giving up, preserving query"); + preserve_entry(orig,access_query); + return OK; + } +*/ -- cgit v0.9.2