summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.cvsignore6
-rw-r--r--AUTHORS14
-rw-r--r--CHANGELOG68
-rw-r--r--Documentation/.cvsignore1
-rw-r--r--Documentation/Makefile.in (renamed from docs/Makefile.in)10
-rw-r--r--Documentation/README13
-rw-r--r--Documentation/documentation.lyx (renamed from docs/documentation.lyx)0
-rw-r--r--Documentation/manual.xml (renamed from docs/manual.xml)1259
-rw-r--r--INSTALL21
-rw-r--r--LICENSE4
-rw-r--r--Makefile.in104
-rw-r--r--TODO.in16
-rw-r--r--apache13.h54
-rw-r--r--apache20.h13
-rw-r--r--build-apache13.bat47
-rw-r--r--build-apache2.bat40
-rw-r--r--configure.ac36
-rw-r--r--contrib/Makefile.in5
-rw-r--r--contrib/README39
-rw-r--r--contrib/mysql_import_combined_log.pl61
-rw-r--r--create_tables.sql (renamed from contrib/create_tables.sql)0
-rw-r--r--docs/.cvsignore3
-rw-r--r--docs/README7
-rw-r--r--functions.h39
-rw-r--r--functions13.h2
-rw-r--r--functions20.h4
-rwxr-xr-xgen_todo.pl64
-rw-r--r--m4/apache.m4175
-rw-r--r--m4/mod_ssl.m450
-rw-r--r--m4/mysql.m464
-rw-r--r--make_combined_log.pl (renamed from contrib/make_combined_log.pl)28
-rw-r--r--mod_log_sql.c992
-rw-r--r--mod_log_sql.h103
-rw-r--r--mod_log_sql.prj15
-rw-r--r--mod_log_sql_mysql.c259
-rw-r--r--mod_log_sql_pgsql.c251
-rw-r--r--mod_log_sql_ssl.c69
-rw-r--r--winconfig.h78
38 files changed, 1563 insertions, 2451 deletions
diff --git a/.cvsignore b/.cvsignore
index 2f18090..1149bb9 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -4,12 +4,10 @@ aclocal.m4
4.deps 4.deps
5*.lo 5*.lo
6*.slo 6*.slo
7*.so
8autom4te-2.53.cache 7autom4te-2.53.cache
9Makefile 8Makefile
10configure 9configure
11config.cache 10config.cache
12config.nice
13config.log 11config.log
14config.status 12config.status
15configure 13configure
@@ -29,7 +27,3 @@ stamp-h.in
29config.h 27config.h
30config.h.in 28config.h.in
31include 29include
32include13
33include20
34TODO
35Release
diff --git a/AUTHORS b/AUTHORS
index d10c5de..2e62393 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,11 +1,11 @@
1Edward Rudd <eddie at omegaware dot com> 1The Apache Foundation
2 Apache 2.0 port. Current Maintainer as of February, 2004 2 standard apache logging module for which this module is based on
3
4Christopher B. Powell <chris at grubbybaby dot com>
5 Maintainer since version 1.06
6 3
7Zeev Suraski <bourbon at netvision.net dot il> 4Zeev Suraski <bourbon at netvision.net dot il>
8 Adding the mysql routines (intial revisions) 5 Adding the mysql routines (intial revisions)
9 6
10The Apache Foundation 7Christopher B. Powell <chris at grubbybaby dot com>
11 standard apache logging module for which this module is based on 8 Maintainer since version 1.06
9
10Edward Rudd <eddie at omegaware dot com>
11 Apache 2.0 port.
diff --git a/CHANGELOG b/CHANGELOG
index 3e0d531..79c740f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,49 +1,35 @@
11.98: 2004-04-? 1$Id: CHANGELOG,v 1.11 2004/02/05 22:05:42 urkle Exp $
2* re-fixed apache.m4 to better detect APR and APU code 2
3* fixed for win32 compilation under apache 2 3TODO:
4* lowered minumum required apache 2 version to 2.0.40 (RH9) 4* Port connection portion to other DBMS? Genericize the module? Start with
5* Added LogSQLDisablePreserve to disable the preserve file. 5 PostgreSQL. (provider mechanism, and libDBI)
6* Changed default preserve file location to logs/mod_log_sql-preserve 6* does determining table name in massvirtual mode upon every request
7 And made LogSQLPreserveFile root relative. 7 cause performance degradation? If so fix.
8* fixed bug where preserve file wouldn't be created in apache 2 8* LogSQLRotateLogs directive with daily/monthly/weekly/etc.
9* finished TransferLog documentation 9* new format char: IP as bigint? ( not w/ ipV6 )
10* changed strstr to ap_strstr calls and strchr to ap_strchr calls to 10* socket-based middleman daemon with configurable conns, or connect/disconnect.
11 stop warning when compiling with AP_DEBUG enabled in apache 2 11 DBI connection pool when I switch to DBI.
12* Updated apache m4 to not pass for apache 1.3 if apache 2 is found 12* ignore by cookie
13 13* tools to import logs into SQL (waiting on permission from author)
141.97: 2004-04-08 14* Directive to yes/no create ancillary tables (or just access table)
15* fixed apache.m4 to work with apache 2 setups with different include 15* break module into separate code files
16 directories for APR and APU then core Apache 16 separate DB implimentation into sub-modules via provider mechanism
17* cleaned up configuration documentation (updated due to deprecated commands) 17* convert documentation to docbook
18* LogSQLLoginInfo updated to support a connection URI 18* add document building to Makefile.in
19* new module "registration" macros to clean up new driver modules 19* investigate thread safety issues (libmysqlclient_r)
20* mysql driver completely separted from core module 20 Add thread locks if using standard mysqlclient
21 21* rewrite main core logging function to optimize for speed.
221.96: 2004-03-04 22
23* fixed LogSQLPreserveFile config parameter 23CHANGES:
24* reworked safe_create_tables and core SQL insert routine.
25* renamed log_sql_* variables and typedefs to logsql_*
26* separated all mysql specific code to separate code module (DB abstraction)
27* separated TODO from Changelog
28* fixed default value of socket file. it's really /var/lib/mysql/mysql.sock not
29 /tmp/mysql.sock
30* Documentation completely converted to Docbook
31* Documentation updated. (still needs more work done)
32* LogSQLDelayedInserts config option removed
33* Added DB generic LogSQLDBParam. Usage is LogSQLDBParam param value
34 example: LogSQLDBParam tcpport 12345
35* notes, cookes, headersin, headersout tables are no longer created unless they
36 are used.
37
381.95: 2004-02-05 241.95: 2004-02-05
39* audit and update of extract_* functions to acheive same output as 25* audit and update of extract_* functions to acheive same output as
40 mod_log_config. 26 mod_log_config.
41 27
421.94: 2004-02-03 281.94: 2004-02-03
43* ssl loggin back in as separate module under 1.3 and 2.0 29* ssl loggin back in as separate module under 1.3 and 2.0
44* preparsing of format tags is now done to speed up main logging loop. 30* preparsing of format tags is now done to speed up main logging loop.
45* fixed a nasty bug with pointer arithmetic (ick) that caused a segfault with 31* fixed a nasty bug with pointer arithmetic (ick) that caused a segfault with
46 LogSQLWhichCookies 32 LogSQLWhichCookies
47 33
481.93: 2004-01-20 341.93: 2004-01-20
49* Compiles for apache 1.3 AND 2.0 35* Compiles for apache 1.3 AND 2.0
@@ -51,9 +37,9 @@
51* split apache version specific includes to seperate header files 37* split apache version specific includes to seperate header files
52* added wrapper defines for apache 1.3 38* added wrapper defines for apache 1.3
53* updated configure m4 scripts to detect both apache versions at the same time 39* updated configure m4 scripts to detect both apache versions at the same time
54 and assign defines as to which version was found. 40 and assign defines as to which version was found.
55* made install default to not activate module in configuration files. 41* made install default to not activate module in configuration files.
56 use make activate instead 42 (use make activate)
57* split SSL logging to separate module (still needs to be finished) 43* split SSL logging to separate module (still needs to be finished)
58 44
591.92: 2004-01-05 451.92: 2004-01-05
diff --git a/Documentation/.cvsignore b/Documentation/.cvsignore
new file mode 100644
index 0000000..f3c7a7c
--- /dev/null
+++ b/Documentation/.cvsignore
@@ -0,0 +1 @@
Makefile
diff --git a/docs/Makefile.in b/Documentation/Makefile.in
index 81f2298..2d07cfd 100644
--- a/docs/Makefile.in
+++ b/Documentation/Makefile.in
@@ -3,9 +3,7 @@
3# Modify these top variables. 3# Modify these top variables.
4SUBDIRS = 4SUBDIRS =
5 5
6EXTRA_DIST = README \ 6EXTRA_DIST = README documentation.lyx
7 manual.xml \
8 manual.html
9 7
10#Don't modify anything below here 8#Don't modify anything below here
11 9
@@ -18,12 +16,6 @@ DISTFILES = $(STD_DIST) $(EXTRA_DIST)
18 16
19all: all-subdirs 17all: all-subdirs
20 18
21%.html: %.xml
22 @xmlto html-nochunks $<
23
24%.pdf: %.xml
25 @xmlto pdf $<
26
27all-subdirs install-subdirs update-subdirs clean-subdirs distclean-subdirs: 19all-subdirs install-subdirs update-subdirs clean-subdirs distclean-subdirs:
28 @otarget=`echo $@|sed s/-subdirs//`; \ 20 @otarget=`echo $@|sed s/-subdirs//`; \
29 list=' $(SUBDIRS)'; \ 21 list=' $(SUBDIRS)'; \
diff --git a/Documentation/README b/Documentation/README
new file mode 100644
index 0000000..15e9612
--- /dev/null
+++ b/Documentation/README
@@ -0,0 +1,13 @@
1$Id: README,v 1.1 2003/12/20 07:16:05 urkle Exp $
2
3The "original" document is the LyX file "documentation.lyx" -- all other
4files here are derived from it. The most visually accurate document
5and the one I'd recommend reading is the PostScript (.ps) file, although
6a whole host of formats are made available here to suit your preference.
7
8To read the HTML docs, open HTML/documentation.html in your browser.
9To read the .dvi file, use Xdvi or kdvi.
10To read the .ps file, use gv or kghostview.
11To read the .lyx file, use LyX.
12To read the .txt file, use less.
13
diff --git a/docs/documentation.lyx b/Documentation/documentation.lyx
index eeb6af5..eeb6af5 100644
--- a/docs/documentation.lyx
+++ b/Documentation/documentation.lyx
diff --git a/docs/manual.xml b/Documentation/manual.xml
index 880bf03..f2d36ff 100644
--- a/docs/manual.xml
+++ b/Documentation/manual.xml
@@ -1,29 +1,25 @@
1<?xml version="1.0" encoding="UTF-8"?> 1<?xml version="1.0" encoding="UTF-8"?>
2<?xml-stylesheet href="file://localhost/home/urkle/Documents/DocBook/docbook.css" type="text/css"?> 2<?xml-stylesheet href="file://localhost/home/urkle/Documents/DocBook/docbook.css" type="text/css"?>
3<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [ 3<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "file:/usr/share/sgml/docbook/xml-dtd-4.1.2-1.0-8/docbookx.dtd">
4<!ENTITY EmailContact "<email>urkle &lt;at&gt; outoforder &lt;dot&gt; cc</email>">
5]>
6<article> 4<article>
7 <articleinfo> 5 <articleinfo>
8 <title>mod_log_sql Manual</title> 6 <title>mod_log_sql Manual</title>
9 <author> 7 <author>
10 <firstname>Edward</firstname>
11 <surname>Rudd</surname>
12 <contrib>Conversion from Lyx to DocBook</contrib>
13 <contrib>Current Maintainer</contrib>
14 <affiliation>
15 <address format="linespecific">&EmailContact;</address>
16 </affiliation>
17 </author>
18 <author>
19 <firstname>Christopher</firstname> 8 <firstname>Christopher</firstname>
20 <othername>B.</othername> 9 <othername>B.</othername>
21 <surname>Powell</surname> 10 <surname>Powell</surname>
22 <contrib>Original documentation author.</contrib>
23 <affiliation> 11 <affiliation>
24 <address format="linespecific"><email>chris &lt;at&gt; grubbybaby &lt;dot&gt; com</email></address> 12 <address format="linespecific"><email>chris &lt;at&gt; grubbybaby &lt;dot&gt; com</email></address>
25 </affiliation> 13 </affiliation>
26 </author> 14 </author>
15 <author>
16 <firstname>Edward</firstname>
17 <surname>Rudd</surname>
18 <contrib>Porting from Lyx to DocBook</contrib>
19 <affiliation>
20 <address format="linespecific"><email>eddie &lt;at&gt; omegaware &lt;dot&gt; com</email></address>
21 </affiliation>
22 </author>
27 <copyright> 23 <copyright>
28 <year>2001</year> 24 <year>2001</year>
29 <year>2002</year> 25 <year>2002</year>
@@ -36,39 +32,29 @@
36 </copyright> 32 </copyright>
37 <revhistory> 33 <revhistory>
38 <revision> 34 <revision>
39 <revnumber>1.2</revnumber>
40 <date>2004-04-?</date>
41 <revremark>Updated for mod_log_sql v1.97</revremark>
42 </revision>
43 <revision>
44 <revnumber>1.1</revnumber>
45 <date>2004-03-02</date>
46 <revremark>Updated for mod_log_sql v1.96</revremark>
47 </revision>
48 <revision>
49 <revnumber>1.0</revnumber> 35 <revnumber>1.0</revnumber>
50 <date>2004-01-22</date> 36 <date>2004-01-22</date>
51 <revremark>Initial Conversion from Lyx to Docbook</revremark> 37 <revremark>Initial Conversion from Lyx to Docbook</revremark>
52 </revision> 38 </revision>
53 </revhistory> 39 </revhistory>
54 </articleinfo> 40 </articleinfo>
55 <sect1> 41 <sect1 id="intro">
56 <title>Introduction</title> 42 <title>Introduction</title>
57 <sect2> 43 <sect2>
58 <title>Summary</title> 44 <title>Summary</title>
59 <para>This Apache module will permit you to log to a SQL database; it can log each access request as well as data associated with each request: cookies, notes, and inbound/outbound headers. Unlike logging to a flat text file -- which is standard in Apache -- a SQL-based log exhibits tremendous flexibility and power of data extraction. (See FAQ entry <xref linkend="FAQ.WhyLogToSQL"/> for further discussion and examples of the advantages to SQL.)</para> 45 <para>This Apache module will permit you to log to a SQL database; it can log each access request as well as data associated with each request: cookies, notes, and inbound/outbound headers. Unlike logging to a flat text file -- which is standard in Apache -- a SQL-based log exhibits tremendous flexibility and power of data extraction. (See section [sub:why] in the FAQ for further discussion and examples of the advantages to SQL.)</para>
60 <para>This module can either replace or happily coexist with mod_log_config, Apache's text file logging facility. In addition to being more configurable than the standard module, mod_log_sql is much more flexible.</para> 46 <para>This module can either replace or happily coexist with mod_log_config, Apache's text file logging facility. In addition to being more configurable than the standard module, mod_log_sql is much more flexible.</para>
61 </sect2> 47 </sect2>
62 <sect2> 48 <sect2 id="copyright">
63 <title>Approach</title> 49 <title>Approach</title>
64 <para>This project was formerly known as "mod_log_mysql." It was renamed "mod_log_sql" in order to reflect the project goal of database in-specificity. The module currently supports MySQL, but support for other database back-ends is underway.</para> 50 <para>This project was formerly known as "mod_log_mysql." It was renamed "mod_log_sql" in order to reflect the project goal of database in-specificity. The module currently supports MySQL, but support for other database back-ends is underway.</para>
65 <para>In order to save speed and overhead, links are kept alive in between queries. This module uses one dedicated SQL link per httpd child, opened by each child process when it is born. Among other things, this means that this module supports logging into only one MySQL server, and for now, also, only one SQL database. But that's a small tradeoff compared to the blinding speed of this module. Error reporting is robust throughout the module and will inform the administrator of database issues in the Apache ErrorLog for the server/virtual server.</para> 51 <para>In order to save speed and overhead, links are kept alive in between queries. This module uses one dedicated SQL link per httpd child, opened by each child process when it is born. Among other things, this means that this module supports logging into only one MySQL server, and for now, also, only one SQL database. But that's a small tradeoff compared to the blinding speed of this module. Error reporting is robust throughout the module and will inform the administrator of database issues in the Apache ErrorLog for the server/virtual server.</para>
66 <para>Virtual hosts are supported in the same manner they are in the regular logging modules. The administrator defines some basic 'global' directives in the main server config, then defines more specific 'local' directives inside each VirtualHost stanza.</para> 52 <para>Virtual hosts are supported in the same manner they are in the regular logging modules. The administrator defines some basic 'global' directives in the main server config, then defines more specific 'local' directives inside each VirtualHost stanza.</para>
67 <para>A robust "preserve" capability has now been implemented. This permits the module to preserve any failed INSERT commands to a local file on its machine. In any situation that the database is unavailable -- e.g. the network fails or the database host is rebooted -- mod_log_sql will note this in the error log and begin appending its log entries to the preserve file (which is created with the user and group ID of the running Apache process, e.g. "nobody/nobody" on many Linux installations). When database availability returns, mod_log_sql seamlessly resumes logging to it. When convenient for the sysadmin, he/she can easily import the preserve file into the database because it is simply a series of SQL insert statements.</para> 53 <para>A robust "preserve" capability has now been implemented. This permits the module to preserve any failed INSERT commands to a local file on its machine. In any situation that the database is unavailable -- e.g. the network fails or the database host is rebooted -- mod_log_sql will note this in the error log and begin appending its log entries to the preserve file (which is created with the user &amp; group ID of the running Apache process, e.g. "nobody/nobody" on many Linux installations). When database availability returns, mod_log_sql seamlessly resumes logging to it. When convenient for the sysadmin, he/she can easily import the preserve file into the database because it is simply a series of SQL insert statements.</para>
68 </sect2> 54 </sect2>
69 <sect2> 55 <sect2>
70 <title>What gets logged by default?</title> 56 <title>What gets logged by default?</title>
71 <para>All the data that would be contained in the "Combined Log Format" is logged by default, plus a little extra. Your best bet is to begin by accepting this default, then later customize the log configuration based on your needs. The documentation of the run-time directives includes a full explanation of what you can log, including examples -- see section <xref endterm="Sect.ConfigReference.title" linkend="Sect.ConfigReference"/>.</para> 57 <para>All the data that would be contained in the "Combined Log Format" is logged by default, plus a little extra. Your best bet is to begin by accepting this default, then later customize the log configuration based on your needs. The documentation of the run-time directives includes a full explanation of what you can log, including examples -- see section [sec:ConfRef].</para>
72 </sect2> 58 </sect2>
73 <sect2> 59 <sect2>
74 <title>Miscellaneous Notes</title> 60 <title>Miscellaneous Notes</title>
@@ -98,12 +84,7 @@
98 <para>The actual logging code was taken from the already existing flat file text modules, so all that credit goes to the Apache Software Foundation.</para> 84 <para>The actual logging code was taken from the already existing flat file text modules, so all that credit goes to the Apache Software Foundation.</para>
99 <para>The MySQL routines and directives were added by Zeev Suraski &lt;bourbon@netvision.net.il&gt;. </para> 85 <para>The MySQL routines and directives were added by Zeev Suraski &lt;bourbon@netvision.net.il&gt;. </para>
100 <para>All changes from 1.06+ and the new documentation were added by Chris Powell <email>chris &lt;at&gt; grubbybaby &lt;dot&gt; com</email>. It seems that the module had fallen into the "un-maintained" category -- it had not been updated since 1998 -- so Chris adopted it as the new maintainer.</para> 86 <para>All changes from 1.06+ and the new documentation were added by Chris Powell <email>chris &lt;at&gt; grubbybaby &lt;dot&gt; com</email>. It seems that the module had fallen into the "un-maintained" category -- it had not been updated since 1998 -- so Chris adopted it as the new maintainer.</para>
101 <para>In December of 2003, Edward Rudd &EmailContact; porting the module to Apache 2.0, cleaning up the code, converting the documentation to DocBook, optimizing the main logging loop, and added the much anticipated database abstraction layer.</para> 87 <para>In December of 2003, Edward Rudd <email>eddie &lt;at&gt; omegaware &lt;dot&gt; com</email> porting the module to Apache 2.0, cleaning up the code, converting the documentation to DocBook, optimizing the main logging loop, and added the much anticipated database abstraction layer.</para>
102 <para>As of February 2004, Chris Powell handed over maintenance of the module over to Edward Rudd. So you should contact Edward Rudd about the module from now on.</para>
103 </sect2>
104 <sect2 id="Sect.MailingLists">
105 <title id="Sect.MailingLists.title">Mailing Lists</title>
106 <para>A general discussion and support mailing list is provided for mod_log_sq at lists.outoforder.cc. To subscribe to the mailing list send a blank e-mail to mod_log_sql-subscribe@lists.outoforder.cc. The list archives can be accessed via Gmane.org's mailng list gateway via any new reader <ulink url="news://news.gmane.org/gmane.comp.apache.mod-log-sql">news://news.gmane.org/gmane.comp.apache.mod-log-sql</ulink>, or via a web browser at <ulink url="http://news.gmane.org/gmane.comp.apache.mod-log-sql">http://news.gmane.org/gmane.comp.apache.mod-log-sql</ulink>.</para>
107 </sect2> 88 </sect2>
108 </sect1> 89 </sect1>
109 <sect1> 90 <sect1>
@@ -129,7 +110,48 @@
129 </itemizedlist> 110 </itemizedlist>
130 </sect2> 111 </sect2>
131 <sect2> 112 <sect2>
132 <title>Compiling and Installing</title> 113 <title>Platform Specific Notes</title>
114 <para><remark>This section is currently not applicable as the new autoconf setup should autodetect everything for your server..Win32 system, however, need to be updated.</remark>These installation documents assume a relatively modern GNU/Linux scenario. mod_log_sql has been ported to other platforms; following are notes on compiling the module for those platforms.</para>
115 <sect3>
116 <title>&lt;sub:Solaris&gt;Solaris</title>
117 <para>The nanosleep() function used in mod_log_sql relies on linking aginst the librt library. Make the following alterations before proceeding: </para>
118 <orderedlist>
119 <listitem>
120 <para>In Makefile, search for the string "-lmysqlclient -lz" and change it to read "-lmysqlclient -lz -lrt"</para>
121 </listitem>
122 <listitem>
123 <para> In part [step:Linking] of section [sec:Static] below, change "-lmysqlclient -lm -lz" to read "-lmysqlclient -lm -lz -lrt"</para>
124 </listitem>
125 </orderedlist>
126 </sect3>
127 <sect3>
128 <title>BSD</title>
129 <para>No notes are available at present, but they are desired. If you have successfully ported mod_log_sql to BSD, please contact [(chris@grubbybaby.com)||the maintaniner, Chris Powell] and help fill in this section.</para>
130 </sect3>
131 <sect3>
132 <title>Win32</title>
133 <para>No notes are available at present, but they are desired. If you have successfully ported mod_log_sql to Win32, please contact [(chris@grubbybaby.com)||the maintaniner, Chris Powell] and help fill in this section.</para>
134 </sect3>
135 <sect3>
136 <title>OS X</title>
137 <para>mod_log_sql should compile and work out-of-the-box on this platform. Here are some notes from a user successfully running the module on OS X:</para>
138 <para>The only changes I had to make were to where I had the various libraries installed. Here are the changes I made to the head of the Makefile: APACHESOURCE = /usr/local/src/apache_1.3.27 (Wasn't sure if this was really needed or not, so I downloaded the Apache source just in case) APACHEINSTALLED = /usr/sbin APACHEHEADERS = /usr/include/httpd APXS = $(APACHEINSTALLED)/apxs MYSQLLIBRARIES = /usr/local/mysql/lib MYSQLHEADERS = /usr/local/mysql/include I'm using a binary installation of MySQL and the default apache installation on OS X Client 10.2.3, the locations of these files may vary depending on how you've installed MySQL and will almost certainly be different if you're using OS X Server.</para>
139 <para> My thanks to Tom Wiebe for being the first (to my knowlege) mod_log_sql user on OS X and for providing these notes.</para>
140 </sect3>
141 <sect3>
142 <title>Digital Unix</title>
143 <para>Digital Unix, like Solaris, needs to be linked against librt; see section [sub:Solaris]. Here are further notes from a user successfully running the module on Digital Unix:</para>
144 <para>Instead of trying to get the module to remember where the MySQL libraries were, I instead compiled apache with the information: LDFLAGS='-rpath /isp/mysql/lib/mysql' ./configure ... Everything worked as expected after that. (The error I got without this was "/sbin/loader: Fatal Error: cannot map libmysqlclient.so" ) Digital Unix (v4.0f, at least ) appears to follow the same requirements needed by Solaris, so simply adding librt to the module made it compile without errors. As for the warnings, here's the text: mod_log_sql.c: In function `extract_request_duration': mod_log_sql.c:292: warning: long int format, different type arg (arg 4) mod_log_sql.c: In function `extract_request_timestamp': mod_log_sql.c:497: warning: long int format, different type arg (arg 4) Poking around in the code, it looks like the compiler was complaining that what time() is returning doesn't play nicely with %ld by default. I just typecast them as (long)'s and the warnings went away ( not that the module wasn't working correctly without them ). The module works very well so far in testing... hasn't dropped a single log entry yet. </para>
145 <para>My thanks to Jim Turner for permitting me to quote him here, and for being the first known user of mod_log_sql on Digital Unix</para>
146 </sect3>
147 </sect2>
148 <sect2>
149 <title>Do I want a DSO or a static module</title>
150 <para><remark>This section is no longer applicable, as the new autoconf setup only allows DSO with Apache 1.3 and 2.0.</remark>You need to know the answer to this question before you proceed. The answer is pretty straightforward: what have you done in the past? If you like all your Apache modules to be dynamic, then you should keep doing that. If you're more of an old-school type and prefer to compile the modules right into apache, do that. Both methods work equally well. </para>
151 <para>FWIW, the DSO method is more modern and increasing in popularity because apxs takes care of a lot of dirty little details for you. As you'll see below, the static-module method is a little more complex.</para>
152 </sect2>
153 <sect2>
154 <title>Installation as an Apache DSO (preferred)</title>
133 <orderedlist> 155 <orderedlist>
134 <listitem> 156 <listitem>
135 <para>Unpack the archive into a working directory.</para> 157 <para>Unpack the archive into a working directory.</para>
@@ -155,7 +177,7 @@ $ cd mod_log_sql-1.9</screen>
155 <listitem> 177 <listitem>
156 <para>This is the directory to search for the <filename>libmysqlclient</filename> library and the <application>MySQL</application> headers.</para> 178 <para>This is the directory to search for the <filename>libmysqlclient</filename> library and the <application>MySQL</application> headers.</para>
157 <para>The default is to search <filename>/usr/include</filename>, <filename>/usr/include/mysql</filename>, <filename>/usr/local/include</filename>, and <filename>/usr/local/include/mysql</filename> for <application>MySQL</application> headers.. And <filename>/usr/lib</filename>. <filename>/usr/lib/mysql</filename>, <filename>/usr/local/lib</filename>, and <filename>/usr/local/lin/mysql</filename> for the <application>MySQL</application> libraries.</para> 179 <para>The default is to search <filename>/usr/include</filename>, <filename>/usr/include/mysql</filename>, <filename>/usr/local/include</filename>, and <filename>/usr/local/include/mysql</filename> for <application>MySQL</application> headers.. And <filename>/usr/lib</filename>. <filename>/usr/lib/mysql</filename>, <filename>/usr/local/lib</filename>, and <filename>/usr/local/lin/mysql</filename> for the <application>MySQL</application> libraries.</para>
158 <para>Specifying this testargument will search $directory/include and $directory/mysql for <application>MySQL</application> headers. And $directory/lib and $directory/lib/mysql for <application>MySQL</application> libraries.</para> 180 <para>Specifying this argument will search $directory/include and $directory/mysql for <application>MySQL</application> headers. And $directory/lib and $directory/lib/mysql for <application>MySQL</application> libraries.</para>
159 </listitem> 181 </listitem>
160 </varlistentry> 182 </varlistentry>
161 <varlistentry> 183 <varlistentry>
@@ -179,8 +201,7 @@ $ cd mod_log_sql-1.9</screen>
179 <screen format="linespecific">$ locate ndbm.h 201 <screen format="linespecific">$ locate ndbm.h
180/usr/include/db1/ndbm.h 202/usr/include/db1/ndbm.h
181/usr/include/gdbm/ndbm.h</screen> 203/usr/include/gdbm/ndbm.h</screen>
182 <para>As far as I can tell, there is no difference as to which you specify, but it should be the one that you compiled mod_ssl with.</para> 204 <para>As far as I can tell, there is no difference as to which you specify, but it should be the one that you compiled mod_ssl with. If unsure specify the <filename>/usr/include/db1</filename>.</para>
183 <para>The default is <filename>/usr/include/db1</filename>, which should work on most systems.</para>
184 </listitem> 205 </listitem>
185 </varlistentry> 206 </varlistentry>
186 <varlistentry> 207 <varlistentry>
@@ -199,23 +220,20 @@ $ cd mod_log_sql-1.9</screen>
199 </listitem> 220 </listitem>
200 <listitem> 221 <listitem>
201 <para>Now compile the module with GNU make. You may have to specify gmake on some systems like FreeBSD.</para> 222 <para>Now compile the module with GNU make. You may have to specify gmake on some systems like FreeBSD.</para>
202 <screen>$ gmake</screen> 223 <screen>$ make</screen>
203 </listitem> 224 </listitem>
204 <listitem> 225 <listitem>
205 <para>If there were no errors, you can now install the module(s). If you compiled as a non-root user you may need to switch users with <application>su</application> or <application>sudo</application>.</para> 226 <para>If there were no errors, you can now install the module(s). If you compiled as a non-root user you may need to switch users with <application>su</application> or <application>sudo</application>.</para>
206 <screen>$ su -c "gmake install" 227 <screen>$ su -c "make install"
207Password:</screen> 228Password:</screen>
208 </listitem> 229 </listitem>
209 <listitem> 230 <listitem>
210 <para>Now edit your Apache configuration and load the modules.</para> 231 <para>Now edit your Apache configuration and load the modules.</para>
211 <remark>If you are loading the SSL logging module, you need to make sure it is loaded after mod_ssl and mod_log_sql.</remark> 232 <remark>If you are loading the SSL logging module, you need to make sure it is loaded after mod_ssl and mod_log_sql.</remark>
212 <remark>If you have previously used mod_log_sql version 1.18, the name of the module has changed from sql_log_module to log_sql_module (the first parameter to LoadModule)</remark>
213 <remark>If you are upgrading from any release earlier than 1.97 you need to add an extra LoadModule directive to load the database driver (ie mysql).</remark>
214 <orderedlist> 233 <orderedlist>
215 <listitem> 234 <listitem>
216 <para>Insert these lines to either the main <filename>httpd.conf</filename> or a file included via an include directive.</para> 235 <para>Insert these lines to either the main <filename>httpd.conf</filename> or a file included via an include directive.</para>
217 <programlisting>LoadModule log_sql_module modules/mod_log_sql.so 236 <programlisting>LoadModule log_sql_module modules/mod_log_sql.so
218LoadModule log_sql_mysql_module modules/mod_log_sql_mysql.so
219&lt;IfModule mod_ssl.c&gt; 237&lt;IfModule mod_ssl.c&gt;
220LoadModule log_sql_ssl_module moduels/mod_log_sql_ssl.so 238LoadModule log_sql_ssl_module moduels/mod_log_sql_ssl.so
221&lt;/IfModule&gt;</programlisting> 239&lt;/IfModule&gt;</programlisting>
@@ -224,7 +242,6 @@ LoadModule log_sql_ssl_module moduels/mod_log_sql_ssl.so
224 <listitem> 242 <listitem>
225 <para>If you are using Apache 1.3 you may need add these lines later in the configuration.</para> 243 <para>If you are using Apache 1.3 you may need add these lines later in the configuration.</para>
226 <programlisting>AddModule mod_log_sql.c 244 <programlisting>AddModule mod_log_sql.c
227AddModule mod_log_sql_mysql.c
228&lt;IfModule mod_ssl.c&gt; 245&lt;IfModule mod_ssl.c&gt;
229AddModule mod_log_sql_ssl.c 246AddModule mod_log_sql_ssl.c
230&lt;/IfModule&gt;</programlisting> 247&lt;/IfModule&gt;</programlisting>
@@ -235,12 +252,12 @@ AddModule mod_log_sql_ssl.c
235 </orderedlist> 252 </orderedlist>
236 </sect2> 253 </sect2>
237 </sect1> 254 </sect1>
238 <sect1 id="Sect.Configuration"> 255 <sect1>
239 <title id="Sect.Configuration.title">Configuration</title> 256 <title>&lt;sec:Configuration&gt;Configuration</title>
240 <sect2 id="Sect.Preperation"> 257 <sect2>
241 <title id="Sect.Preperation.title">Preparing MySQL for logging</title> 258 <title>&lt;sub:PrepDb&gt;Preparing MySQL for logging</title>
242 <para>You have to prepare the database to receive data from <application>mod_log_sql</application>, and set up run-time directives in <filename>httpd.conf</filename> to control how and what <application>mod_log_sql</application> logs.</para> 259 <para>You have to prepare the database to receive data from <application>mod_log_sql</application>, and set up run-time directives in <filename>httpd.conf</filename> to control how and what <application>mod_log_sql</application> logs.</para>
243 <para>This section will discuss how to get started with a basic configuration. Full documentation of all available run-time directives is available in section <xref endterm="Sect.ConfigReference.title" linkend="Sect.ConfigReference"/>.</para> 260 <para>This section will discuss how to get started with a basic configuration. Full documentation of all available run-time directives is available in section [sec:ConfRef].</para>
244 <orderedlist> 261 <orderedlist>
245 <listitem> 262 <listitem>
246 <para>mod_log_sql can make its own tables on-the-fly, or you can pre-make the tables by hand. The advantage of letting the module make the tables is ease-of-use, but for raw performance you will want to pre-make the tables in order to save some overhead. In this basic setup we'll just let the module create tables for us.</para> 263 <para>mod_log_sql can make its own tables on-the-fly, or you can pre-make the tables by hand. The advantage of letting the module make the tables is ease-of-use, but for raw performance you will want to pre-make the tables in order to save some overhead. In this basic setup we'll just let the module create tables for us.</para>
@@ -251,8 +268,8 @@ AddModule mod_log_sql_ssl.c
251Enter password: 268Enter password:
252mysql&gt; create database apachelogs;</screen> 269mysql&gt; create database apachelogs;</screen>
253 </listitem> 270 </listitem>
254 <listitem id="Item.CreateTable"> 271 <listitem>
255 <para>If you want to hand-create the tables, run the enclosed 'create-tables' SQL script as follows ("create_tables.sql" needs to be in your current working directory).</para> 272 <para>&lt;part:CrTbl&gt;If you want to hand-create the tables, run the enclosed 'create-tables' SQL script as follows ("create_tables.sql" needs to be in your current working directory).</para>
256 <screen>mysql&gt; use apachelogs 273 <screen>mysql&gt; use apachelogs
257Database changed 274Database changed
258mysql&gt; source create_tables.sql</screen> 275mysql&gt; source create_tables.sql</screen>
@@ -262,11 +279,11 @@ mysql&gt; source create_tables.sql</screen>
262 <screen>mysql&gt; grant insert,create on apachelogs.* to loguser@my.apachemachine.com identified by 'l0gger';</screen> 279 <screen>mysql&gt; grant insert,create on apachelogs.* to loguser@my.apachemachine.com identified by 'l0gger';</screen>
263 </listitem> 280 </listitem>
264 <listitem> 281 <listitem>
265 <para>You may be especially security-paranoid and want "loguser" to not have "create" capability within the "apachelogs" database. You can disable that privilege, but the cost is that you will not be able to use the module's on-the-fly table creation feature. If that cost is acceptable, hand-create the tables as described in step <xref linkend="Item.CreateTable"/> and use the following GRANT statement instead of the one above:</para> 282 <para>You may be especially security-paranoid and want "loguser" to not have "create" capability within the "apachelogs" database. You can disable that privilege, but the cost is that you will not be able to use the module's on-the-fly table creation feature. If that cost is acceptable, hand-create the tables as described in step [part:CrTbl] and use the following GRANT statement instead of the one above:</para>
266 <screen>mysql&gt; grant insert on apachelogs.* to loguser@my.apachemachine.com identified by 'l0gger';</screen> 283 <screen>mysql&gt; grant insert on apachelogs.* to loguser@my.apachemachine.com identified by 'l0gger';</screen>
267 </listitem> 284 </listitem>
268 <listitem id="Item.EnableLogging"> 285 <listitem>
269 <para>Enable full logging of your <application>MySQL</application> daemon (at least temporarily for debugging purposes) if you don't do this already. Edit /etc/my.cnf and add the following line to your [mysqld] section:</para> 286 <para>&lt;step:EnaLog&gt;Enable full logging of your <application>MySQL</application> daemon (at least temporarily for debugging purposes) if you don't do this already. Edit /etc/my.cnf and add the following line to your [mysqld] section:</para>
270 <programlisting>log=/var/log/mysql-messages</programlisting> 287 <programlisting>log=/var/log/mysql-messages</programlisting>
271 <para>Then restart <application>MySQL</application></para> 288 <para>Then restart <application>MySQL</application></para>
272 <screen># /etc/rc.d/init.d/mysql restart</screen> 289 <screen># /etc/rc.d/init.d/mysql restart</screen>
@@ -282,13 +299,14 @@ mysql&gt; source create_tables.sql</screen>
282 <para>Use the <application>MySQL</application> database called "apachelogs" running on "dbmachine.foo.com". Use username "loguser" and password "l0gg3r" to authenticate to the database. Permit the module create tables for us.</para> 299 <para>Use the <application>MySQL</application> database called "apachelogs" running on "dbmachine.foo.com". Use username "loguser" and password "l0gg3r" to authenticate to the database. Permit the module create tables for us.</para>
283 <example> 300 <example>
284 <title>Basic Example</title> 301 <title>Basic Example</title>
285 <programlisting>LogSQLLoginInfo mysql://loguser:l0gg3r@dbmachine.foo.com/apachelogs 302 <programlisting>LogSQLLoginInfo dbmachine.foo.com loguser l0gg3r
303LogSQLDatabase apachelogs
286LogSQLCreateTables on</programlisting> 304LogSQLCreateTables on</programlisting>
287 </example> 305 </example>
288 <para>If your database resides on localhost instead of another host, specify the MySQL server's socket file as follows:</para> 306 <para>If your database resides on localhost instead of another host, specify the MySQL server's socket file as follows:</para>
289 <programlisting>LogSQLDBParam socketfile /your/path/to/mysql.sock</programlisting> 307 <programlisting>LogSQLSocketFile /your/path/to/mysql.sock</programlisting>
290 <para>If your database is listening on a port other than 3306, specify the correct TCP port as follows:</para> 308 <para>If your database is listening on a port other than 3306, specify the correct TCP port as follows:</para>
291 <programlisting>LogSQLDBParam port 1234</programlisting> 309 <programlisting>LogSQLTCPPort 1234</programlisting>
292 </listitem> 310 </listitem>
293 <listitem> 311 <listitem>
294 <para>The actual logging is set up on a virtual-host-by-host basis. So, skip down to the virtual host you want to set up. Instruct this virtual host to log entries to the table "access_log" by inserting a LogSQLTransferLogTable directive. (The LogSQLTransferLogTable directive is the minimum required to log -- other directives that you will learn about later simply tune the module's behavior.)</para> 312 <para>The actual logging is set up on a virtual-host-by-host basis. So, skip down to the virtual host you want to set up. Instruct this virtual host to log entries to the table "access_log" by inserting a LogSQLTransferLogTable directive. (The LogSQLTransferLogTable directive is the minimum required to log -- other directives that you will learn about later simply tune the module's behavior.)</para>
@@ -312,7 +330,7 @@ LogSQLCreateTables on</programlisting>
312 <para>Visit your web site in a browser to trigger some hits, then confirm that the entries are being successfully logged:</para> 330 <para>Visit your web site in a browser to trigger some hits, then confirm that the entries are being successfully logged:</para>
313 <screen># mysql -hdbmachine.foo.com -umysqladmin -p -e "select * from access_log" apachelogs 331 <screen># mysql -hdbmachine.foo.com -umysqladmin -p -e "select * from access_log" apachelogs
314Enter password:</screen> 332Enter password:</screen>
315 <para>Several lines of output should follow, corresponding to your hits on the site. You now have basic functionality. Don't disable your regular Apache logs until you feel comfortable that the database is behaving as you'd like and that things are going well. If you do not see any entries in the access_log, please consult section <xref linkend="FAQ.NothingLogged"/> of the FAQ on how to debug and fix the situation.</para> 333 <para>Several lines of output should follow, corresponding to your hits on the site. You now have basic functionality. Don't disable your regular Apache logs until you feel comfortable that the database is behaving as you'd like and that things are going well. If you do not see any entries in the access_log, please consult section [faq:NothingLogged] of the FAQ on how to debug and fix the situation.</para>
316 </listitem> 334 </listitem>
317 <listitem> 335 <listitem>
318 <para>You can now activate the advanced features of mod_log_sql, which are described in the next section.</para> 336 <para>You can now activate the advanced features of mod_log_sql, which are described in the next section.</para>
@@ -324,7 +342,7 @@ Enter password:</screen>
324 <sect3> 342 <sect3>
325 <title>Instructing the module what to log</title> 343 <title>Instructing the module what to log</title>
326 <para>The most basic directive for the module is LogSQLTransferLogFormat, which tells the module which information to send to the database; logging to the database will not take place without it. Place a LogSQLTransferLogFormat directive in the VirtualHost stanza of each virtual host that you want to activate.</para> 344 <para>The most basic directive for the module is LogSQLTransferLogFormat, which tells the module which information to send to the database; logging to the database will not take place without it. Place a LogSQLTransferLogFormat directive in the VirtualHost stanza of each virtual host that you want to activate.</para>
327 <para>After LogSQLTransferLogFormat you supply a string of characters that tell the module what information to log. In the configuration directive reference (section <xref linkend="Conf.LogSQLTransferLogFormat"/>) there is a table which clearly defines all the possible things to log. Let's say you want to log only the "request time," the "remote host," and the "request"; you'd use:</para> 345 <para>After LogSQLTransferLogFormat you supply a string of characters that tell the module what information to log. In the configuration directive reference (section [sub:Frmat]) there is a table which clearly defines all the possible things to log. Let's say you want to log only the "request time," the "remote host," and the "request"; you'd use:</para>
328 <programlisting>LogSQLTransferLogFormat hUS</programlisting> 346 <programlisting>LogSQLTransferLogFormat hUS</programlisting>
329 <para>But a more appropriate string to use is</para> 347 <para>But a more appropriate string to use is</para>
330 <programlisting>LogSQLTransferLogFormat AbHhmRSsTUuv</programlisting> 348 <programlisting>LogSQLTransferLogFormat AbHhmRSsTUuv</programlisting>
@@ -340,8 +358,8 @@ Enter password:</screen>
340 </listitem> 358 </listitem>
341 </itemizedlist> 359 </itemizedlist>
342 </sect3> 360 </sect3>
343 <sect3 id="Sect.Ignore"> 361 <sect3>
344 <title id="Sect.Ignore.title" xreflabel="Using Filtering Directives">Instructing the module what NOT to log using filtering directives</title> 362 <title>&lt;sub:Ignore&gt;Instructing the module what NOT to log using filtering directives</title>
345 <para>One "accept" and two "ignore" 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.</para> 363 <para>One "accept" and two "ignore" 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.</para>
346 <para><emphasis>It is important to remember that each of these three directives is purely optional. mod_log_sql's default is to log everything.</emphasis></para> 364 <para><emphasis>It is important to remember that each of these three directives is purely optional. mod_log_sql's default is to log everything.</emphasis></para>
347 <para>When a request comes in, the contents of LogSQLRequestAccept are evaluated first. This optional, "blanket" directive lets you specify that only certain things are to be accepted for logging, and everything else discarded. Because it is evaluated before LogSQLRequestIgnore and LogSQLRemhostIgnore it can halt logging before those two filtering directives "get their chance." </para> 365 <para>When a request comes in, the contents of LogSQLRequestAccept are evaluated first. This optional, "blanket" directive lets you specify that only certain things are to be accepted for logging, and everything else discarded. Because it is evaluated before LogSQLRequestIgnore and LogSQLRemhostIgnore it can halt logging before those two filtering directives "get their chance." </para>
@@ -408,8 +426,8 @@ LogSQLRequestIgnore statistics.html bluedot.jpg</programlisting>
408 <para>There are numerous benefits. The admin will not need to create new tables for every new VirtualHost. (Although the admin will still need to drop the tables of virtual hosts that are removed.) The admin will not need to set LogSQLTransferLogTable for each virtual host -- it will be configured automatically based on the host's name. Because each virtual host will log to its own segregated table, data about one virtual server will segregate from others; an admin can grant users access to the tables they need, and they will be unable to view data about another user's virtual host.</para> 426 <para>There are numerous benefits. The admin will not need to create new tables for every new VirtualHost. (Although the admin will still need to drop the tables of virtual hosts that are removed.) The admin will not need to set LogSQLTransferLogTable for each virtual host -- it will be configured automatically based on the host's name. Because each virtual host will log to its own segregated table, data about one virtual server will segregate from others; an admin can grant users access to the tables they need, and they will be unable to view data about another user's virtual host.</para>
409 <para>In an ISP scenario the admin is likely to have a cluster of many front-end webservers logging to a back-end database. mod_log_sql has a feature that permits analysis of how well the web servers are loadbalancing: the LogSQLMachineID directive. The administrator uses this directive to assign a unique identifier to each machine in the web cluster, e.g. "LogSQLMachineID web01," "LogSQLMachineID web02," etc. Used in conjunction with the 'M' character in LogSQLTransferLogFormat, each entry in the SQL log will include the machine ID of the machine that created the entry. This permits the administrator to count the entries made by each particular machine and thereby analyze the front-end loadbalancing algorithm.</para> 427 <para>In an ISP scenario the admin is likely to have a cluster of many front-end webservers logging to a back-end database. mod_log_sql has a feature that permits analysis of how well the web servers are loadbalancing: the LogSQLMachineID directive. The administrator uses this directive to assign a unique identifier to each machine in the web cluster, e.g. "LogSQLMachineID web01," "LogSQLMachineID web02," etc. Used in conjunction with the 'M' character in LogSQLTransferLogFormat, each entry in the SQL log will include the machine ID of the machine that created the entry. This permits the administrator to count the entries made by each particular machine and thereby analyze the front-end loadbalancing algorithm.</para>
410 </sect3> 428 </sect3>
411 <sect3 id="Sect.MultiTable"> 429 <sect3>
412 <title id="Sect.MultiTable.title">Logging many-to-one data in separate tables</title> 430 <title>&lt;secMulTable&gt;Logging many-to-one data in separate tables</title>
413 <para>A given HTTP request can have a one-to-many relationship with certain kinds of data. For example, a single HTTP request can have 4 cookies, 3 headers and 5 "mod_gzip" notes associated with it. mod_log_sql is capable of logging these relationships due to the elegance of SQL relational data.</para> 431 <para>A given HTTP request can have a one-to-many relationship with certain kinds of data. For example, a single HTTP request can have 4 cookies, 3 headers and 5 "mod_gzip" notes associated with it. mod_log_sql is capable of logging these relationships due to the elegance of SQL relational data.</para>
414 <para>You already have a single table containing access requests. One of the columns in that table is 'id' which is intended to contain the unique request ID supplied by the standard Apache module mod_unique_id -- all you need to do is compile in that module and employ the LogSQLTransferLogFormat character 'I'. Thereafter, each request gets a unique ID that can be thought of as a primary key within the database, useful for joining multiple tables. So let's envision several new tables: a notes table, a cookies table, and a table for inbound and outbound headers.</para> 432 <para>You already have a single table containing access requests. One of the columns in that table is 'id' which is intended to contain the unique request ID supplied by the standard Apache module mod_unique_id -- all you need to do is compile in that module and employ the LogSQLTransferLogFormat character 'I'. Thereafter, each request gets a unique ID that can be thought of as a primary key within the database, useful for joining multiple tables. So let's envision several new tables: a notes table, a cookies table, and a table for inbound and outbound headers.</para>
415 <table> 433 <table>
@@ -573,8 +591,8 @@ where a.id=n.id and a.id='PPIDskBRH30AAGPtAsg';</screen>
573 <para>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 LogSQLMachineID directive. Assume a scenario where the production webservers have IDs like "web01," "web02," and so on -- and the test webservers have IDs like "test01," "test02," 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:</para> 591 <para>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 LogSQLMachineID directive. Assume a scenario where the production webservers have IDs like "web01," "web02," and so on -- and the test webservers have IDs like "test01," "test02," 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:</para>
574 <programlisting>delete from access_log where machine_id like 'test%';</programlisting> 592 <programlisting>delete from access_log where machine_id like 'test%';</programlisting>
575 </sect3> 593 </sect3>
576 <sect3 id="Sect.DelayedInsert"> 594 <sect3>
577 <title id="Sect.DelayedInsert.title">Optimizing for a busy database</title> 595 <title>&lt;sub:DelayedIns&gt;Optimizing for a busy database</title>
578 <para>A busy MySQL database will have SELECT statements running concurrently with INSERT and UPDATE statements. A long-running SELECT can in certain circumstances block INSERTs and therefore block mod_log_sql. A workaround is to enable mod_log_sql for "delayed inserts," which are described as follows in the MySQL documentation.</para> 596 <para>A busy MySQL database will have SELECT statements running concurrently with INSERT and UPDATE statements. A long-running SELECT can in certain circumstances block INSERTs and therefore block mod_log_sql. A workaround is to enable mod_log_sql for "delayed inserts," which are described as follows in the MySQL documentation.</para>
579 <para>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. This is a common problem when you use MySQL for logging and you also periodically run SELECT and UPDATE statements that take a long time to complete. DELAYED was introduced in MySQL Version 3.22.15. It is a MySQL extension to ANSI SQL92.</para> 597 <para>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. This is a common problem when you use MySQL for logging and you also periodically run SELECT and UPDATE statements that take a long time to complete. DELAYED was introduced in MySQL Version 3.22.15. It is a MySQL extension to ANSI SQL92.</para>
580 <para>INSERT DELAYED only works with ISAM and MyISAM tables. 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. </para> 598 <para>INSERT DELAYED only works with ISAM and MyISAM tables. 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. </para>
@@ -590,687 +608,404 @@ where a.id=n.id and a.id='PPIDskBRH30AAGPtAsg';</screen>
590 </listitem> 608 </listitem>
591 </orderedlist> 609 </orderedlist>
592 <warning> 610 <warning>
593 <para>The MySQL documentation concludes, "This means that you should only use INSERT DELAYED when you are really sure you need it!" 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 FAQ entry <xref linkend="FAQ.DelayedInsert"/> -- you have been warned.</para> 611 <para>The MySQL documentation concludes, "This means that you should only use INSERT DELAYED when you are really sure you need it!" 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 [sub:DelayedInsFAQ] in the FAQ -- you have been warned.</para>
594 </warning> 612 </warning>
595 <para>If you are experiencing issues which could be solved by delayed inserts, then set LogSqlDelayedInserts On in the <filename>httpd.conf</filename>. All regular INSERT statements are now INSERT DELAYED, and you should see no more blocking of the module.</para> 613 <para>If you are experiencing issues which could be solved by delayed inserts, then set LogSqlDelayedInserts On in the <filename>httpd.conf</filename>. All regular INSERT statements are now INSERT DELAYED, and you should see no more blocking of the module.</para>
596 </sect3> 614 </sect3>
597 </sect2> 615 </sect2>
598 <sect2 id="Sect.ConfigReference"> 616 <sect2>
599 <title id="Sect.ConfigReference.title">Configuration Directive Reference</title> 617 <title>&lt;sec:ConfRef&gt;Configuration directive reference</title>
600 <para>It is imperative that you understand which directives are used only once in the main server config, and which are used inside VirtualHost stanzas and therefore multiple times within httpd.conf. The "context" listed with each entry informs you of this.</para> 618 <para>It is imperative that you understand which directives are used only once in the main server config, and which are used inside VirtualHost stanzas and therefore multiple times within httpd.conf. The "context" listed with each entry informs you of this.</para>
601 <sect3> 619 <variablelist>
602 <title>DataBase Configuration</title> 620 <varlistentry>
603 <variablelist> 621 <term>LogSQLCookieLogTable</term>
604 <varlistentry> 622 <listitem>
605 <term>LogSQLLoginInfo</term> 623 <cmdsynopsis sepchar=" ">
606 <listitem> 624 <command>LogSQLCookieLogTable</command>
607 <cmdsynopsis> 625 <arg choice="req" rep="norepeat"><replaceable></replaceable>table-name</arg>
608 <command>LogSQLLoginInfo</command> 626 </cmdsynopsis>
609 <arg choice="req"><replaceable>connection URI</replaceable></arg> 627 <simpara>Example: LogSQLCookieLogTable cookie_log</simpara>
610 </cmdsynopsis> 628 <simpara>Default: cookies</simpara>
611 <simpara>Example: LogSQLLoginInfo mysql://logwriter:passw0rd@foobar.baz.com/Apache_log</simpara> 629 <simpara>Context: virtual host</simpara>
612 <simpara>Context: main server config</simpara> 630 <para>Defines which table is used for logging of cookies. Working in conjunction with LogSQLWhichCookies, 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.</para>
613 <para>Defines the basic connection URI to connect to the database with. The format of the connection URI is</para> 631 <note>
614 <simpara>driver://username[:password]@hostname[:port]/database</simpara> 632 <para>You must create the table (see create-tables.sql, included in the package), or LogSQLCreateTables must be set to "on".</para>
615 <variablelist> 633 </note>
616 <varlistentry> 634 </listitem>
617 <term>driver</term> 635 </varlistentry>
618 <listitem> 636 <varlistentry>
619 <simpara>The database driver to use (mysql, pgsql, etc..)</simpara> 637 <term>LogSQLCreateTables</term>
620 </listitem> 638 <listitem>
621 </varlistentry> 639 <cmdsynopsis>
622 <varlistentry> 640 <command>LogSQLCreateTables</command>
623 <term>username</term> 641 <arg choice="req">flag</arg>
624 <listitem> 642 </cmdsynopsis>
625 <simpara>The database username to login with INSERT privileges on the logging table defined in LogSQLtransferLogTable.</simpara> 643 <simpara>Example: LogSQLCreateTables On</simpara>
626 </listitem> 644 <simpara>Default: Off</simpara>
627 </varlistentry> 645 <simpara>Context: main server config</simpara>
628 <varlistentry> 646 <para>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 LogSQLMassVirtualHosting directive).</para>
629 <term>password</term> 647 <para>There is a slight disadvantage: if you wish to activate this feature, then the userid specified in LogSQLLoginInfo 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 LogSQLCreateTables. But most people -- even the very security-conscious -- will find that granting CREATE on the logging database is reasonable.</para>
630 <listitem> 648 <note>
631 <simpara>The password to use for username, and can be omitted if there is no password.</simpara> 649 <para>This is defined only once in the <filename moreinfo="none">httpd.conf</filename> file.</para>
632 </listitem> 650 </note>
633 </varlistentry> 651 </listitem>
634 <varlistentry> 652 </varlistentry>
635 <term>hostname</term> 653 <varlistentry>
636 <listitem> 654 <term>LogSQLDatabase</term>
637 <simpara>The hostname or Ip address of the Database machine, ans is simple "localhost" if the database lives on the same machine as Apache.</simpara> 655 <listitem>
638 </listitem> 656 <cmdsynopsis>
639 </varlistentry> 657 <command>LogSQLDatabase</command>
640 <varlistentry> 658 <arg choice="req"><replaceable>database</replaceable></arg>
641 <term>port</term> 659 </cmdsynopsis>
642 <listitem> 660 <simpara>Example: LogSQLDatabase loggingdb</simpara>
643 <simpara>Port on hostname to connect to the Database, if not specified use the default port for the database.</simpara> 661 <simpara>Context: main server config</simpara>
644 </listitem> 662 <para>Defines the database that is used for logging. "database" must be a valid db on the MySQL host defined in LogSQLLoginInfo</para>
645 </varlistentry> 663 <note>
646 <varlistentry> 664 <para>This is defined only once in the <filename>httpd.conf</filename> file.</para>
647 <term>database</term> 665 <para>This directive Must be defined for logging to be enabled.</para>
648 <listitem> 666 </note>
649 <simpara>The database to connect to on the server.</simpara> 667 </listitem>
650 </listitem> 668 </varlistentry>
651 </varlistentry> 669 <varlistentry>
652 </variablelist> 670 <term>LogForcePreserve</term>
653 <note> 671 <listitem>
654 <para>This is defined only once in the <filename moreinfo="none">httpd.conf</filename> file.</para> 672 <cmdsynopsis>
655 <para>This directive Must be defined for logging to be enabled.</para> 673 <command>LogSQLForcePreserve</command>
656 </note> 674 <arg choice="req">flag</arg>
657 </listitem> 675 </cmdsynopsis>
658 </varlistentry> 676 <simpara>Example: LogForcePreserve On</simpara>
659 <varlistentry> 677 <simpara>Default: Off</simpara>
660 <term>LogSQLDBParam</term> 678 <simpara>Context: main server config</simpara>
661 <listitem> 679 <para>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.</para>
662 <cmdsynopsis sepchar=" "> 680 <para>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.</para>
663 <command moreinfo="none">LogSQLDBParam</command> 681 <note>
664 <arg choice="req" rep="norepeat"><replaceable>parameter-name</replaceable></arg> 682 <para>This is defined only once in the <filename>httpd.conf</filename> file.</para>
665 <arg choice="req" rep="norepeat"><replaceable>value</replaceable></arg> 683 </note>
666 </cmdsynopsis> 684 </listitem>
667 <simpara>Example: LogSQLDBParam socketfile /var/lib/mysql/mysql.socket</simpara> 685 </varlistentry>
668 <simpara>Context: main server config</simpara> 686 <varlistentry>
669 <para>This is the new method of specifying Database connection credentials and settings. This is used to define database driver specific options. For a list of options read the documentation for each specific database driver.</para> 687 <term>LogSQLHeadersInLogTable</term>
670 <note> 688 <listitem>
671 <para>Each parameter-name may only be defined once.</para> 689 <cmdsynopsis>
672 </note> 690 <command>LogSQLHeadersInLogTable</command>
673 </listitem> 691 <arg choice="req"><replaceable>table-name</replaceable></arg>
674 </varlistentry> 692 </cmdsynopsis>
675 <varlistentry> 693 <simpara>Example: LogSQLHeadersInLogTable headers</simpara>
676 <term>LogSQLCreateTables</term> 694 <simpara>Default: headers_in</simpara>
677 <listitem> 695 <simpara>Context: virtual host</simpara>
678 <cmdsynopsis sepchar=" "> 696 <para>Defines which table is used for logging of inbound headers. Working in conjunction with LogSQLWhichHeadersIn, 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_unique_id.</para>
679 <command moreinfo="none">LogSQLCreateTables</command> 697 <note>
680 <arg choice="req" rep="norepeat">flag</arg> 698 <para>Note that you must create the table (see create-tables.sql, included in the package), or LogSQLCreateTables must be set to "on".</para>
681 </cmdsynopsis> 699 </note>
682 <simpara>Example: LogSQLCreateTables On</simpara> 700 </listitem>
683 <simpara>Default: Off</simpara> 701 </varlistentry>
684 <simpara>Context: main server config</simpara> 702 <varlistentry>
685 <para>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 LogSQLMassVirtualHosting directive).</para> 703 <term>LogSQLHeadersOutLogTable</term>
686 <para>There is a slight disadvantage: if you wish to activate this feature, then the userid specified in LogSQLLoginInfo 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 LogSQLCreateTables. But most people -- even the very security-conscious -- will find that granting CREATE on the logging database is reasonable.</para> 704 <listitem>
687 <note> 705 <cmdsynopsis sepchar=" ">
688 <para>This is defined only once in the <filename moreinfo="none">httpd.conf</filename> file.</para> 706 <command moreinfo="none">LogSQLHeadersOutLogTable</command>
689 </note> 707 <arg choice="req" rep="norepeat"><replaceable>table-name</replaceable></arg>
690 </listitem> 708 </cmdsynopsis>
691 </varlistentry> 709 <simpara>Example: LogSQLHeadersOutLogTable headers</simpara>
692 <varlistentry> 710 <simpara>Default: headers_out</simpara>
693 <term>LogSQLForcePreserve</term> 711 <simpara>Context: virtual host</simpara>
694 <listitem> 712 <para>Defines which table is used for logging of outbound headers. Working in conjunction with LogSQLWhichHeadersOut, 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_unique_id.</para>
695 <cmdsynopsis sepchar=" "> 713 <note>
696 <command moreinfo="none">LogSQLForcePreserve</command> 714 <para>Note that you must create the table (see create-tables.sql, included in the package), or LogSQLCreateTables must be set to "on".</para>
697 <arg choice="req" rep="norepeat">flag</arg> 715 </note>
698 </cmdsynopsis> 716 </listitem>
699 <simpara>Example: LogForcePreserve On</simpara> 717 </varlistentry>
700 <simpara>Default: Off</simpara> 718 <varlistentry>
701 <simpara>Context: main server config</simpara> 719 <term>LogSQLLoginInfo</term>
702 <para>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.</para> 720 <listitem>
703 <para>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.</para> 721 <cmdsynopsis>
704 <note> 722 <command>LogSQLLoginInfo</command>
705 <para>This is defined only once in the <filename moreinfo="none">httpd.conf</filename> file.</para> 723 <arg choice="req"><replaceable>host</replaceable></arg>
706 </note> 724 <arg choice="req"><replaceable>user</replaceable></arg>
707 </listitem> 725 <arg choice="req"><replaceable>password</replaceable></arg>
708 </varlistentry> 726 </cmdsynopsis>
709 <varlistentry> 727 <simpara>Example: LogSQLLoginInfo foobar.baz.com logwriter passw0rd</simpara>
710 <term>LogSQLMachineID</term> 728 <simpara>Context: main server config</simpara>
711 <listitem> 729 <para>Defines the general parameters of the MySQL host to which you will be logging. "host" is the hostname or IP address of the MySQL machine, and is simply "localhost" if the database lives on the same machine as Apache. "user" is the MySQL userid (not a Unix userid!) with INSERT privileges on the table defined in LogSQLTransferLogTable. "password" is that user's password.</para>
712 <cmdsynopsis sepchar=" "> 730 <note>
713 <command moreinfo="none">LogSQLMachineID</command> 731 <para>This is defined only once in the <filename moreinfo="none">httpd.conf</filename> file.</para>
714 <arg choice="req" rep="norepeat">machineID</arg> 732 <para>This directive Must be defined for logging to be enabled.</para>
715 </cmdsynopsis> 733 </note>
716 <simpara>Example: LogSQLMachineID web01</simpara> 734 </listitem>
717 <simpara>Context: main server config</simpara> 735 </varlistentry>
718 <para>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 load-balancing methodology. LogSQLMachineID permits you to distinguish each machine's entries if you assign each machine its own LogSQLMachineID: for example, the first webserver gets ``LogSQLMachineID web01,'' the second gets ``LogSQLMachineID web02,'' etc.</para> 736 <varlistentry>
719 <note> 737 <term>LogSQLMachineID</term>
720 <para>This is defined only once in the <filename moreinfo="none">httpd.conf</filename> file.</para> 738 <listitem>
721 </note> 739 <cmdsynopsis>
722 </listitem> 740 <command></command>
723 </varlistentry> 741 <arg></arg>
724 <varlistentry> 742 </cmdsynopsis>
725 <term>LogSQlPreserveFile</term> 743 <simpara></simpara>
726 <listitem> 744 <simpara></simpara>
727 <cmdsynopsis sepchar=" "> 745 <simpara></simpara>
728 <command moreinfo="none">LogSQLPreserveFile</command> 746 <para></para>
729 <arg choice="req" rep="norepeat"><replaceable>filename</replaceable></arg> 747 <para></para>
730 </cmdsynopsis> 748 <note>
731 <simpara>Example: LogSQLPreserveFile offline-preserve</simpara> 749 <para><filename></filename></para>
732 <simpara>Default: /tmp/sql-preserve</simpara> 750 </note>
733 <simpara>Context: virtual host</simpara> 751 </listitem>
734 <para>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:</para> 752 </varlistentry>
735 <screen format="linespecific"># mysql -uadminuser -p mydbname &lt; /tmp/sql-preserve</screen> 753 <varlistentry>
736 <para>If you do not define LogSQLPreserveFile then all virtual servers will log to the same default preserve file (<filename moreinfo="none">/tmp/sql-preserve</filename>). 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 LogSQLTransferLogFormat directive. It is only necessary to segregate preserve-files by virualhost if you also segregate access logs by virtualhost.</para> 754 <term>LogSQLMassVirtualHosting</term>
737 <para>The module will log to Apache's ErrorLog 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.</para> 755 <listitem>
738 <para>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 &amp; group ID of the running Apache process (e.g. 'nobody' on many Linux distributions).</para> 756 <cmdsynopsis>
739 </listitem> 757 <command></command>
740 </varlistentry> 758 <arg></arg>
741 </variablelist> 759 </cmdsynopsis>
742 </sect3> 760 <simpara></simpara>
743 <sect3> 761 <simpara></simpara>
744 <title>Table Names</title> 762 <simpara></simpara>
745 <variablelist> 763 <para></para>
746 <varlistentry> 764 <para></para>
747 <term>LogSQLTransferLogTable</term> 765 <note>
748 <listitem> 766 <para><filename></filename></para>
749 <cmdsynopsis sepchar=" "> 767 </note>
750 <command moreinfo="none">LogSQLTransferLogTable</command> 768 </listitem>
751 <arg choice="req" rep="norepeat"><replaceable>table-name</replaceable></arg> 769 </varlistentry>
752 </cmdsynopsis> 770 <varlistentry>
753 <simpara>Example: LogSQLTransferLogTable access_log_table</simpara> 771 <term>LogSQLNotesLogTable</term>
754 <simpara>Context: virtual host</simpara> 772 <listitem>
755 <para>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 the LogSQLLoginInfo connection URI.</para> 773 <cmdsynopsis>
756 <para>This directive is <emphasis>not</emphasis> necessary if you declare LogSQLMassVirtualHosting On, since that directive activates dynamically-named tables. If you attempt to use LogSqlTransferlogTable at the same time a warning will be logged and it will be ignored, since LogSQLMassVirtualHosting takes priority.</para> 774 <command></command>
757 <note> 775 <arg></arg>
758 <para>Requires unless LogSQLMassVirtualHosting is set to On</para> 776 </cmdsynopsis>
759 </note> 777 <simpara></simpara>
760 </listitem> 778 <simpara></simpara>
761 </varlistentry> 779 <simpara></simpara>
762 <varlistentry> 780 <para></para>
763 <term>LogSQLCookieLogTable</term> 781 <para></para>
764 <listitem> 782 <note>
765 <cmdsynopsis sepchar=" "> 783 <para><filename></filename></para>
766 <command moreinfo="none">LogSQLCookieLogTable</command> 784 </note>
767 <arg choice="req" rep="norepeat"><replaceable></replaceable>table-name</arg> 785 </listitem>
768 </cmdsynopsis> 786 </varlistentry>
769 <simpara>Example: LogSQLCookieLogTable cookie_log</simpara> 787 <varlistentry>
770 <simpara>Default: cookies</simpara> 788 <term>LogSQlPreserveFile</term>
771 <simpara>Context: virtual host</simpara> 789 <listitem>
772 <para>Defines which table is used for logging of cookies. Working in conjunction with LogSQLWhichCookies, 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.</para> 790 <cmdsynopsis>
773 <note> 791 <command></command>
774 <para>You must create the table (see create-tables.sql, included in the package), or LogSQLCreateTables must be set to "on".</para> 792 <arg></arg>
775 </note> 793 </cmdsynopsis>
776 </listitem> 794 <simpara></simpara>
777 </varlistentry> 795 <simpara></simpara>
778 <varlistentry> 796 <simpara></simpara>
779 <term>LogSQLHeadersInLogTable</term> 797 <para></para>
780 <listitem> 798 <para></para>
781 <cmdsynopsis sepchar=" "> 799 <note>
782 <command moreinfo="none">LogSQLHeadersInLogTable</command> 800 <para><filename></filename></para>
783 <arg choice="req" rep="norepeat"><replaceable>table-name</replaceable></arg> 801 </note>
784 </cmdsynopsis> 802 </listitem>
785 <simpara>Example: LogSQLHeadersInLogTable headers</simpara> 803 </varlistentry>
786 <simpara>Default: headers_in</simpara> 804 <varlistentry>
787 <simpara>Context: virtual host</simpara> 805 <term>LogSQLRemhostIgnore</term>
788 <para>Defines which table is used for logging of inbound headers. Working in conjunction with LogSQLWhichHeadersIn, 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_unique_id.</para> 806 <listitem>
789 <note> 807 <cmdsynopsis>
790 <para>Note that you must create the table (see create-tables.sql, included in the package), or LogSQLCreateTables must be set to "on".</para> 808 <command></command>
791 </note> 809 <arg></arg>
792 </listitem> 810 </cmdsynopsis>
793 </varlistentry> 811 <simpara></simpara>
794 <varlistentry> 812 <simpara></simpara>
795 <term>LogSQLHeadersOutLogTable</term> 813 <simpara></simpara>
796 <listitem> 814 <para></para>
797 <cmdsynopsis sepchar=" "> 815 <para></para>
798 <command moreinfo="none">LogSQLHeadersOutLogTable</command> 816 <note>
799 <arg choice="req" rep="norepeat"><replaceable>table-name</replaceable></arg> 817 <para><filename></filename></para>
800 </cmdsynopsis> 818 </note>
801 <simpara>Example: LogSQLHeadersOutLogTable headers</simpara> 819 </listitem>
802 <simpara>Default: headers_out</simpara> 820 </varlistentry>
803 <simpara>Context: virtual host</simpara> 821 <varlistentry>
804 <para>Defines which table is used for logging of outbound headers. Working in conjunction with LogSQLWhichHeadersOut, 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_unique_id.</para> 822 <term>LogSQLRequestAccept</term>
805 <note> 823 <listitem>
806 <para>Note that you must create the table (see create-tables.sql, included in the package), or LogSQLCreateTables must be set to "on".</para> 824 <cmdsynopsis>
807 </note> 825 <command></command>
808 </listitem> 826 <arg></arg>
809 </varlistentry> 827 </cmdsynopsis>
810 <varlistentry> 828 <simpara></simpara>
811 <term>LogSQLNotesLogTable</term> 829 <simpara></simpara>
812 <listitem> 830 <simpara></simpara>
813 <cmdsynopsis sepchar=" "> 831 <para></para>
814 <command moreinfo="none">LogSQLNotesLogTable</command> 832 <para></para>
815 <arg choice="req" rep="norepeat"><replaceable>table-name</replaceable></arg> 833 <note>
816 </cmdsynopsis> 834 <para><filename></filename></para>
817 <simpara>Example: LogSQLNotesLogTable notes-log</simpara> 835 </note>
818 <simpara>Default: notes</simpara> 836 </listitem>
819 <simpara>Context: virtual_host</simpara> 837 </varlistentry>
820 <para>Defines which table is used for logging of notes. Working in conjunction with LogSQLWhichNotes, 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.</para> 838 <varlistentry>
821 <note> 839 <term>LogSQLRequestIgnore</term>
822 <para>This table must be created (see create-tables.sql included in the package), or LogSQLCreateTables must be set to 'On'.</para> 840 <listitem>
823 </note> 841 <cmdsynopsis>
824 </listitem> 842 <command></command>
825 </varlistentry> 843 <arg></arg>
826 <varlistentry> 844 </cmdsynopsis>
827 <term>LogSQLMassVirtualHosting</term> 845 <simpara></simpara>
828 <listitem> 846 <simpara></simpara>
829 <cmdsynopsis sepchar=" "> 847 <simpara></simpara>
830 <command moreinfo="none">LogSQLMassVirtualHosting</command> 848 <para></para>
831 <arg choice="req" rep="norepeat">flag</arg> 849 <para></para>
832 </cmdsynopsis> 850 <note>
833 <simpara>Example: LogSQLMassVirtualHosting On</simpara> 851 <para><filename></filename></para>
834 <simpara>Default: Off</simpara> 852 </note>
835 <simpara>Context: main server config</simpara> 853 </listitem>
836 <para>If you administer a site hosting many, many virtual hosts then this option will appeal to you. If you turn on LogSQLMassVirtualHosting then several things happen:</para> 854 </varlistentry>
837 <itemizedlist> 855 <varlistentry>
838 <listitem> 856 <term>LogSQLSocketFile</term>
839 <para>the on-the-fly table creation feature is activated automatically</para> 857 <listitem>
840 </listitem> 858 <cmdsynopsis>
841 <listitem> 859 <command></command>
842 <para>the transfer log table name is dynamically set from the virtual host's name after stripping out SQL-unfriendly characters (example: a virtual host www.grubbybaby.com gets logged to table access_www_grubbybaby_com)</para> 860 <arg></arg>
843 </listitem> 861 </cmdsynopsis>
844 <listitem> 862 <simpara></simpara>
845 <para>which, in turn, means that each virtual host logs to its own segregated table. 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.</para> 863 <simpara></simpara>
846 </listitem> 864 <simpara></simpara>
847 </itemizedlist> 865 <para></para>
848 <para>This is a huge boost in convenience for sites with many virtual servers. Activating LogSQLMassVirtualHosting obviates the need to create every virtual server's table and provides more granular security possibilities.</para> 866 <para></para>
849 <note> 867 <note>
850 <para>This is defined only once in the <filename moreinfo="none">httpd.conf</filename> file.</para> 868 <para><filename></filename></para>
851 </note> 869 </note>
852 </listitem> 870 </listitem>
853 </varlistentry> 871 </varlistentry>
854 </variablelist> 872 <varlistentry>
855 </sect3> 873 <term>LogSQLTCPPort</term>
856 <sect3> 874 <listitem>
857 <title>Configuring What Is logged</title> 875 <cmdsynopsis>
858 <variablelist> 876 <command></command>
859 <varlistentry id="Conf.LogSQLTransferLogFormat"> 877 <arg></arg>
860 <term>LogSQLTransferLogFormat </term> 878 </cmdsynopsis>
861 <listitem> 879 <simpara></simpara>
862 <cmdsynopsis sepchar=" "> 880 <simpara></simpara>
863 <command moreinfo="none">LogSQLTransferLogFormat</command> 881 <simpara></simpara>
864 <arg choice="req" rep="norepeat"><replaceable>format-string</replaceable></arg> 882 <para></para>
865 </cmdsynopsis> 883 <para></para>
866 <simpara>Example: LogSQLTransferLogFormat huSUTv</simpara> 884 <note>
867 <simpara>Default: AbHhmRSsTUuv</simpara> 885 <para><filename></filename></para>
868 <simpara>Context: virtual host</simpara> 886 </note>
869 <para>Each character in the format-string defines an attribute of the request that you wish to log. The default logs the information required to create Combined Log Format logs, plus several extras. Here is the full list of allowable keys, which sometimes resemble their Apache counterparts, but do not always:</para> 887 </listitem>
870 <table> 888 </varlistentry>
871 <title>Core LogFormat parameters</title> 889 <varlistentry>
872 <tgroup cols="5"> 890 <term>&lt;sub:Frmat&gt;LogSQLTransferLogFormat </term>
873 <colspec colname="1" colnum="1"/> 891 <listitem>
874 <colspec colname="2" colnum="2"/> 892 <cmdsynopsis>
875 <colspec colname="3" colnum="3"/> 893 <command></command>
876 <colspec colname="4" colnum="4"/> 894 <arg></arg>
877 <colspec colname="5" colnum="5"/> 895 </cmdsynopsis>
878 <thead> 896 <simpara></simpara>
879 <row> 897 <simpara></simpara>
880 <entry colname="1">Symbol</entry> 898 <simpara></simpara>
881 <entry colname="2">Meaning</entry> 899 <para></para>
882 <entry colname="3">DB Field</entry> 900 <para></para>
883 <entry colname="4">Data Type</entry> 901 <note>
884 <entry colname="5">Example</entry> 902 <para><filename></filename></para>
885 </row> 903 </note>
886 </thead> 904 </listitem>
887 <tbody> 905 </varlistentry>
888 <row> 906 <varlistentry>
889 <entry colname="1">A</entry> 907 <term>LogSQLTransferLogTable</term>
890 <entry colname="2">User Agent</entry> 908 <listitem>
891 <entry colname="3">agent</entry> 909 <cmdsynopsis>
892 <entry colname="4">varchar(255)</entry> 910 <command></command>
893 <entry colname="5">Mozilla/4.0 (compat; MSIE 6.0; Windows)</entry> 911 <arg></arg>
894 </row> 912 </cmdsynopsis>
895 <row> 913 <simpara></simpara>
896 <entry colname="1">a</entry> 914 <simpara></simpara>
897 <entry colname="2">CGi request arguments</entry> 915 <simpara></simpara>
898 <entry colname="3">request_args</entry> 916 <para></para>
899 <entry colname="4">varchar(255)</entry> 917 <para></para>
900 <entry colname="5">user=Smith&amp;cart=1231&amp;item=532</entry> 918 <note>
901 </row> 919 <para><filename></filename></para>
902 <row> 920 </note>
903 <entry colname="1">b</entry> 921 </listitem>
904 <entry colname="2">Bytes transfered</entry> 922 </varlistentry>
905 <entry colname="3">bytes_sent</entry> 923 <varlistentry>
906 <entry colname="4">int unsigned</entry> 924 <term>LogSQLWhichCookie</term>
907 <entry colname="5">32561</entry> 925 <listitem>
908 </row> 926 <cmdsynopsis>
909 <row> 927 <command></command>
910 <entry colname="1">c<xref linkend="Foot.LogCookie" xreflabel="[1]"/></entry> 928 <arg></arg>
911 <entry colname="2">Text of cookie</entry> 929 </cmdsynopsis>
912 <entry colname="3">cookie</entry> 930 <simpara></simpara>
913 <entry colname="4">varchar(255)</entry> 931 <simpara></simpara>
914 <entry colname="5">Apache=sdyn.fooonline.net 1300102700823</entry> 932 <simpara></simpara>
915 </row> 933 <para></para>
916 <row> 934 <para></para>
917 <entry>f</entry> 935 <note>
918 <entry>Local filename requested</entry> 936 <para><filename></filename></para>
919 <entry>request_file</entry> 937 </note>
920 <entry>varchar(255)</entry> 938 </listitem>
921 <entry>/var/www/html/books-cycroad.html</entry> 939 </varlistentry>
922 </row> 940 <varlistentry>
923 <row> 941 <term>LogSQLWhichCookies</term>
924 <entry>H</entry> 942 <listitem>
925 <entry>HTTP request_protocol</entry> 943 <cmdsynopsis>
926 <entry>request_protocol</entry> 944 <command></command>
927 <entry>varchar(10)</entry> 945 <arg></arg>
928 <entry>HTTP/1.1</entry> 946 </cmdsynopsis>
929 </row> 947 <simpara></simpara>
930 <row> 948 <simpara></simpara>
931 <entry>h</entry> 949 <simpara></simpara>
932 <entry>Name of remote host</entry> 950 <para></para>
933 <entry>remote_host</entry> 951 <para></para>
934 <entry>varchar(50)</entry> 952 <note>
935 <entry>blah.foobar.com</entry> 953 <para><filename></filename></para>
936 </row> 954 </note>
937 <row> 955 </listitem>
938 <entry>I</entry> 956 </varlistentry>
939 <entry>Request ID (from modd_unique_id)</entry> 957 <varlistentry>
940 <entry>id</entry> 958 <term>LogSQLWhichHeadersIn</term>
941 <entry>char(19)</entry> 959 <listitem>
942 <entry>POlFcUBRH30AAALdBG8</entry> 960 <cmdsynopsis>
943 </row> 961 <command></command>
944 <row> 962 <arg></arg>
945 <entry>l</entry> 963 </cmdsynopsis>
946 <entry>Ident user info</entry> 964 <simpara></simpara>
947 <entry>remote_logname</entry> 965 <simpara></simpara>
948 <entry>varcgar(50)</entry> 966 <simpara></simpara>
949 <entry>bobby</entry> 967 <para></para>
950 </row> 968 <para></para>
951 <row> 969 <note>
952 <entry>M</entry> 970 <para><filename></filename></para>
953 <entry>Machine ID<xref linkend="Foot.MachineID" xreflabel="[2]"/></entry> 971 </note>
954 <entry>machine_id</entry> 972 </listitem>
955 <entry>varchar(25)</entry> 973 </varlistentry>
956 <entry>web01</entry> 974 <varlistentry>
957 </row> 975 <term>LogSQLWhichHeadersOut</term>
958 <row> 976 <listitem>
959 <entry>m</entry> 977 <cmdsynopsis>
960 <entry>HTTP request method</entry> 978 <command></command>
961 <entry>request_method</entry> 979 <arg></arg>
962 <entry>varchar(10)</entry> 980 </cmdsynopsis>
963 <entry>GET</entry> 981 <simpara></simpara>
964 </row> 982 <simpara></simpara>
965 <row> 983 <simpara></simpara>
966 <entry>P</entry> 984 <para></para>
967 <entry>httpd cchild PID</entry> 985 <para></para>
968 <entry>child_pid</entry> 986 <note>
969 <entry>smallint unsigned</entry> 987 <para><filename></filename></para>
970 <entry>3215</entry> 988 </note>
971 </row> 989 </listitem>
972 <row> 990 </varlistentry>
973 <entry>p</entry> 991 <varlistentry>
974 <entry>http port</entry> 992 <term>LogSQLWhichNotes</term>
975 <entry>server_port</entry> 993 <listitem>
976 <entry>smallint unsigned</entry> 994 <cmdsynopsis>
977 <entry>80</entry> 995 <command></command>
978 </row> 996 <arg></arg>
979 <row> 997 </cmdsynopsis>
980 <entry>R</entry> 998 <simpara></simpara>
981 <entry>Referer</entry> 999 <simpara></simpara>
982 <entry>referer</entry> 1000 <simpara></simpara>
983 <entry>varchar(255)</entry> 1001 <para></para>
984 <entry>http://www.biglinks4u.com/linkpage.html</entry> 1002 <para></para>
985 </row> 1003 <note>
986 <row> 1004 <para><filename></filename></para>
987 <entry>r</entry> 1005 </note>
988 <entry>Request in full form</entry> 1006 </listitem>
989 <entry>request_line</entry> 1007 </varlistentry>
990 <entry>varchar(255)</entry> 1008 </variablelist>
991 <entry>GET /books-cycroad.html HTTP/1.1</entry>
992 </row>
993 <row>
994 <entry>S</entry>
995 <entry>Time of request in UNIX time_t format</entry>
996 <entry>time_stamp</entry>
997 <entry>int unsigned</entry>
998 <entry>1005598029</entry>
999 </row>
1000 <row>
1001 <entry>T</entry>
1002 <entry>Seconds to service request</entry>
1003 <entry>request_duration</entry>
1004 <entry>smallint unsigned</entry>
1005 <entry>2</entry>
1006 </row>
1007 <row>
1008 <entry>t</entry>
1009 <entry>Time of request in human format</entry>
1010 <entry>request_time</entry>
1011 <entry>char(28)</entry>
1012 <entry> [02/Dec/2001:15:01:26 -0800]</entry>
1013 </row>
1014 <row>
1015 <entry>U</entry>
1016 <entry>Request in simple form</entry>
1017 <entry>request_uri</entry>
1018 <entry>varchar(255)</entry>
1019 <entry>/books-cycroad.html</entry>
1020 </row>
1021 <row>
1022 <entry>u</entry>
1023 <entry>User info from HTTP auth</entry>
1024 <entry>remote_user</entry>
1025 <entry>varchar(50)</entry>
1026 <entry>bobby</entry>
1027 </row>
1028 <row>
1029 <entry>v</entry>
1030 <entry>Virtual host servicing the request</entry>
1031 <entry>virtual_host</entry>
1032 <entry>varchar(255)</entry>
1033 <entry>www.foobar.com</entry>
1034 </row>
1035 </tbody>
1036 </tgroup>
1037 </table>
1038 <note id="Foot.LogCookie">
1039 <simpara>[1] You must also specify LogSQLWhichCookie for this to take effect.</simpara>
1040 </note>
1041 <note id="Foot.MachineID">
1042 <simpara>[2] You must also specify LogSQLmachineID for this to take effect.</simpara>
1043 </note>
1044 <table>
1045 <title>SSL LogFormat Parameters</title>
1046 <tgroup cols="5">
1047 <colspec colname="1" colnum="1"/>
1048 <colspec colname="2" colnum="2"/>
1049 <colspec colname="3" colnum="3"/>
1050 <colspec colname="4" colnum="4"/>
1051 <colspec colname="5" colnum="5"/>
1052 <thead>
1053 <row>
1054 <entry colname="1">Symbol</entry>
1055 <entry colname="2">Meaning</entry>
1056 <entry colname="3">DB Field</entry>
1057 <entry colname="4">Data Type</entry>
1058 <entry colname="5">Example</entry>
1059 </row>
1060 </thead>
1061 <tbody>
1062 <row>
1063 <entry colname="1">z</entry>
1064 <entry colname="2">SSL cipher used</entry>
1065 <entry colname="3">ssl_cipher</entry>
1066 <entry colname="4">varchar(25)</entry>
1067 <entry colname="5">RC4-MD5</entry>
1068 </row>
1069 <row>
1070 <entry colname="1">q</entry>
1071 <entry colname="2">Keysize of the SSL connection</entry>
1072 <entry colname="3">ssl_keysize</entry>
1073 <entry colname="4">smallint unsigned</entry>
1074 <entry colname="5">56</entry>
1075 </row>
1076 <row>
1077 <entry colname="1">Q</entry>
1078 <entry colname="2">maximum keysize supported</entry>
1079 <entry colname="3">ssl_maxkeysize</entry>
1080 <entry colname="4">smallint unsigned</entry>
1081 <entry colname="5">128</entry>
1082 </row>
1083 </tbody>
1084 </tgroup>
1085 </table>
1086 </listitem>
1087 </varlistentry>
1088 <varlistentry>
1089 <term>LogSQLRemhostIgnore</term>
1090 <listitem>
1091 <cmdsynopsis sepchar=" ">
1092 <command moreinfo="none">LogSQLRemhostIgnore</command>
1093 <arg choice="req" rep="repeat"><replaceable>hostname</replaceable></arg>
1094 </cmdsynopsis>
1095 <simpara>Example: LogSQLRemhostIgnore localnet.com</simpara>
1096 <simpara>Context: virtual host</simpara>
1097 <para>Lists a series of strings that, if present in the REMOTE_HOST, will cause that request to <emphasis>not</emphasis> 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 <xref endterm="Sect.Ignore.title" linkend="Sect.Ignore"/> for some tips for using this directive.</para>
1098 <para>Each string may contain a + or - prefix in a &lt;VirtualHost&gt; context and will cause those strings to be added (+) or removed (-) from the global configuration. Otherwise the global is completely ignored and overridden if defined in a &lt;VirtualHost&gt;</para>
1099 <para>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.</para>
1100 </listitem>
1101 </varlistentry>
1102 <varlistentry>
1103 <term>LogSQLRequestAccept</term>
1104 <listitem>
1105 <cmdsynopsis sepchar=" ">
1106 <command moreinfo="none">LogSQLRequestAccept</command>
1107 <arg choice="req" rep="repeat"><replaceable>hostname</replaceable></arg>
1108 </cmdsynopsis>
1109 <simpara>Example: LogSQLRequestAccept .html .php .jpg</simpara>
1110 <simpara>Default: if not specified, all requests are 'accepted'</simpara>
1111 <simpara>Context: virtual host</simpara>
1112 <para>Lists a series of strings that, if present in the URI, will permit that request to be considered for logging (depending on additional filtering by the "ignore" directives). Any request that fails to match one of the LogSQLRequestAccept entries will be discarded.</para>
1113 <para>Each string may contain a + or - prefix in a &lt;VirtualHost&gt; context and will cause those strings to be added (+) or removed (-) from the global configuration. Otherwise the global is completely ignored and overridden if defined in a &lt;VirtualHost&gt;</para>
1114 <para>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 <xref endterm="Sect.Ignore.title" linkend="Sect.Ignore"/> for some tips for using this directive.</para>
1115 <para>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.</para>
1116 <para>This directive is completely optional. It is more general than LogSQLRequestIgnore and is evaluated before LogSQLRequestIgnore . If this directive is not used, <emphasis>all</emphasis> 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.</para>
1117 </listitem>
1118 </varlistentry>
1119 <varlistentry>
1120 <term>LogSQLRequestIgnore</term>
1121 <listitem>
1122 <cmdsynopsis sepchar=" ">
1123 <command moreinfo="none">LogSQLRequestIgnore</command>
1124 <arg choice="req" rep="repeat"><replaceable>hostname</replaceable></arg>
1125 </cmdsynopsis>
1126 <simpara>Example: LogSQLRequestIgnore root.exe cmd.exe default.ida favicon.ico</simpara>
1127 <simpara>Context: virtual host</simpara>
1128 <para>Lists a series of strings that, if present in the URI, will cause that request to <emphasis>NOT</emphasis> be logged. This directive is useful for cutting down on log clutter when you are certain that you want to ignore requests for certain objects. See section <xref endterm="Sect.Ignore.title" linkend="Sect.Ignore"/> for some tips for using this directive.</para>
1129 <para>Each string may contain a + or - prefix in a &lt;VirtualHost&gt; context and will cause those strings to be added (+) or removed (-) from the global configuration. Otherwise the global is completely ignored and overridden if defined in a &lt;VirtualHost&gt;</para>
1130 <para>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.</para>
1131 </listitem>
1132 </varlistentry>
1133 <varlistentry>
1134 <term>LogSQLWhichCookie</term>
1135 <listitem>
1136 <cmdsynopsis sepchar=" ">
1137 <command moreinfo="none">LogSQLWhichCookie</command>
1138 <arg choice="req" rep="norepeat"><replaceable>cookiename</replaceable></arg>
1139 </cmdsynopsis>
1140 <simpara>Example; LogSQLWhichCookie Clicks</simpara>
1141 <simpara>Context: virtual host</simpara>
1142 <para>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.</para>
1143 <para>mod_log_sql allows you to log cookie information. LogSQL_WhichCookie 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.</para>
1144 <note>
1145 <para>You must include a 'c' character in LogSQLTransferLogFormat for this directive to take effect.</para>
1146 <para>although this was origintally intended for people using mod_usertrack to create user-tracking cookies, you are not restricted in any way. You can choose which cookie you wish to log to the database - any cookie at all - and it does not necessarily have to have anything to do with mod_usertrack.</para>
1147 </note>
1148 </listitem>
1149 </varlistentry>
1150 <varlistentry>
1151 <term>LogSQLWhichCookies</term>
1152 <listitem>
1153 <cmdsynopsis sepchar=" ">
1154 <command moreinfo="none">LogSQLWhichCookies</command>
1155 <arg choice="req" rep="repeat"><replaceable>cookie-name</replaceable></arg>
1156 </cmdsynopsis>
1157 <simpara>Example: logSQLWhichCookies userlogin cookie1 cookie2</simpara>
1158 <simpara>Context: virtual host</simpara>
1159 <para>Defines the list of cookies you would like logged. This works in conjunction with LogSQLCookieLogTable. This directive does <emphasis>not</emphasis> require any additional characters to be added to the LogSQLTransferLogFormat string. The feature is activated simply by including this directive, upon which you will begin populating the separate cookie table with data.</para>
1160 <para>Each string may contain a + or - prefix in a &lt;VirtualHost&gt; context and will cause those strings to be added (+) or removed (-) from the global configuration. Otherwise the global is completely ignored and overridden if defined in a &lt;VirtualHost&gt;</para>
1161 <note>
1162 <para>The table must be created (see create-tables.sql, included in the package), or LogSQLCreateTables must be set to 'On'.</para>
1163 </note>
1164 </listitem>
1165 </varlistentry>
1166 <varlistentry>
1167 <term>LogSQLWhichHeadersIn</term>
1168 <listitem>
1169 <cmdsynopsis sepchar=" ">
1170 <command moreinfo="none">LogSQLWhichHeadersIn</command>
1171 <arg choice="req" rep="repeat"><replaceable>header-name</replaceable></arg>
1172 </cmdsynopsis>
1173 <simpara>Example: LogSQLWhichHeadersIn UserAgent Accept-Encodeing Host</simpara>
1174 <simpara>Context: virtual host</simpara>
1175 <para>Defines the list of inbound headers you would like logged. This works in conjunction with LogSQLHeadersInLogTable. This directive does not require any additional characters to be added to the LogSQLTransferLogFormat string. The feature is activated simply by including this directive, upon which you will begin populating the separate inbound-headers table with data.</para>
1176 <para>Each string may contain a + or - prefix in a &lt;VirtualHost&gt; context and will cause those strings to be added (+) or removed (-) from the global configuration. Otherwise the global is completely ignored and overridden if defined in a &lt;VirtualHost&gt;</para>
1177 <note>
1178 <para>The table must be created (see create-tables.sql, included in the package), or LogSQLCreateTables must be set to 'On'.</para>
1179 </note>
1180 </listitem>
1181 </varlistentry>
1182 <varlistentry>
1183 <term>LogSQLWhichHeadersOut</term>
1184 <listitem>
1185 <cmdsynopsis sepchar=" ">
1186 <command moreinfo="none">LogSQLWhichHeadersOut</command>
1187 <arg choice="req" rep="repeat"><replaceable>header-name</replaceable></arg>
1188 </cmdsynopsis>
1189 <simpara>Example: LogSQLWhichHeadersOut Expires Content-Type Cache-Control</simpara>
1190 <simpara>Context: virtual host</simpara>
1191 <para>Defines the list of outbound headers you would like logged. This works in conjunction with LogSQLHeadersOutLogTable. This directive does not require any additional characters to be added to the LogSQLTransferLogFormat string. The feature is activated simply by including this directive, upon which you will begin populating the separate outbound-headers table with data.</para>
1192 <para>Each string may contain a + or - prefix in a &lt;VirtualHost&gt; context and will cause those strings to be added (+) or removed (-) from the global configuration. Otherwise the global is completely ignored and overridden if defined in a &lt;VirtualHost&gt;</para>
1193 <note>
1194 <para>The table must be created (see create-tables.sql, included in the package), or LogSQLCreateTables must be set to 'On'.</para>
1195 </note>
1196 </listitem>
1197 </varlistentry>
1198 <varlistentry>
1199 <term>LogSQLWhichNotes</term>
1200 <listitem>
1201 <cmdsynopsis sepchar=" ">
1202 <command moreinfo="none">LogSQLWhichNotes</command>
1203 <arg choice="req" rep="repeat"><replaceable>note-name</replaceable></arg>
1204 </cmdsynopsis>
1205 <simpara>Example: LogSQLWhichNotes mod_gzip_result mod_gzip_ompression_ratio</simpara>
1206 <simpara>Context: virtual host</simpara>
1207 <para>Defines the list of notes you would like logged. This works in conjunction with LogSQLNotesLogTable. This directive does not require any additional characters to be added to the LogSQLTransferLogFormat string. The feature is activated simply by including this directive, upon which you will begin populating the separate notes table with data.</para>
1208 <para>Each string may contain a + or - prefix in a &lt;VirtualHost&gt; context and will cause those strings to be added (+) or removed (-) from the global configuration. Otherwise the global is completely ignored and overridden if defined in a &lt;VirtualHost&gt;</para>
1209 <note>
1210 <para>The table must be created (see create-tables.sql, included in the package), or LogSQLCreateTables must be set to 'On'.</para>
1211 </note>
1212 </listitem>
1213 </varlistentry>
1214 </variablelist>
1215 </sect3>
1216 <sect3>
1217 <title>Deprecated Command</title>
1218 <variablelist>
1219 <varlistentry>
1220 <term>LogSQLSocketFile [Deprecated]</term>
1221 <listitem>
1222 <cmdsynopsis sepchar=" ">
1223 <command moreinfo="none">LogSQLSocketFile</command>
1224 <arg choice="req" rep="norepeat"><replaceable>filename</replaceable></arg>
1225 </cmdsynopsis>
1226 <simpara>Example: LogSQLSocketFile /tmp/mysql.sock</simpara>
1227 <simpara>Default: (database specific)</simpara>
1228 <simpara>Default (MySQL): /var/lib/mysql/mysql.sock</simpara>
1229 <simpara>Context: main server config</simpara>
1230 <para>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.</para>
1231 <para>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.</para>
1232 <note>
1233 <para>This directive is deprecated in favor of LogSQLDBParam socketfile [socketfilename]</para>
1234 <para>This is defined only once in the <filename moreinfo="none">httpd.conf</filename> file.</para>
1235 </note>
1236 </listitem>
1237 </varlistentry>
1238 <varlistentry>
1239 <term>LogSQLTCPPort [Deprecated]</term>
1240 <listitem>
1241 <cmdsynopsis sepchar=" ">
1242 <command moreinfo="none">LogSQLTCPPort</command>
1243 <arg choice="req" rep="norepeat"><replaceable>port-number</replaceable></arg>
1244 </cmdsynopsis>
1245 <simpara>Example: LogSQLTCPPort 3309</simpara>
1246 <simpara>Default: (database specific)</simpara>
1247 <simpara>Default (MySQL): 3306</simpara>
1248 <simpara>Context: main server config</simpara>
1249 <para>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.</para>
1250 <note>
1251 <para>This directive is deprecated in favor of LogSQLDBParam tcpport [port-number]</para>
1252 <para>This is defined only once in the <filename moreinfo="none">httpd.conf</filename> file.</para>
1253 </note>
1254 </listitem>
1255 </varlistentry>
1256 <varlistentry>
1257 <term>LogSQLDatabase [Deprecated]</term>
1258 <listitem>
1259 <cmdsynopsis sepchar=" ">
1260 <command moreinfo="none">LogSQLDatabase</command>
1261 <arg choice="req" rep="norepeat"><replaceable>database</replaceable></arg>
1262 </cmdsynopsis>
1263 <simpara>Example: LogSQLDatabase loggingdb</simpara>
1264 <simpara>Context: main server config</simpara>
1265 <para>Defines the database that is used for logging. "database" must be a valid db on the MySQL host defined in LogSQLLoginInfo</para>
1266 <note>
1267 <para>This directive is deprecated in favor of the URI form of LogSQLLoginInfo.</para>
1268 <para>This is defined only once in the <filename moreinfo="none">httpd.conf</filename> file.</para>
1269 </note>
1270 </listitem>
1271 </varlistentry>
1272 </variablelist>
1273 </sect3>
1274 </sect2> 1009 </sect2>
1275 </sect1> 1010 </sect1>
1276 <sect1> 1011 <sect1>
@@ -1278,7 +1013,7 @@ where a.id=n.id and a.id='PPIDskBRH30AAGPtAsg';</screen>
1278 <qandaset> 1013 <qandaset>
1279 <qandadiv> 1014 <qandadiv>
1280 <title>General module questions</title> 1015 <title>General module questions</title>
1281 <qandaentry id="FAQ.WhyLogToSQL"> 1016 <qandaentry>
1282 <question> 1017 <question>
1283 <para>Why log to an SQL database?</para> 1018 <para>Why log to an SQL database?</para>
1284 </question> 1019 </question>
@@ -1446,7 +1181,7 @@ where a.id=n.id and a.id='PPIDskBRH30AAGPtAsg';</screen>
1446 <para>Who's using mod_log_sql?</para> 1181 <para>Who's using mod_log_sql?</para>
1447 </question> 1182 </question>
1448 <answer> 1183 <answer>
1449 <para>Good question! It would be great to find out! If you are a production-level mod_log_sql user, please contact eddie at &EmailContact; so that you can be mentioned here.</para> 1184 <para>Good question! It would be great to find out! If you are a production-level mod_log_sql user, please contact [(chris@grubbybaby.com)||the maintainer, Chris Powell] so that you can be mentioned here.</para>
1450 </answer> 1185 </answer>
1451 </qandaentry> 1186 </qandaentry>
1452 <qandaentry> 1187 <qandaentry>
@@ -1468,7 +1203,7 @@ where a.id=n.id and a.id='PPIDskBRH30AAGPtAsg';</screen>
1468 <para>Does mod_log_sql work with Apache 2.x?</para> 1203 <para>Does mod_log_sql work with Apache 2.x?</para>
1469 </question> 1204 </question>
1470 <answer> 1205 <answer>
1471 <para>Yes. A port of mod_log_sql is available for Apache 2.x as of mod_log_sql 1.90</para> 1206 <para>Yes. A port of mod_log_sql is available for Apache 2.x, and is currently available and maintained at <ulink url="http://www.outoforder.cc/projects/apache/">OutOfOrder.CC</ulink></para>
1472 </answer> 1207 </answer>
1473 </qandaentry> 1208 </qandaentry>
1474 <qandaentry> 1209 <qandaentry>
@@ -1496,7 +1231,7 @@ where a.id=n.id and a.id='PPIDskBRH30AAGPtAsg';</screen>
1496 <para>I have discovered a bug. Who can I contact?</para> 1231 <para>I have discovered a bug. Who can I contact?</para>
1497 </question> 1232 </question>
1498 <answer> 1233 <answer>
1499 <para>Please contact Edward Rudd at &EmailContact;, or post a message to the mod_log_sql <xref endterm="Sect.MailingLists.title" linkend="Sect.MailingLists"/>. 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.</para> 1234 <para>Please contact [(chris@grubbybaby.com)||the maintainer], or post a message to the mod_log_sql mailing list. 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.</para>
1500 </answer> 1235 </answer>
1501 </qandaentry> 1236 </qandaentry>
1502 </qandadiv> 1237 </qandadiv>
@@ -1511,9 +1246,9 @@ where a.id=n.id and a.id='PPIDskBRH30AAGPtAsg';</screen>
1511 <para>PHP and mod_log_sql can be configured to happily coexist. The solution is to configure PHP to link against the real MySQL libraries: recompile PHP using --with-mysql=/your/path. Apache will run properly once the modules are all using the same version of the MySQL libraries.</para> 1246 <para>PHP and mod_log_sql can be configured to happily coexist. The solution is to configure PHP to link against the real MySQL libraries: recompile PHP using --with-mysql=/your/path. Apache will run properly once the modules are all using the same version of the MySQL libraries.</para>
1512 </answer> 1247 </answer>
1513 </qandaentry> 1248 </qandaentry>
1514 <qandaentry id="FAQ.NothingLogged"> 1249 <qandaentry>
1515 <question> 1250 <question>
1516 <para>Apache appears to start up fine, but nothing is getting logged in the database</para> 1251 <para>&lt;faq:NothingLogged&gt;Apache appears to start up fine, but nothing is getting logged in the database</para>
1517 </question> 1252 </question>
1518 <answer> 1253 <answer>
1519 <para>If you do not see any entries in the access_log, then something is preventing the inserts from happening. This could be caused by several things:</para> 1254 <para>If you do not see any entries in the access_log, then something is preventing the inserts from happening. This could be caused by several things:</para>
@@ -1522,17 +1257,17 @@ where a.id=n.id and a.id='PPIDskBRH30AAGPtAsg';</screen>
1522 <simpara>Improper privileges set up in the MySQL database </simpara> 1257 <simpara>Improper privileges set up in the MySQL database </simpara>
1523 </listitem> 1258 </listitem>
1524 <listitem> 1259 <listitem>
1525 <simpara>You are not hitting a VirtualHost that has a LogSQLTransferLogTable entry </simpara> 1260 <simpara>You aren't hitting a VirtualHost that has a LogSQLTransferLogTable entry </simpara>
1526 </listitem> 1261 </listitem>
1527 <listitem> 1262 <listitem>
1528 <simpara>You did not specify the right database host or login information</simpara> 1263 <simpara>You didn't specify the right database host or login information</simpara>
1529 </listitem> 1264 </listitem>
1530 <listitem> 1265 <listitem>
1531 <simpara>Another factor is preventing a connection to the database</simpara> 1266 <simpara>Another factor is preventing a connection to the database</simpara>
1532 </listitem> 1267 </listitem>
1533 </itemizedlist> 1268 </itemizedlist>
1534 <remark>It is improper to ask for help before you have followed these steps.</remark> 1269 <remark>It is improper to ask for help before you have followed these steps.</remark>
1535 <para>First examine the MySQL log that you established in step <xref linkend="Item.EnableLogging"/> of section <xref endterm="Sect.Preperation.title" linkend="Sect.Preperation"/>. Ensure that the INSERT statements are not being rejected because of a malformed table name or other typographical error. By enabling that log, you instructed MySQL to log every connection and command it receives -- if you see no INSERT attempts in the log, the module isn't successfully connecting to the database. If you see nothing at all in the log -- not even a record of your administrative connection attempts, then you did not enable the log correctly. If you do see INSERT attempts but they are failing, the log should tell you why.</para> 1270 <para>First examine the MySQL log that you established in step [step:EnaLog] of section [sub:PrepDb]. Ensure that the INSERT statements are not being rejected because of a malformed table name or other typographical error. By enabling that log, you instructed MySQL to log every connection and command it receives -- if you see no INSERT attempts in the log, the module isn't successfully connecting to the database. If you see nothing at all in the log -- not even a record of your administrative connection attempts, then you did not enable the log correctly. If you do see INSERT attempts but they are failing, the log should tell you why.</para>
1536 <para>Second, confirm that your LogSQL* directives are all correct.</para> 1271 <para>Second, confirm that your LogSQL* directives are all correct.</para>
1537 <para>Third, examine the Apache error logs for messages from mod_log_sql; the module will offer hints as to why it cannot connect, etc. </para> 1272 <para>Third, examine the Apache error logs for messages from mod_log_sql; the module will offer hints as to why it cannot connect, etc. </para>
1538 <para>The next thing to do is to change the LogLevel directive <emphasis>in the main server config as well as in each VirtualHost config:</emphasis></para> 1273 <para>The next thing to do is to change the LogLevel directive <emphasis>in the main server config as well as in each VirtualHost config:</emphasis></para>
@@ -1545,7 +1280,7 @@ ErrorLog /var/log/httpd/server-messages </programlisting>
1545 <para>Why do I get the message "insufficient configuration info to establish database link" in my Apache error log?</para> 1280 <para>Why do I get the message "insufficient configuration info to establish database link" in my Apache error log?</para>
1546 </question> 1281 </question>
1547 <answer> 1282 <answer>
1548 <para>At a minimum, LogSQLLoginInfo in the URl form and either LogSQLTableName or LogSQLMassVirtualHosting must be defined in order for the module to be able to establish a database link. If these are not defined or are incomplete you will receive this error message.</para> 1283 <para>At a minimum, LogSQLDatabase and LogSQLLoginInfo and either LogSQLTableName or LogSQLMassVirtualHosting must be defined in order for the module to be able to establish a database link. If these are not defined or are incomplete you will receive this error message.</para>
1549 </answer> 1284 </answer>
1550 </qandaentry> 1285 </qandaentry>
1551 <qandaentry> 1286 <qandaentry>
@@ -1553,7 +1288,7 @@ ErrorLog /var/log/httpd/server-messages </programlisting>
1553 <para>My database cannot handle all the open connections from mod_log_sql, is there anything I can do?</para> 1288 <para>My database cannot handle all the open connections from mod_log_sql, is there anything I can do?</para>
1554 </question> 1289 </question>
1555 <answer> 1290 <answer>
1556 <para>The rule of thumb: if you have n webservers each configured to support y MaxClients, then your database must be able to handle n times y simultaneous connections in the worst case. Certainly you must use common sense, consider reasonable traffic expectations and structure things accordingly.</para> 1291 <para>The rule of thumb: if you have n webservers each configured to support y MaxClients, then your database must be able to handle n\times y simultenous connections in the worst case. Certainly you must use common sense, consider reasonable traffic expectations and structure things accordingly.</para>
1557 </answer> 1292 </answer>
1558 <answer> 1293 <answer>
1559 <para>Tweaking my.cnf to scale to high connection loads is imperative. But if hardware limitations prevent your MySQL server from gracefully handling the number of incoming connections, it would be beneficial to upgrade the memory or CPU on that server in order to handle the load. </para> 1294 <para>Tweaking my.cnf to scale to high connection loads is imperative. But if hardware limitations prevent your MySQL server from gracefully handling the number of incoming connections, it would be beneficial to upgrade the memory or CPU on that server in order to handle the load. </para>
@@ -1562,7 +1297,7 @@ ErrorLog /var/log/httpd/server-messages </programlisting>
1562 <para>Jeremy Zawodny, a highly respected MySQL user and contributor to Linux Magazine, has this very helpful and highly appropriate article on tuning MySQL: <ulink url="http://jeremy.zawodny.com/blog/archives/000173.html">MySQL, Linux, and Thread Caching</ulink></para> 1297 <para>Jeremy Zawodny, a highly respected MySQL user and contributor to Linux Magazine, has this very helpful and highly appropriate article on tuning MySQL: <ulink url="http://jeremy.zawodny.com/blog/archives/000173.html">MySQL, Linux, and Thread Caching</ulink></para>
1563 </answer> 1298 </answer>
1564 <answer> 1299 <answer>
1565 <para><abbrev></abbrev>Please remember that mod_log_sql's overriding principle is performance -- that is what the target audience demands and expects. Other database logging solutions do not open and maintain many database connections, but their performance suffers drastically. For example, pgLOGd funnels all log connections through a separate daemon that connects to the database, but that bottlenecks the entire process. mod_log_sql achieves performance numbers an order of magnitude greater than the alternatives because it dispenses with the overhead associated with rapid connection cycling, and it does not attempt to shoehorn all the database traffic through a single extra daemon or proxy process.</para> 1300 <para><abbrev></abbrev>Please remember that mod_log_sql's overriding principle is performance -- that is what the target audience demands and expects. Other database logging solutions do not open and maintain many database connections, but their performance suffers drastically. For example, pgLOGd funnels all log connections through a separate daemon that connects to the database, but that bottlenecks the entire process. mod_log_sql achieves performance numbers an order of magnitude greater 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.</para>
1566 </answer> 1301 </answer>
1567 <answer> 1302 <answer>
1568 <remark>Currently connection pooling is being implemented as part of the Database Abstraction layer to allow multiple httpd processes to share connections.</remark> 1303 <remark>Currently connection pooling is being implemented as part of the Database Abstraction layer to allow multiple httpd processes to share connections.</remark>
@@ -1573,7 +1308,7 @@ ErrorLog /var/log/httpd/server-messages </programlisting>
1573 <para>Why do I occasionally see a "lost connection to MySQL server" message in my Apache error log?</para> 1308 <para>Why do I occasionally see a "lost connection to MySQL server" message in my Apache error log?</para>
1574 </question> 1309 </question>
1575 <answer> 1310 <answer>
1576 <para>This message may appear every now and then in your Apache error log, especially on very lightly loaded servers. This does not 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 have not 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:</para> 1311 <para>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:</para>
1577 <screen>[Tue Nov 12 19:04:10 2002] [error] mod_log_sql: first attempt failed, 1312 <screen>[Tue Nov 12 19:04:10 2002] [error] mod_log_sql: first attempt failed,
1578 API said: error 2013, Lost connection to MySQL server during query 1313 API said: error 2013, Lost connection to MySQL server during query
1579[Tue Nov 12 19:04:10 2002] [error] mod_log_sql: reconnect successful 1314[Tue Nov 12 19:04:10 2002] [error] mod_log_sql: reconnect successful
@@ -1685,9 +1420,9 @@ mysql&gt; optimize table access_log; </screen>
1685 <para>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!</para> 1420 <para>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!</para>
1686 </answer> 1421 </answer>
1687 </qandaentry> 1422 </qandaentry>
1688 <qandaentry id="FAQ.DelayedInsert"> 1423 <qandaentry>
1689 <question> 1424 <question>
1690 <para>What is the issue with activating delayed inserts?</para> 1425 <para>&lt;sub:DelayedInsFAQ&gt;What is the issue with activating delayed inserts?</para>
1691 </question> 1426 </question>
1692 <answer> 1427 <answer>
1693 <para>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.</para> 1428 <para>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.</para>
@@ -1705,7 +1440,7 @@ mysql&gt; optimize table access_log; </screen>
1705 <para>Instead of delayed inserts, you may wish to utilize InnoDB tables (instead of the standard MyISAM tables). InnoDB tables suppot row-level locking and are recommended for high-volume databases.</para> 1440 <para>Instead of delayed inserts, you may wish to utilize InnoDB tables (instead of the standard MyISAM tables). InnoDB tables suppot row-level locking and are recommended for high-volume databases.</para>
1706 </answer> 1441 </answer>
1707 <answer> 1442 <answer>
1708 <para>If after understanding these problems you still wish to enable delayed inserts, section <xref endterm="Sect.DelayedInsert.title" linkend="Sect.DelayedInsert"/> discusses how.</para> 1443 <para>If after understanding these problems you still wish to enable delayed inserts, section [sub:DelayedIns] discusses how.</para>
1709 </answer> 1444 </answer>
1710 </qandaentry> 1445 </qandaentry>
1711 </qandadiv> 1446 </qandadiv>
@@ -1730,9 +1465,9 @@ rm -f /var/log/httpd/templog</programlisting>
1730 <para>See? Easy.</para> 1465 <para>See? Easy.</para>
1731 </answer> 1466 </answer>
1732 </qandaentry> 1467 </qandaentry>
1733 <qandaentry id="FAQ.Cookie"> 1468 <qandaentry>
1734 <question> 1469 <question>
1735 <para>How can I log mod_usertrack cookies?</para> 1470 <para>&lt;sec:cookie&gt;How can I log mod_usertrack cookies?</para>
1736 </question> 1471 </question>
1737 <answer> 1472 <answer>
1738 <para>A number of people like to log mod_usertrack cookies in their Apache TransferLog to aid in understanding their visitors' clickstreams. This is accomplished, for example, with a statement as follows:</para> 1473 <para>A number of people like to log mod_usertrack cookies in their Apache TransferLog to aid in understanding their visitors' clickstreams. This is accomplished, for example, with a statement as follows:</para>
@@ -1788,8 +1523,8 @@ rm -f /var/log/httpd/templog</programlisting>
1788 </question> 1523 </question>
1789 <answer> 1524 <answer>
1790 <para>As of version 1.17, you have a choice in how you want cookie logging handled.</para> 1525 <para>As of version 1.17, you have a choice in how you want cookie logging handled.</para>
1791 <para>If you are interested in logging only one cookie per request, follow the instructions in FAQ entry <xref linkend="FAQ.Cookie"/> above. That cookie will be logged to a column in the regular access_log table, and the actual cookie you want to log is specified with LogSQLWhichCookie. Don't forget to specify the 'c' character in LogSQLTransferLogFormat.</para> 1526 <para>If you are interested in logging only one cookie per request, follow the instructions in section [sec:cookie] above. That cookie will be logged to a column in the regular access_log table, and the actual cookie you want to log is specified with LogSQLWhichCookie. Don't forget to specify the 'c' character in LogSQLTransferLogFormat.</para>
1792 <para>If, however, you need to log multiple cookies per request, you must employ the LogSQLWhichCookies (note the plural) directive. The cookies you specify will be logged to a separate table (as discussed in section <xref endterm="Sect.MultiTable.title" linkend="Sect.MultiTable"/>), and entries in that table will be linked to the regular access_log entries via the unique ID that is supplied by mod_unique_id. Without mod_unique_id the information will still be logged but you will be unable to correlate which cookies go with which access-requests. Furthermore, with LogSQLWhichCookies, you do not need to include the 'c' character in LogSQLTransferLogFormat.</para> 1527 <para>If, however, you need to log multiple cookies per request, you must employ the LogSQLWhichCookies (note the plural) directive. The cookies you specify will be logged to a separate table (as discussed in section [secMulTable]), and entries in that table will be linked to the regular access_log entries via the unique ID that is supplied by mod_unique_id. Without mod_unique_id the information will still be logged but you will be unable to correlate which cookies go with which access-requests. Furthermore, with LogSQLWhichCookies, you do not need to include the 'c' character in LogSQLTransferLogFormat.</para>
1793 <para>LogSQLWhichCookie and LogSQLWhichCookies can coexist without conflict because they operate on entireley different tables, but you're better off choosing the one you need.</para> 1528 <para>LogSQLWhichCookie and LogSQLWhichCookies can coexist without conflict because they operate on entireley different tables, but you're better off choosing the one you need.</para>
1794 </answer> 1529 </answer>
1795 </qandaentry> 1530 </qandaentry>
@@ -1812,7 +1547,7 @@ mysql&gt; alter table access_log add column ssl_maxkeysize smallint unsigned;</s
1812 LogSQLTransferLogFormat AbHhmRSsTUuvcQqz 1547 LogSQLTransferLogFormat AbHhmRSsTUuvcQqz
1813&lt;/VirtualHost&gt;</programlisting> 1548&lt;/VirtualHost&gt;</programlisting>
1814 <para>You also need to make sure you have the mod_log_sql_ssl module loaded as well.</para> 1549 <para>You also need to make sure you have the mod_log_sql_ssl module loaded as well.</para>
1815 <para>The last three characters (Qqz) in the directive are the SSL ones; see section <xref linkend="Conf.LogSQLTransferLogFormat"/> in the directives documentation for details of the LogSQLTransferLogFormat directive.</para> 1550 <para>The last three characters (Qqz) in the directive are the SSL ones; see section [sub:Frmat] in the directives documentation for details of the LogSQLTransferLogFormat directive.</para>
1816 <para>Restart Apache, then perform some hits on your server. Then run the following select statement:</para> 1551 <para>Restart Apache, then perform some hits on your server. Then run the following select statement:</para>
1817 <screen>mysql&gt; select remote_host,request_uri,ssl_cipher,ssl_keysize,ssl_maxkeysize from access_log where ssl_cipher is not null;</screen> 1552 <screen>mysql&gt; select remote_host,request_uri,ssl_cipher,ssl_keysize,ssl_maxkeysize from access_log where ssl_cipher is not null;</screen>
1818 <table> 1553 <table>
diff --git a/INSTALL b/INSTALL
index 072f738..3cc8a94 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,20 +1,5 @@
1$Id: INSTALL,v 1.1 2003/12/20 07:16:05 urkle Exp $
2
1This document has been superseded by the new documentation in the 3This document has been superseded by the new documentation in the
2docs/ directory. There you will find the docs in a variety of 4Documentation/ directory. There you will find the docs in a variety of
3formats, including PostScript, plaintext, and HTML. 5formats, including PostScript, plaintext, and HTML.
4
5Basic overview is..
6
7./configure --with-apxs=/path/to/apxs --enable-ssl
8
9gmake
10
11gmake install
12
13
14edit httpd.conf and add the following.
15
16LoadModule log_sql_module modules/mod_log_sql.so
17LoadModule log_sql_mysql_module modules/mod_log_sql_mysql.so
18<IfModule mod_ssl.c>
19LoadModule log_sql_ssl_module modules/mod_log_sql_ssl.so
20</IfModule>
diff --git a/LICENSE b/LICENSE
index 4c98781..b6090e0 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,5 @@
1$Id: LICENSE,v 1.1 2003/12/20 07:16:05 urkle Exp $
1 2
2Copyright (c) 2004 Edward M. Rudd. All rights reserved.
3Copyright (c) 2002 Christopher B. Powell. All rights reserved. 3Copyright (c) 2002 Christopher B. Powell. All rights reserved.
4Portions copyright (c) 2000 The Apache Software Foundation. 4Portions copyright (c) 2000 The Apache Software Foundation.
5 5
@@ -117,3 +117,5 @@ WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
117MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 117MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
118 118
119The End 119The End
120
121
diff --git a/Makefile.in b/Makefile.in
index 07278d3..bc3d2d7 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,8 +1,9 @@
1# @configure_input@ 1# @configure_input@
2 2
3# Modify these top variables. 3# Modify these top variables.
4SUBDIRS = docs contrib 4SUBDIRS = Documentation
5SOURCES = @PACKAGE_NAME@.c 5SOURCES = \
6 @PACKAGE_NAME@.c
6 7
7HEADERS = mod_log_sql.h \ 8HEADERS = mod_log_sql.h \
8 functions.h \ 9 functions.h \
@@ -13,52 +14,22 @@ HEADERS = mod_log_sql.h \
13 14
14CFLAGS = -Wc,-Wall -Wc,-Werror -Wc,-fno-strict-aliasing 15CFLAGS = -Wc,-Wall -Wc,-Werror -Wc,-fno-strict-aliasing
15 16
16LDADD = @RT_LIBS@ 17INCLUDES = @MYSQL_CFLAGS@
17 18
18EXTRA_DIST = AUTHORS INSTALL TODO LICENSE CHANGELOG 19LDADD = @MYSQL_LDFLAGS@ @MYSQL_LIBS@
20
21EXTRA_DIST = AUTHORS INSTALL LICENSE CHANGELOG make_combined_log.pl
19 22
20TARGET = @PACKAGE_NAME@@APXS_EXTENSION@ 23TARGET = @PACKAGE_NAME@@APXS_EXTENSION@
21 24
22TARGETS = $(TARGET) 25sslSOURCES = mod_log_sql_ssl.c
23 26
24sslSOURCES = @PACKAGE_NAME@_ssl.c
25sslTARGET = @PACKAGE_NAME@_ssl@APXS_EXTENSION@ 27sslTARGET = @PACKAGE_NAME@_ssl@APXS_EXTENSION@
26sslLDADD =
27sslCFLAGS = @MOD_SSL_CFLAGS@
28sslNAME = log_sql_ssl
29 28
30ifeq (@WANT_SSL_MOD@,1) 29ifeq (@WANT_SSL_MOD@,1)
31TARGETS += $(sslTARGET) 30TARGETS = $(TARGET) $(sslTARGET)
32endif 31else
33 32TARGETS = $(TARGET)
34mysqlSOURCES = @PACKAGE_NAME@_mysql.c
35mysqlTARGET = @PACKAGE_NAME@_mysql@APXS_EXTENSION@
36mysqlLDADD = @MYSQL_LDFLAGS@ @MYSQL_LIBS@
37mysqlCFLAGS = @MYSQL_CFLAGS@
38mysqlNAME = log_sql_mysql
39
40ifeq (@WANT_MYSQL_MOD@,1)
41TARGETS += $(mysqlTARGET)
42endif
43
44pgsqlSOURCES = @PACKAGE_NAME@_pgsql.c
45pgsqlTARGET = @PACKAGE_NAME@_pgsql@APXS_EXTENSION@
46pgsqlLDADD = @PGSQL_LDFLAGS@ @PGSQL_LIBS@
47pgsqlCFLAGS = @PGSQL_CFLAGS@
48pgsqlNAME = log_sql_pgsql
49
50ifeq (@WANT_PGSQL_MOD@,1)
51TARGETS += $(pgsqlTARGET)
52endif
53
54dbiSOURCES = @PACKAGE_NAME@_dbi.c
55dbiTARGET = @PACKAGE_NAME@_dbi@APXS_EXTENSION@
56dbiLDADD = @DBI_LDFLAGS@ @DBI_LIBS@
57dbiCFLAGS = @DBI_CFLAGS@
58dbiNAME = log_sql_dbi
59
60ifeq (@WANT_DBI_MOD@,1)
61TARGETS += $(dbiTARGET)
62endif 33endif
63 34
64#Don't modify anything below here 35#Don't modify anything below here
@@ -68,11 +39,11 @@ PROVIDERS_SUBDIRS = @subdirs@
68srcdir = @abs_srcdir@ 39srcdir = @abs_srcdir@
69builddir = @abs_builddir@ 40builddir = @abs_builddir@
70 41
71OBJ = $(SOURCES:.c=.o) $(sslSOURCES:.c=.o) $(mysqlSOURCES:.c=.o) 42OBJ = $(SOURCES:.c=.o) $(sslSOURCES:.c=.o)
72 43
73LO = $(SOURCES:.c=.lo) $(sslSOURCES:.c=.lo) $(mysqlSOURCES:.c=.lo) 44LO = $(SOURCES:.c=.lo) $(sslSOURCES:.c=.lo)
74 45
75SLO = $(SOURCES:.c=.slo) $(sslSOURCES:.c=.slo) $(mysqlSOURCES:.c=.slo) 46SLO = $(SOURCES:.c=.slo) $(sslSOURCES:.c=.slo)
76 47
77STD_DIST = install-sh \ 48STD_DIST = install-sh \
78 config.sub \ 49 config.sub \
@@ -84,8 +55,7 @@ STD_DIST = install-sh \
84 stamp-h.in \ 55 stamp-h.in \
85 config.h.in 56 config.h.in
86 57
87DISTFILES = $(STD_DIST) $(EXTRA_DIST) $(SOURCES) $(HEADERS) \ 58DISTFILES = $(STD_DIST) $(EXTRA_DIST) $(SOURCES) $(sslSOURCES) $(HEADERS)
88 $(sslSOURCES) $(mysqlSOURCES)
89 59
90all: $(TARGETS) all-subdirs 60all: $(TARGETS) all-subdirs
91 61
@@ -104,49 +74,23 @@ all-subdirs install-subdirs activate-subdirs clean-subdirs distclean-subdirs:
104 fi; \ 74 fi; \
105 done; 75 done;
106 76
107TODO: TODO.in
108 @./gen_todo.pl
109
110$(TARGET): $(SOURCES) $(HEADERS) 77$(TARGET): $(SOURCES) $(HEADERS)
111 @@APXS_BIN@ -c -o $(TARGET) $(CFLAGS) \ 78 @@APXS_BIN@ -c -o $(TARGET) $(INCLUDES) $(CFLAGS) \
112 @DEFS@ @AP_DEFS@ $(LDADD) $(SOURCES) 79 $(LDADD) @DEFS@ @APACHE_DEFS@ $(SOURCES)
113 80
114$(sslTARGET): $(sslSOURCES) $(HEADERS) 81$(sslTARGET): $(sslSOURCES) $(HEADERS)
115 @@APXS_BIN@ -c -o $(sslTARGET) $(sslCFLAGS) $(CFLAGS) \ 82 @@APXS_BIN@ -c -o $(sslTARGET) $(INCLUDES) @MOD_SSL_CFLAGS@ $(CFLAGS) \
116 @DEFS@ @AP_DEFS@ $(sslLDADD) $(sslSOURCES) 83 @DEFS@ @APACHE_DEFS@ $(sslSOURCES)
117 84
118$(mysqlTARGET): $(mysqlSOURCES) $(HEADERS) 85include:
119 @@APXS_BIN@ -c -o $(mysqlTARGET) $(mysqlCFLAGS) $(CFLAGS) \ 86 rm -rf include
120 @DEFS@ @AP_DEFS@ $(mysqlLDADD) $(mysqlSOURCES) 87 ln -s @APACHE_INCDIR@ include
121
122$(pgsqlTARGET): $(pgsqlSOURCES) $(HEADERS)
123 @@APXS_BIN@ -c -o $(pgsqlTARGET) $(pgsqlCFLAGS) $(CFLAGS) \
124 @DEFS@ @AP_DEFS@ $(pgsqlLDADD) $(pgsqlSOURCES)
125
126$(dbiTARGET): $(dbiSOURCES) $(HEADERS)
127 @@APXS_BIN@ -c -o $(dbiTARGET) $(dbiCFLAGS) $(CFLAGS) \
128 @DEFS@ @AP_DEFS@ $(dbiLDADD) $(dbiSOURCES)
129 88
130install: $(TARGETS) install-subdirs 89install: $(TARGETS) install-subdirs
131 @@APXS_BIN@ -i $(TARGET); \ 90 @@APXS_BIN@ -i $(TARGET); \
132 @APXS_BIN@ -n $(mysqlNAME) -i $(mysqlTARGET); \
133 if test @WANT_SSL_MOD@ -eq 1; then \ 91 if test @WANT_SSL_MOD@ -eq 1; then \
134 @APXS_BIN@ -n $(sslNAME) -i $(sslTARGET); \ 92 @APXS_BIN@ -i $(sslTARGET); \
135 fi; \ 93 fi
136 echo "*************************************************************************"; \
137 echo "*** The mod_log_sql modules have been installed."; \
138 echo "*** Please edit your Apache configuration files and"; \
139 echo "*** add the appropriate LoadModule directives per the documentation"; \
140 echo "*** in docs/manual.html"; \
141 echo "*** If you have previously used 1.18 or lower then you must change"; \
142 echo "*** >LoadModule sql_log_module modules/mod_log_sql.so"; \
143 echo "*** to"; \
144 echo "*** >LoadModule log_sql_module modules/mod_log_sql.so"; \
145 echo "*** in your httpd.conf as the internal name of the module has changed."; \
146 echo "*** "; \
147 echo "*** Also read the documentation about using SSL support and new "; \
148 echo "*** configuration directives."; \
149 echo "*************************************************************************";
150 94
151activate: activate-subdirs 95activate: activate-subdirs
152 @@APXS_BIN@ -i -a $(TARGET); \ 96 @@APXS_BIN@ -i -a $(TARGET); \
diff --git a/TODO.in b/TODO.in
deleted file mode 100644
index 12bb30c..0000000
--- a/TODO.in
+++ /dev/null
@@ -1,16 +0,0 @@
1TODO:
2* write alternate DB driver (PostgreSQL, libDBI, mod_*_pool)
3* look at forcing table name to ServerName instead of on of the names in
4 ServerAlias?
5* LogSQLRotateLogs directive with daily/monthly/weekly/etc.
6* socket-based middleman daemon with configurable conns, or connect/disconnect.
7* DBI connection pool when I switch to DBI.
8* ignore by cookie
9* investigate thread safety issues
10 Use libmysqlclient_r for threaded MPM (or always?)
11 Add thread locks if using standard mysqlclient
12 Check locking issues with the preserve file?
13* rewrite main core logging function to optimize for speed.
14* Clean up table creation code.
15 support DB independent way of defining the tables
16-----
diff --git a/apache13.h b/apache13.h
index ce4ec64..8181c43 100644
--- a/apache13.h
+++ b/apache13.h
@@ -1,4 +1,4 @@
1/* $Id$ */ 1/* $Header: /home/cvs/mod_log_sql/apache13.h,v 1.4 2004/02/05 21:59:46 urkle Exp $ */
2#ifndef APACHE13_H 2#ifndef APACHE13_H
3#define APACHE13_H 3#define APACHE13_H
4 4
@@ -8,27 +8,25 @@
8#include "http_core.h" 8#include "http_core.h"
9 9
10/* Defines */ 10/* Defines */
11#define AP_MODULE_DECLARE_DATA MODULE_VAR_EXPORT 11#define AP_MODULE_DECLARE_DATA
12#define APR_OFF_T_FMT "ld" 12#define APR_OFF_T_FMT "ld"
13#define APR_PID_T_FMT "d" 13#define APR_PID_T_FMT "d"
14#define APR_SUCCESS 0 14#define APR_SUCCESS 0
15#define APR_OFFSETOF XtOffsetOf 15#define APR_OFFSETOF XtOffsetOf
16 16
17/** method of declaring a directive with raw argument parsing */ 17/*AP_INIT_TAKE1("LogSQLTransferLogTable", set_server_nmv_string_slot,
18# define AP_INIT_RAW_ARGS(directive, func, mconfig, where, help) \ 18 (void *)APR_OFFSETOF(logsql_state, transfer_table_name), RSRC_CONF,
19 { directive, func, mconfig, where, RAW_ARGS, help } 19 "The database table that holds the transfer log")
20
21{"LogSQLTransferLogTable", set_log_sql_transfer_table, NULL, RSRC_CONF, TAKE1,
22 "The database table that holds the transfer log"}*/
23
20/** method of declaring a directive which takes 1 argument */ 24/** method of declaring a directive which takes 1 argument */
21# define AP_INIT_TAKE1(directive, func, mconfig, where, help) \ 25# define AP_INIT_TAKE1(directive, func, mconfig, where, help) \
22 { directive, func, mconfig, where, TAKE1, help } 26 { directive, func, mconfig, where, TAKE1, help }
23/** method of declaring a directive which takes 2 argument */
24# define AP_INIT_TAKE2(directive, func, mconfig, where, help) \
25 { directive, func, mconfig, where, TAKE2, help }
26/** method of declaring a directive which takes multiple arguments */ 27/** method of declaring a directive which takes multiple arguments */
27# define AP_INIT_ITERATE(directive, func, mconfig, where, help) \ 28# define AP_INIT_ITERATE(directive, func, mconfig, where, help) \
28 { directive, func, mconfig, where, ITERATE, help } 29 { directive, func, mconfig, where, ITERATE, help }
29/** method of declaring a directive which takes 1 or 3 arguments */
30# define AP_INIT_TAKE13(directive, func, mconfig, where, help) \
31 { directive, func, mconfig, where, TAKE13, help }
32/** method of declaring a directive which takes 3 arguments */ 30/** method of declaring a directive which takes 3 arguments */
33# define AP_INIT_TAKE3(directive, func, mconfig, where, help) \ 31# define AP_INIT_TAKE3(directive, func, mconfig, where, help) \
34 { directive, func, mconfig, where, TAKE3, help } 32 { directive, func, mconfig, where, TAKE3, help }
@@ -39,35 +37,21 @@
39/* Types */ 37/* Types */
40#define apr_pool_t pool 38#define apr_pool_t pool
41#define apr_array_header_t array_header 39#define apr_array_header_t array_header
42#define apr_table_t table
43
44#define apr_status_t int
45#define apr_uri_t uri_components
46 40
47/* Functions */ 41/* Functions */
48#define ap_get_remote_host(a,b,c,d) ap_get_remote_host(a,b,c) 42#define ap_get_remote_host(a,b,c,d) ap_get_remote_host(a,b,c)
49#define ap_set_deprecated NULL 43
50
51#define apr_uri_unparse ap_unparse_uri_components 44#define apr_uri_unparse ap_unparse_uri_components
52#define apr_uri_parse ap_parse_uri_components
53#define ap_add_version_component(p,s) ap_add_version_component(s)
54 45
55#define apr_pool_create(a,b) *(a) = ap_make_sub_pool(b) 46#define apr_pool_create(a,b) *(a) = ap_make_sub_pool(b)
56#define apr_pool_destroy ap_destroy_pool
57#define apr_palloc ap_palloc 47#define apr_palloc ap_palloc
58#define apr_pcalloc ap_pcalloc 48#define apr_pcalloc ap_pcalloc
59#define apr_pstrdup ap_pstrdup 49#define apr_pstrdup ap_pstrdup
60#define apr_pstrcat ap_pstrcat 50#define apr_pstrcat ap_pstrcat
61#define apr_psprintf ap_psprintf 51#define apr_psprintf ap_psprintf
62#define apr_snprintf ap_snprintf 52#define apr_snprintf ap_snprintf
63#define ap_strchr strchr
64#define ap_strchr_c strchr
65#define ap_strstr strstr
66#define ap_strstr_c strstr
67 53
68#define apr_table_set ap_table_set
69#define apr_table_get ap_table_get 54#define apr_table_get ap_table_get
70#define apr_table_make ap_make_table
71 55
72#define apr_array_push ap_push_array 56#define apr_array_push ap_push_array
73#define apr_array_make ap_make_array 57#define apr_array_make ap_make_array
@@ -76,22 +60,6 @@
76 60
77#define apr_tolower ap_tolower 61#define apr_tolower ap_tolower
78 62
79void log_error(char *file, int line, int level, apr_status_t status, 63#define log_error ap_log_error
80 const server_rec *s, const char *fmt, ...) __attribute__ ((format (printf, 6,7)));
81
82#ifndef WIN32
83inline
84#endif
85void log_error(char *file, int line, int level,
86 apr_status_t status, const server_rec *s, const char *fmt, ...)
87{
88 static char buff[MAX_STRING_LEN];
89 va_list args;
90 va_start(args, fmt);
91 ap_vsnprintf(buff,MAX_STRING_LEN, fmt,args);
92 ap_log_error(file,line,level | APLOG_NOERRNO ,s,"%s",buff);
93 va_end(args);
94}
95
96 64
97#endif /* APACHE13_H */ 65#endif /* APACHE13_H */
diff --git a/apache20.h b/apache20.h
index 9d87588..1b54858 100644
--- a/apache20.h
+++ b/apache20.h
@@ -1,4 +1,4 @@
1/* $Id$ */ 1/* $Header: /home/cvs/mod_log_sql/apache20.h,v 1.3 2004/01/21 04:34:21 urkle Exp $ */
2#ifndef APACHE20_H 2#ifndef APACHE20_H
3#define APACHE20_H 3#define APACHE20_H
4 4
@@ -20,6 +20,15 @@
20 20
21#include "util_time.h" 21#include "util_time.h"
22 22
23#define log_error ap_log_error 23static void log_error(char *file, int line, int level, const server_rec *s, const char *fmt, ...) __attribute__ ((format (printf, 5,6)));
24static inline void log_error(char *file, int line, int level, const server_rec *s, const char *fmt, ...)
25{
26 static char buff[MAX_STRING_LEN];
27 va_list args;
28 va_start(args, fmt);
29 apr_vsnprintf(buff,MAX_STRING_LEN, fmt,args);
30 ap_log_error(file,line,level,0,s,"%s",buff);
31 va_end(args);
32}
24 33
25#endif /* APACHE20_H */ 34#endif /* APACHE20_H */
diff --git a/build-apache13.bat b/build-apache13.bat
deleted file mode 100644
index 77461ee..0000000
--- a/build-apache13.bat
+++ /dev/null
@@ -1,47 +0,0 @@
1@echo off
2cls
3rem path to Microsoft SDK installation
4SET DIR_MSSDK=C:\Program Files\Microsoft SDK
5rem path to apache2 installation
6SET DIR_APACHE=C:\Program Files\Apache Group\Apache
7rem path to mysql 4.0 installation
8SET DIR_MYSQL=C:\MySQL
9rem Can be set to opt or debug
10SET LIB_MYSQL=opt
11
12copy /Y winconfig.h config.h
13mkdir Release
14cd Release
15Rem Compile all the source code
16echo /MD /W3 /Zi /Ze /O2 > RESP_c.txt
17echo /DNDEBUG /D_WINDOWS /DWIN32 >> RESP_c.txt
18echo /Fd"mod_log_sql" /FD >> RESP_c.txt
19echo /DHAVE_CONFIG_H /DWITH_APACHE13 /DLOGSQL_DECLARE_EXPORT >> RESP_c.txt
20echo /DSHARED_MODULE >> RESP_c.txt
21echo /I.. >> RESP_c.txt
22echo /I"%DIR_MSSDK%\Include" >> RESP_c.txt
23echo /I"%DIR_APACHE%\Include" >> RESP_c.txt
24echo /I"%DIR_MYSQL%\Include" >> RESP_c.txt
25cl @RESP_c.txt /c ..\mod_log_sql.c ..\mod_log_sql_mysql.c
26
27rem link main module
28echo /MACHINE:I386 /SUBSYSTEM:windows > RESP_l.txt
29echo /OUT:mod_log_sql.so /DLL /OPT:REF /DEBUG >> RESP_l.txt
30echo /LIBPATH:"%DIR_APACHE%\lib" >> RESP_l.txt
31echo /LIBPATH:"%DIR_APACHE%\libexec" >> RESP_l.txt
32echo /LIBPATH:"%DIR_MSSDK%\lib" >> RESP_l.txt
33echo ApacheCore.lib >> RESP_l.txt
34link @RESP_l.txt mod_log_sql.obj
35
36rem link mysql module
37echo /MACHINE:I386 /SUBSYSTEM:windows > RESP_l.txt
38echo /OUT:mod_log_sql_mysql.so /DLL /OPT:REF /DEBUG >> RESP_l.txt
39echo /LIBPATH:"%DIR_APACHE%\lib" >> RESP_l.txt
40echo /LIBPATH:"%DIR_APACHE%\libexec" >> RESP_l.txt
41echo /LIBPATH:"%DIR_MYSQL%\lib\%LIB_MYSQL%" >> RESP_l.txt
42echo /LIBPATH:"%DIR_MSSDK%\lib" >> RESP_l.txt
43echo /NODEFAULTLIB:LIBCMT.lib >> RESP_l.txt
44echo ApacheCore.lib >> RESP_l.txt
45echo libmysql.lib mod_log_sql.lib >> RESP_l.txt
46link @RESP_l.txt mod_log_sql_mysql.obj
47cd ..
diff --git a/build-apache2.bat b/build-apache2.bat
deleted file mode 100644
index f44109c..0000000
--- a/build-apache2.bat
+++ /dev/null
@@ -1,40 +0,0 @@
1@echo off
2rem path to Microsoft SDK installation
3SET DIR_MSSDK=C:\Program Files\Microsoft SDK
4rem path to apache2 installation
5SET DIR_APACHE=C:\Program Files\Apache Group\Apache2
6rem path to mysql 4.0 installation
7SET DIR_MYSQL=C:\MySQL
8rem Can be set to opt or debug
9SET LIB_MYSQL=opt
10
11copy /Y winconfig.h config.h
12mkdir Release
13cd Release
14Rem Compile all the source code
15echo /MD /W3 /Zi /O2 /DNDEBUG /D_WINDOWS /DWIN32 > RESP_c.txt
16echo /Fd"mod_log_sql" /FD >> RESP_c.txt
17echo /DHAVE_CONFIG_H /DWITH_APACHE20 /DLOGSQL_DECLARE_EXPORT >> RESP_c.txt
18echo /I.. >> RESP_c.txt
19echo /I"%DIR_MSSDK%\Include" >> RESP_c.txt
20echo /I"%DIR_APACHE%\Include" >> RESP_c.txt
21echo /I"%DIR_MYSQL%\Include" >> RESP_c.txt
22cl @RESP_c.txt /c ..\mod_log_sql.c ..\mod_log_sql_mysql.c
23
24rem link main module
25echo /MACHINE:I386 /SUBSYSTEM:windows > RESP_l.txt
26echo /OUT:mod_log_sql.so /DLL /OPT:REF /DEBUG >> RESP_l.txt
27echo /LIBPATH:"%DIR_APACHE%\lib" >> RESP_l.txt
28echo libapr.lib libaprutil.lib libhttpd.lib >> RESP_l.txt
29link @RESP_l.txt mod_log_sql.obj
30
31rem link mysql module
32echo /MACHINE:I386 /SUBSYSTEM:windows > RESP_l.txt
33echo /OUT:mod_log_sql_mysql.so /DLL /OPT:REF /DEBUG >> RESP_l.txt
34echo /LIBPATH:"%DIR_APACHE%\lib" >> RESP_l.txt
35echo /LIBPATH:"%DIR_MYSQL%\lib\%LIB_MYSQL%" >> RESP_l.txt
36echo /NODEFAULTLIB:LIBCMT.lib >> RESP_l.txt
37echo libapr.lib libaprutil.lib libhttpd.lib >> RESP_l.txt
38echo libmysql.lib mod_log_sql.lib >> RESP_l.txt
39link @RESP_l.txt mod_log_sql_mysql.obj
40cd ..
diff --git a/configure.ac b/configure.ac
index 42e2bde..fb036ce 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,5 @@
1dnl Required initializer 1dnl Required initializer
2AC_INIT(mod_log_sql, 1.98) 2AC_INIT(mod_log_sql, 1.95)
3OOO_CONFIG_NICE(config.nice)
4AC_PREREQ(2.53) 3AC_PREREQ(2.53)
5AC_CONFIG_HEADERS(config.h) 4AC_CONFIG_HEADERS(config.h)
6 5
@@ -9,9 +8,9 @@ AC_CONFIG_SRCDIR(mod_log_sql.c)
9dnl Add a test for a compiler. 8dnl Add a test for a compiler.
10AC_PROG_CC 9AC_PROG_CC
11 10
12APACHE20_VERSION=2.0.40 11APACHE20_VERSION=2.0.44
13APACHE13_VERSION=1.3.20 12APACHE13_VERSION=1.3.20
14CHECK_APACHE($APACHE13_VERSION,$APACHE20_VERSION, 13CHECK_PATH_APACHE($APACHE13_VERSION,$APACHE20_VERSION,
15 :, 14 :,
16 :, 15 :,
17 AC_MSG_ERROR([*** The correct version Apache was not found!]) 16 AC_MSG_ERROR([*** The correct version Apache was not found!])
@@ -31,43 +30,20 @@ CHECK_PATH_MOD_SSL(
31 30
32AC_SUBST(WANT_SSL_MOD) 31AC_SUBST(WANT_SSL_MOD)
33 32
34WANT_MYSQL_MOD=1
35AC_SUBST(WANT_MYSQL_MOD)
36WANT_PGSQL_MOD=0
37AC_SUBST(WANT_PGSQL_MOD)
38WANT_DBI_MOD=0
39AC_SUBST(WANT_DBI_MOD)
40
41case "$target" in
42 *-*-solaris* | *-*-osf* )
43 if test $APACHE_VERSION -eq 1.3; then
44 RT_LIBS=-lrt
45 fi
46 ;;
47 *)
48 RT_LIBS=""
49 ;;
50esac
51
52AC_SUBST(RT_LIBS)
53
54
55AC_CHECK_HEADERS(limits.h) 33AC_CHECK_HEADERS(limits.h)
56 34
57AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h]) 35AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h])
58 36
59dnl Write config.status and the Makefile 37dnl Write config.status and the Makefile
60 38
61AC_OUTPUT(Makefile 39AC_OUTPUT(Makefile Documentation/Makefile)
62docs/Makefile
63contrib/Makefile)
64
65 40
66AC_MSG_RESULT([------------------------------------]) 41AC_MSG_RESULT([------------------------------------])
67AC_MSG_RESULT([Apache version : $AP_VERSION]) 42AC_MSG_RESULT([Apache version : $APACHE_VERSION])
68if test $WANT_SSL_MOD -eq 1; then 43if test $WANT_SSL_MOD -eq 1; then
69 AC_MSG_RESULT([SSL Support : yes]) 44 AC_MSG_RESULT([SSL Support : yes])
70else 45else
71 AC_MSG_RESULT([SSL Support : no]) 46 AC_MSG_RESULT([SSL Support : no])
72 AC_MSG_RESULT([*** Use --enable-ssl to enable SSL support]) 47 AC_MSG_RESULT([*** Use --enable-ssl to enable SSL support])
48 AC_MSG_RESULT([*** and --with-ssl-inc for the directory for SSL headers])
73fi 49fi
diff --git a/contrib/Makefile.in b/contrib/Makefile.in
index b384fd0..c40a711 100644
--- a/contrib/Makefile.in
+++ b/contrib/Makefile.in
@@ -3,10 +3,7 @@
3# Modify these top variables. 3# Modify these top variables.
4SUBDIRS = 4SUBDIRS =
5 5
6EXTRA_DIST = README \ 6EXTRA_DIST = README mysql_import_combined_log.pl
7 create_tables.sql \
8 make_combined_log.pl \
9 mysql_import_combined_log.pl
10 7
11#Don't modify anything below here 8#Don't modify anything below here
12 9
diff --git a/contrib/README b/contrib/README
index bf0e65f..7dac946 100644
--- a/contrib/README
+++ b/contrib/README
@@ -1,38 +1 @@
1This directory contains contributed scripts/programs/utilites for mod_log_sql. This directory contains contributed scripts/programs/utilites related to mod_log_sql.
2
3* create_tables.sql
4
5This is the create table SQL commands to create the access, headers_in,
6headers_out, cookies, and notes tables in the MySQL database.
7Use it like this.
8mysql -u user -h host -p apachelogdatabase < create_tables.sql
9Where:
10 user is the username to log in as,
11 host is the hostname the server is on,
12 apachelogdatabase is the database to put the tables into
13 -p will have mysql ask you for a password for the user
14
15*make_combined_log.pl
16
17This perl script will extract the data from mod_log_sql's tables in the
18database and export a standard Apache combined log file. Use this to run
19logs through a program like webalizer.
20
21You must edit the perl script to configure variables before you run it.
22Usage:
23./make_combined_log.pl days virtualhost
24Where:
25 days is the number of days to fetch (starting from now and going back
26 in time)
27 virtualhost is the name of the virtualhost to retrieve
28
29Example:
30 ./make_combined_log.pl 2 example.com
31
32*mysql_import_combined_log.pl
33
34This is a perl script written by Aaron Jenson that imports a combined log file
35from apache into a SQL database table.. You can use this script to import logs
36from a webserver you are converting over from the standard Apache log system to
37mod_log_sql. A Usage statement can be fetch by running the program with no
38parameters or with --help or -?.
diff --git a/contrib/mysql_import_combined_log.pl b/contrib/mysql_import_combined_log.pl
index bffec20..1c801f2 100644
--- a/contrib/mysql_import_combined_log.pl
+++ b/contrib/mysql_import_combined_log.pl
@@ -1,8 +1,4 @@
1#!/usr/bin/perl -w 1#!/usr/bin/perl -w
2# $Id: mysql_import_combined_log.pl,v 1.4 2004/02/21 18:09:50 urkle Exp $
3# Written by Aaron Jenson.
4# Original source: http://www.visualprose.com/software.php
5# Updated to work under Perl 5.6.1 by Edward Rudd
6use strict; 2use strict;
7use Getopt::Long qw(:config bundling); 3use Getopt::Long qw(:config bundling);
8use DBI; 4use DBI;
@@ -37,44 +33,47 @@ my @cols = (
37); 33);
38my $col = ''; 34my $col = '';
39 35
36%options = (
37 "version" => sub { VERSION_MESSAGE(); exit 0; },
38 "help|?" => sub { HELP_MESSAGE(); exit 0; },
39 );
40
40GetOptions (\%options, 41GetOptions (\%options,
41 "version" => sub { VERSION_MESSAGE(); exit 0; }, 42 "h|host=s",
42 "help|?" => sub { HELP_MESSAGE(); exit 0; }, 43 "d|database=s",
43 "host|h=s", 44 "t|table=s",
44 "database|d=s", 45 "u|username=s",
45 "table|t=s", 46 "p|password=s",
46 "username|u=s", 47 "f|logfile=s");
47 "password|p=s", 48
48 "logfile|f=s"); 49$options{h} ||= 'localhost';
49 50$options{d} ||= '';
50$options{host} ||= 'localhost'; 51$options{u} ||= '';
51$options{database} ||= ''; 52$options{p} ||= '';
52$options{username} ||= ''; 53$options{f} ||= '';
53$options{password} ||= ''; 54
54$options{logfile} ||= ''; 55if( ! $options{d} )
55
56if( ! $options{database} )
57{ 56{
58 HELP_MESSAGE(); 57 HELP_MESSAGE();
59 print "Must supply a database to connect to.\n"; 58 print "Must supply a database to connect to.\n";
60 exit 1; 59 exit 1;
61} 60}
62 61
63if( ! $options{table} ) 62if( ! $options{t} )
64{ 63{
65 HELP_MESSAGE(); 64 HELP_MESSAGE();
66 print "Must supply table name.\n"; 65 print "Must supply table name.\n";
67 exit 1; 66 exit 1;
68} 67}
69 68
70if( $options{logfile} ) 69if( $options{f} )
71{ 70{
72 if( ! -e $options{logfile} ) 71 if( ! -e $options{f} )
73 { 72 {
74 print "File '$options{logfile}' doesn't exist.\n"; 73 print "File '$options{f}' doesn't exist.\n";
75 exit 1; 74 exit 1;
76 } 75 }
77 open(STDIN, "<$options{logfile}") || die "Can't open $options{logfile} for reading."; 76 open(STDIN, "<$options{f}") || die "Can't open $options{f} for reading.";
78} 77}
79 78
80$dbh = Connect(); 79$dbh = Connect();
@@ -82,7 +81,7 @@ if (! $dbh) {
82 exit 1; 81 exit 1;
83} 82}
84 83
85$sql = "INSERT INTO $options{table} ("; 84$sql = "INSERT INTO $options{t} (";
86foreach $col (@cols) 85foreach $col (@cols)
87{ 86{
88 $sql .= "$col," if( $col ); 87 $sql .= "$col," if( $col );
@@ -115,15 +114,15 @@ while($line = <STDIN>)
115} 114}
116print "Parsed $linecount Log lines\n"; 115print "Parsed $linecount Log lines\n";
117print "Inserted $insertcount records\n"; 116print "Inserted $insertcount records\n";
118print "to table '$options{table}' in database '$options{database}' on '$options{host}'\n"; 117print "to table '$options{t}' in database '$options{d}' on '$options{h}'\n";
119 118
120# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 119# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
121# Connects to a MySQL database and returns the connection. 120# Connects to a MySQL database and returns the connection.
122# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 121# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
123sub Connect 122sub Connect
124{ 123{
125 my $dsn = "DBI:mysql:$options{database};hostname=$options{host}"; 124 my $dsn = "DBI:mysql:$options{d};hostname=$options{h}";
126 return DBI->connect( $dsn, $options{username}, $options{password} ); 125 return DBI->connect( $dsn, $options{u}, $options{p} );
127} 126}
128 127
129 128
@@ -216,9 +215,7 @@ EOF
216# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 215# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
217sub VERSION_MESSAGE 216sub VERSION_MESSAGE
218{ 217{
219 print "mysql_import_combined_log.pl version 1.2\n"; 218 print "mysql_import_combined_log.pl version 1.1\n";
220 print "Version 1.0 Written by Aaron Jenson.\n";
221 print "Update to work with perl 5.6.1 by Edward Rudd\n";
222} 219}
223 220
2241; 2211;
diff --git a/contrib/create_tables.sql b/create_tables.sql
index 0fe0f4b..0fe0f4b 100644
--- a/contrib/create_tables.sql
+++ b/create_tables.sql
diff --git a/docs/.cvsignore b/docs/.cvsignore
deleted file mode 100644
index 73cd04a..0000000
--- a/docs/.cvsignore
+++ /dev/null
@@ -1,3 +0,0 @@
1Makefile
2manual.html
3manual.pdf
diff --git a/docs/README b/docs/README
deleted file mode 100644
index dd40351..0000000
--- a/docs/README
+++ /dev/null
@@ -1,7 +0,0 @@
1The "original" document is the Docbook file "manual.xml" -- all other
2files here are derived from it.
3
4To read the HTML docs, open manual.html in your browser.
5
6To generate other formats of the documentation use xmlto or your favorite
7xslt docbook converter to convert the xml file.
diff --git a/functions.h b/functions.h
index dcbc939..917a1f9 100644
--- a/functions.h
+++ b/functions.h
@@ -1,5 +1,4 @@
1/* $Id$ */ 1/* $Header: /home/cvs/mod_log_sql/functions.h,v 1.2 2004/02/05 21:59:46 urkle Exp $ */
2
3/* Begin the individual functions that, given a request r, 2/* Begin the individual functions that, given a request r,
4 * extract the needed information from it and return the 3 * extract the needed information from it and return the
5 * value to the calling entity. 4 * value to the calling entity.
@@ -176,16 +175,20 @@ static const char *extract_specific_cookie(request_rec *r, char *a)
176 char *cookiebuf; 175 char *cookiebuf;
177 176
178 if (a != NULL) { 177 if (a != NULL) {
179 log_error(APLOG_MARK,APLOG_DEBUG, 0, r->server, 178 #ifdef DEBUG
180 "watching for cookie '%s'", a); 179 log_error(APLOG_MARK,APLOG_DEBUG,
180 r->server,"watching for cookie '%s'", a);
181 #endif
181 182
182 /* Fetch out the cookie header */ 183 /* Fetch out the cookie header */
183 cookiestr = (char *)apr_table_get(r->headers_in, "cookie2"); 184 cookiestr = (char *)apr_table_get(r->headers_in, "cookie2");
184 if (cookiestr != NULL) { 185 if (cookiestr != NULL) {
185 log_error(APLOG_MARK,APLOG_DEBUG, 0, r->server, 186 #ifdef DEBUG
186 "Cookie2: [%s]", cookiestr); 187 log_error(APLOG_MARK,APLOG_DEBUG,r->server,
188 "Cookie2: [%s]", cookiestr);
189 #endif
187 /* Does the cookie string contain one with our name? */ 190 /* Does the cookie string contain one with our name? */
188 isvalid = ap_strstr_c(cookiestr, a); 191 isvalid = strstr(cookiestr, a);
189 if (isvalid != NULL) { 192 if (isvalid != NULL) {
190 /* Move past the cookie name and equal sign */ 193 /* Move past the cookie name and equal sign */
191 isvalid += strlen(a) + 1; 194 isvalid += strlen(a) + 1;
@@ -193,7 +196,7 @@ static const char *extract_specific_cookie(request_rec *r, char *a)
193 cookiebuf = apr_pstrdup(r->pool, isvalid); 196 cookiebuf = apr_pstrdup(r->pool, isvalid);
194 /* Segregate just this cookie out of the string 197 /* Segregate just this cookie out of the string
195 * with a terminating nul at the first semicolon */ 198 * with a terminating nul at the first semicolon */
196 cookieend = ap_strchr(cookiebuf, ';'); 199 cookieend = strchr(cookiebuf, ';');
197 if (cookieend != NULL) 200 if (cookieend != NULL)
198 *cookieend = '\0'; 201 *cookieend = '\0';
199 return cookiebuf; 202 return cookiebuf;
@@ -202,13 +205,15 @@ static const char *extract_specific_cookie(request_rec *r, char *a)
202 205
203 cookiestr = (char *)apr_table_get(r->headers_in, "cookie"); 206 cookiestr = (char *)apr_table_get(r->headers_in, "cookie");
204 if (cookiestr != NULL) { 207 if (cookiestr != NULL) {
205 log_error(APLOG_MARK,APLOG_DEBUG, 0, r->server, 208 #ifdef DEBUG
206 "Cookie: [%s]", cookiestr); 209 log_error(APLOG_MARK,APLOG_DEBUG,r->server,
207 isvalid = ap_strstr_c(cookiestr, a); 210 "Cookie: [%s]", cookiestr);
211 #endif
212 isvalid = strstr(cookiestr, a);
208 if (isvalid != NULL) { 213 if (isvalid != NULL) {
209 isvalid += strlen(a) + 1; 214 isvalid += strlen(a) + 1;
210 cookiebuf = apr_pstrdup(r->pool, isvalid); 215 cookiebuf = apr_pstrdup(r->pool, isvalid);
211 cookieend = ap_strchr(cookiebuf, ';'); 216 cookieend = strchr(cookiebuf, ';');
212 if (cookieend != NULL) 217 if (cookieend != NULL)
213 *cookieend = '\0'; 218 *cookieend = '\0';
214 return cookiebuf; 219 return cookiebuf;
@@ -217,13 +222,15 @@ static const char *extract_specific_cookie(request_rec *r, char *a)
217 222
218 cookiestr = apr_table_get(r->headers_out, "set-cookie"); 223 cookiestr = apr_table_get(r->headers_out, "set-cookie");
219 if (cookiestr != NULL) { 224 if (cookiestr != NULL) {
220 log_error(APLOG_MARK,APLOG_DEBUG, 0, r->server, 225 #ifdef DEBUG
221 "Set-Cookie: [%s]", cookiestr); 226 log_error(APLOG_MARK,APLOG_DEBUG,r->server,
222 isvalid = ap_strstr_c(cookiestr, a); 227 "Set-Cookie: [%s]", cookiestr);
228 #endif
229 isvalid = strstr(cookiestr, a);
223 if (isvalid != NULL) { 230 if (isvalid != NULL) {
224 isvalid += strlen(a) + 1; 231 isvalid += strlen(a) + 1;
225 cookiebuf = apr_pstrdup(r->pool, isvalid); 232 cookiebuf = apr_pstrdup(r->pool, isvalid);
226 cookieend = ap_strchr(cookiebuf, ';'); 233 cookieend = strchr(cookiebuf, ';');
227 if (cookieend != NULL) 234 if (cookieend != NULL)
228 *cookieend = '\0'; 235 *cookieend = '\0';
229 return cookiebuf; 236 return cookiebuf;
diff --git a/functions13.h b/functions13.h
index 54e3138..7fe8850 100644
--- a/functions13.h
+++ b/functions13.h
@@ -1,4 +1,4 @@
1/* $Id$ */ 1/* $Header: /home/cvs/mod_log_sql/functions13.h,v 1.3 2004/02/05 21:59:46 urkle Exp $ */
2 2
3static const char *extract_bytes_sent(request_rec *r, char *a) 3static const char *extract_bytes_sent(request_rec *r, char *a)
4{ 4{
diff --git a/functions20.h b/functions20.h
index ee58513..31d9e4b 100644
--- a/functions20.h
+++ b/functions20.h
@@ -1,5 +1,5 @@
1/* $Id$ */ 1/* $Header: /home/cvs/mod_log_sql/functions20.h,v 1.3 2004/02/05 21:59:46 urkle Exp $ */
2 2/* functions */
3static const char *extract_bytes_sent(request_rec *r, char *a) 3static const char *extract_bytes_sent(request_rec *r, char *a)
4{ 4{
5 if (!r->sent_bodyct || !r->bytes_sent) { 5 if (!r->sent_bodyct || !r->bytes_sent) {
diff --git a/gen_todo.pl b/gen_todo.pl
deleted file mode 100755
index 20b0894..0000000
--- a/gen_todo.pl
+++ /dev/null
@@ -1,64 +0,0 @@
1#!/usr/bin/perl
2
3# Copyright 2003-2004 Edward Rudd
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17use strict;
18my $rootdir = ".";
19opendir(MYDIR, $rootdir) or die "Unable to open directory";
20print "Building TODO file for source directory\n";
21my $todo_header = "* Things TODO *\n\n";
22if (open ( TODOFILE, "TODO.in")) {
23 $todo_header = do { local $/; <TODOFILE> };
24 close (TODOFILE);
25}
26open (TODOFILE, "> TODO");
27print TODOFILE $todo_header;
28print "Parsing...";
29while (my $entry = readdir(MYDIR)) {
30 next if (!($entry =~ /\.[ch]$/));
31 print "$entry...";
32 open(DAFILE, $rootdir.'/'.$entry) or die "Unable to open file\n";
33 my $linenumber = 0;
34 my $status = 0; # 0=no comment 1=comment 2=in todo block
35 while (my $line = <DAFILE>) {
36 $linenumber++;
37 if ($status==0) {
38 if ( ($line =~ /\/\/\s+TODO: (.*)/) || ($line =~ /\/\*\s+TODO: (.*)\s*\*\//) ){
39 print TODOFILE $entry.":".$linenumber.": ".$1."\n";
40 } else {
41 if ($line =~ /\/\*\*/) {
42 $status = 1;
43 }
44 }
45 } else {
46 if ($line =~ /\*\//) {
47 $status = 0;
48 } else {
49 if ($status==1) {
50 if ($line =~ /TODO:/) {
51 $status=2;
52 }
53 } else {
54 if ($line =~ /\* \s+-?\s*(.*)/) {
55 print TODOFILE $entry.":".$linenumber.": ".$1."\n";
56 }
57 }
58 }
59 }
60 }
61 close(DAFILE);
62}
63print "\n";
64closedir(MYDIR);
diff --git a/m4/apache.m4 b/m4/apache.m4
new file mode 100644
index 0000000..3d76b72
--- /dev/null
+++ b/m4/apache.m4
@@ -0,0 +1,175 @@
1dnl TEST_APACHE_VERSION([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
2dnl Test for Apache
3dnl
4AC_DEFUN(TEST_APACHE_VERSION,
5[dnl
6 AC_REQUIRE([AC_CANONICAL_TARGET])
7
8 min_apache_version="$1"
9 no_apache=""
10 ac_save_CFLAGS="$CFLAGS"
11 CFLAGS="$CFLAGS $APACHE_CFLAGS"
12
13 AC_TRY_RUN([
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
17#include "httpd.h"
18
19#ifndef AP_SERVER_BASEREVISION
20 #define AP_SERVER_BASEREVISION SERVER_BASEREVISION
21#endif
22
23char* my_strdup (char *str)
24{
25 char *new_str;
26
27 if (str) {
28 new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char));
29 strcpy (new_str, str);
30 } else
31 new_str = NULL;
32
33 return new_str;
34}
35
36int main (int argc, char *argv[])
37{
38 int major1, minor1, micro1;
39 int major2, minor2, micro2;
40 char *tmp_version;
41
42 { FILE *fp = fopen("conf.apachetest", "a"); if ( fp ) fclose(fp); }
43
44 tmp_version = my_strdup("$min_apache_version");
45 if (sscanf(tmp_version, "%d.%d.%d", &major1, &minor1, &micro1) != 3) {
46 printf("%s, bad version string\n", "$min_apache_version");
47 exit(1);
48 }
49 tmp_version = my_strdup(AP_SERVER_BASEREVISION);
50 if (sscanf(tmp_version, "%d.%d.%d", &major2, &minor2, &micro2) != 3) {
51 printf("%s, bad version string\n", AP_SERVER_BASEREVISION);
52 exit(1);
53 }
54 if ((major2 > major1) ||
55 ((major2 == major1) && (minor2 > minor1)) ||
56 ((major2 == major1) && (minor2 == minor1) && (micro2 >= micro1)))
57 {
58 exit(0);
59 } else {
60 /*printf("\n*** This module requires apache version %d.%d.%d or greater\n",
61 major1, minor1, micro1);
62 printf("*** I found version %d.%d.%d. Please verify the installation directory\n",
63 major2, minor2, micro2);
64 printf("*** of apache with the --with-apxs configure option.\n");*/
65 exit(1);
66 }
67}
68
69],, no_apache=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
70 CFLAGS="$ac_save_CFLAGS"
71
72 if test "x$no_apache" = x ; then
73 ifelse([$2], , :, [$2])
74 else
75 if test -f conf.apachetest ; then
76 :
77 else
78 echo "*** Could not run Apache test program, checking why..."
79 CFLAGS="$CFLAGS APACHE_CFLAGS"
80 AC_TRY_LINK([
81#include <stdio.h>
82#include "httpd.h"
83
84int main(int argc, char *argv[])
85{ return 0; }
86#undef main
87#define main K_and_R_C_main
88], [ return 0; ],
89 [ echo "*** The test program compiled, but failed to run. Check config.log" ],
90 [ echo "*** The test program failed to compile or link. Check config.log" ])
91 CFLAGS="$ac_save_CFLAGS"
92 fi
93 ifelse([$3], , :, [$3])
94 fi
95 rm -f conf.apachetest
96])
97
98dnl CHECK_PATH_APACHE([MINIMUM13-VERSION [, MINIMUM20-VERSION [,
99dnl ACTION-IF-FOUND13 [, ACTION-IF-FOUND20 [, ACTION-IF-NOT-FOUND]]])
100dnl Test for Apache apxs
101dnl
102AC_DEFUN(CHECK_PATH_APACHE,
103[dnl
104AC_ARG_WITH(
105 apxs,
106 [AC_HELP_STRING([--with-apxs=PATH],[Location to APXS binary (default: /usr)])],
107 apxs_prefix="$withval",
108 apxs_prefix="/usr"
109 )
110AC_ARG_ENABLE(
111 apachetest,
112 [AC_HELP_STRING([--disable-apachetest],[Do not try to compile and run apache version test program])],
113 ,
114 enable_apachetest=yes
115 )
116
117 PATH="$apxs_prefix:$apxs_prefix/bin:$apxs_prefix/sbin:$PATH"
118 if test -x $apxs_prefix -a ! -d $apxs_prefix; then
119 APXS_BIN=$apxs_prefix
120 else
121 AC_PATH_PROG(APXS_BIN, apxs, no, [$PATH])
122 fi
123 min_apache13_version=ifelse([$1], ,no,$1)
124 min_apache20_version=ifelse([$2], ,no,$2)
125 no_apxs=""
126 if test "$APXS_BIN" = "no"; then
127 AC_MSG_ERROR([*** The apxs binary installed by apache could not be found!])
128 AC_MSG_ERROR([*** If apache is installed in PREFIX, make sure PREFIX/bin is in])
129 AC_MSG_ERROR([*** your path, or use the --with-apxs configure option])
130 else
131 APACHE_INCDIR=`$APXS_BIN -q INCLUDEDIR`
132 APACHE_CPPFLAGS=`$APXS_BIN -q CFLAGS`
133 APACHE_CFLAGS="-I$APACHE_INCDIR"
134 APACHE_MODDIR=`$APXS_BIN -q LIBEXECDIR`
135
136 if test "x$enable_apachetest" = "xyes" ; then
137 if test "$min_apache20_version" != "no"; then
138 AC_MSG_CHECKING(for Apache 2.0 version >= $min_apache20_version)
139 TEST_APACHE_VERSION($min_apache20_version,
140 AC_MSG_RESULT(yes)
141 AC_DEFINE(WITH_APACHE20,1,[Define to 1 if we are compiling with Apache 2.0.x])
142 APACHE_VERSION="20"
143 APXS_EXTENSION=.la
144 APACHE_DEFS="-DWITH_APACHE20"
145 ifelse([$4], , , $4),
146 AC_MSG_RESULT(no)
147 if test "x$min_apache13_version" = "xno"; then
148 ifelse([$5], , , $5)
149 fi
150 )
151 fi
152 if test "$min_apache13_version" != "no" -a "x$APACHE_VERSION" = "x"; then
153 AC_MSG_CHECKING(for Apache 1.3 version >= $min_apache13_version)
154 TEST_APACHE_VERSION($min_apache13_version,
155 AC_MSG_RESULT(yes)
156 AC_DEFINE(WITH_APACHE13,1,[Define to 1 if we are compiling with Apache 1.3.x])
157 APACHE_VERSION="13"
158 APXS_EXTENSION=.so
159 APACHE_CFLAGS="-g $APACHE_CFLAGS"
160 APACHE_DEFS="-DWITH_APACHE13"
161 ifelse([$3], , , $3),
162 AC_MSG_RESULT(no)
163 ifelse([$5], , , $5)
164 )
165 fi
166 fi
167 AC_SUBST(APACHE_DEFS)
168 AC_SUBST(APACHE_CFLAGS)
169 AC_SUBST(APACHE_CPPFLAGS)
170 AC_SUBST(APACHE_INCDIR)
171 AC_SUBST(APACHE_MODDIR)
172 AC_SUBST(APACHE_VERSION)
173 AC_SUBST(APXS_EXTENSION)
174 fi
175])
diff --git a/m4/mod_ssl.m4 b/m4/mod_ssl.m4
new file mode 100644
index 0000000..c431bce
--- /dev/null
+++ b/m4/mod_ssl.m4
@@ -0,0 +1,50 @@
1dnl CHECK_PATH_MOD_SSL([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
2dnl Test for mod_ssl and openssl header directory.
3dnl
4AC_DEFUN(CHECK_PATH_MOD_SSL,
5[dnl
6AC_ARG_ENABLE(
7 ssl,
8 [AC_HELP_STRING([--enable-ssl],[Compile in SSL support])],
9 ssl_val=yes,
10 ssl_val=no
11 )
12AC_ARG_WITH(
13 ssl-inc,
14 [AC_HELP_STRING([--with-ssl-inc=DIR],[Location of SSL header files])],
15 ssl_incdir="$withval",
16 )
17AC_ARG_WITH(
18 db-inc,
19 [AC_HELP_STRING([--with-db-inc=DIR],[Location of DB header files])],
20 db_incdir="$withval",
21 db_incdir="/usr/include/db1"
22 )
23
24 if test "x$ssl_val" = "xyes"; then
25 ac_save_CFLAGS=$CFLAGS
26 ac_save_CPPFLAGS=$CPPFLAGS
27 MOD_SSL_CFLAGS="-I/usr/include/openssl"
28 if test "x$ssl_incdir" != "x"; then
29 MOD_SSL_CFLAGS="-I$ssl_incdir -I$ssl_incdir/openssl $MOD_SSL_CFLAGS"
30 fi
31 if test "x$db_incdir" != "x"; then
32 MOD_SSL_CFLAGS="-I$db_incdir $MOD_SSL_CFLAGS"
33 fi
34 CFLAGS="$APACHE_CFLAGS $APACHE_CPPFLAGS $MOD_SSL_CFLAGS $CFLAGS"
35 CPPFLAGS="$APACHE_CFLAGS $APACHE_CPPFLAGS $MOD_SSL_CFLAGS $CPPFLAGS"
36 AC_CHECK_HEADERS([mod_ssl.h],
37 mod_ssl_h=yes
38 )
39 CFLAGS=$ac_save_CFLAGS
40 CPPFLAGS=$ac_save_CPPFLAGS
41 if test "x$mod_ssl_h" = "x"; then
42 ifelse([$2], , :, [$2])
43 else
44 AC_SUBST(MOD_SSL_CFLAGS)
45 ifelse([$1], , :, [$1])
46 fi
47 else
48 ifelse([$2], , :, [$2])
49 fi
50])
diff --git a/m4/mysql.m4 b/m4/mysql.m4
new file mode 100644
index 0000000..7892f88
--- /dev/null
+++ b/m4/mysql.m4
@@ -0,0 +1,64 @@
1dnl CHECK_PATH_MYSQL([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUNT]])
2dnl Check for MySQL Libs
3dnl
4AC_DEFUN(CHECK_PATH_MYSQL,
5[dnl
6AC_ARG_WITH(
7 mysql,
8 [AC_HELP_STRING([--with-mysql],[Path to MySQL client library])],
9 mysql_prefix="$withval",
10
11 )
12AC_ARG_ENABLE(
13 mysqltest,
14 [AC_HELP_STRING([--disble-mysqltest],[Do not try to compile and run mysql test program])],
15 ,
16 enable_apachetest=yes)
17
18 AC_REQUIRE([AC_CANONICAL_TARGET])
19 ac_save_CFLAGS=$CFLAGS
20 ac_save_LDFLAGS=$LDFLAGS
21 if test "x$mysql_prefix" != "x" && test "x$mysql_prefix" != "xyes"; then
22 MYSQL_LDFLAGS="-L${mysql_prefix}/lib -L${mysql_prefix}/lib/mysql -L${mysql_prefix}/mysql/lib"
23 MYSQL_CFLAGS="-I${mysql_prefix}/include -I${mysql_prefix}/include/mysql -I${mysql_prefix}/mysql/include"
24 else
25 MYSQL_LDFLAGS="-L/usr/local/mysql/lib -L/usr/lib/mysql -L/usr/mysql/lib -L/usr/local/lib/mysql -L/usr/local/mysql/lib/mysql -L/usr/mysql/lib/mysql"
26 MYSQL_CFLAGS="-I/usr/local/mysql/include -I/usr/include/mysql -I/usr/mysql/include -I/usr/local/include/mysql -I/usr/local/mysql/include/mysql -I/usr/mysql/include/mysql"
27 fi
28 CFLAGS="$CFLAGS $MYSQL_CFLAGS"
29 LDFLAGS="$LDFLAGS $MYSQL_LDFLAGS"
30 AC_CHECK_LIB(m, floor)
31 AC_CHECK_LIB(z, gzclose)
32 with_mysql="yes"
33 AC_DEFINE(WITH_MYSQL,1,[Define to 1 if we are compiling with mysql])
34 AC_CHECK_LIB(mysqlclient, mysql_init, ,
35 [AC_MSG_ERROR(libmysqlclient is needed for MySQL support)])
36 MYSQL_LIBS=$LIBS
37 AC_CHECK_FUNCS(mysql_real_escape_string)
38 AC_MSG_CHECKING(whether mysql clients can run)
39 AC_TRY_RUN([
40 #include <stdio.h>
41 #include <mysql.h>
42 int main(void)
43 {
44 MYSQL *a = mysql_init(NULL);
45 return 0;
46 }
47 ], , no_mysql=yes,[echo $ac_n "cross compiling; assumed OK.... $ac_c"])
48 CFLAGS=$ac_save_CFLAGS
49 LDFLAGS=$ac_save_LDFLAGS
50 if test "x$no_mysql" = x; then
51 AC_MSG_RESULT(yes)
52 ifelse([$1], , :, [$1])
53 else
54 AC_MSG_RESULT(no)
55 echo "*** MySQL could not be found ***"
56 MYSQL_CFLAGS=""
57 MYSQL_LDFLAGS=""
58 MYSQL_LIBS=""
59 ifelse([$2], , :, [$2])
60 fi
61 AC_SUBST(MYSQL_LDFLAGS)
62 AC_SUBST(MYSQL_CFLAGS)
63 AC_SUBST(MYSQL_LIBS)
64])
diff --git a/contrib/make_combined_log.pl b/make_combined_log.pl
index 2c55271..1b50f11 100644
--- a/contrib/make_combined_log.pl
+++ b/make_combined_log.pl
@@ -1,6 +1,6 @@
1#!/usr/bin/perl 1#!/usr/bin/perl
2 2
3# $Id: make_combined_log.pl,v 1.2 2004/02/12 23:32:55 urkle Exp $ 3# $Id: make_combined_log.pl,v 1.1 2003/12/20 07:16:05 urkle Exp $
4# 4#
5# make_combined_log.pl 5# make_combined_log.pl
6# 6#
@@ -34,9 +34,14 @@ $| = 1;
34 34
35use DBI; 35use DBI;
36 36
37# Remove the # in front of this line when you have 37# Remember, $#ARGV is parameters minus one...
38# edited the variables below. 38if ($#ARGV != 1) {
39#$has_edited_source = 1; 39 die "Incorrect usage, please read the perl source code for correct usage."
40}
41
42$days = $ARGV[0];
43$virthost = $ARGV[1];
44
40# 45#
41# Set up the proper variables to permit database access 46# Set up the proper variables to permit database access
42# 47#
@@ -47,20 +52,6 @@ $serverPass = "somepass";
47$serverTbl = "acc_log_tbl"; 52$serverTbl = "acc_log_tbl";
48$serverDb = "apache"; 53$serverDb = "apache";
49 54
50if (!defined($has_edited_source)) {
51 print "Please edit this file and configure it first.\n";
52 print "This program is $0\n";
53 exit 1;
54}
55# Remember, $#ARGV is parameters minus one...
56if ($#ARGV != 1) {
57 print "Usage $0 days virtualhost\n";
58 exit 1;
59}
60
61$days = $ARGV[0];
62$virthost = $ARGV[1];
63
64# 55#
65# Other constants 56# Other constants
66# 57#
@@ -137,3 +128,4 @@ while (@data = $records->fetchrow_array) {
137# Done 128# Done
138# 129#
139$records->finish; 130$records->finish;
131
diff --git a/mod_log_sql.c b/mod_log_sql.c
index fc9dcc0..7320f66 100644
--- a/mod_log_sql.c
+++ b/mod_log_sql.c
@@ -1,4 +1,19 @@
1/* $Id$ */ 1/* $Header: /home/cvs/mod_log_sql/mod_log_sql.c,v 1.14 2004/02/05 21:59:46 urkle Exp $ */
2/* --------*
3 * DEFINES *
4 * --------*/
5
6/* The enduser may wish to modify this */
7#define DEBUG
8
9/* The enduser won't modify these */
10#define MYSQL_ERROR(mysql) ((mysql)?(mysql_error(mysql)):"MySQL server has gone away")
11
12/* ---------*
13 * INCLUDES *
14 * ---------*/
15#include "mysql.h"
16#include "mysqld_error.h"
2 17
3#if defined(WITH_APACHE20) 18#if defined(WITH_APACHE20)
4# include "apache20.h" 19# include "apache20.h"
@@ -36,7 +51,7 @@
36#define DEFAULT_HIN_TABLE_NAME "headers_in" 51#define DEFAULT_HIN_TABLE_NAME "headers_in"
37#define DEFAULT_HOUT_TABLE_NAME "headers_out" 52#define DEFAULT_HOUT_TABLE_NAME "headers_out"
38#define DEFAULT_COOKIE_TABLE_NAME "cookies" 53#define DEFAULT_COOKIE_TABLE_NAME "cookies"
39#define DEFAULT_PRESERVE_FILE "logs/mod_log_sql-preserve" 54#define DEFAULT_PRESERVE_FILE "/tmp/sql-preserve"
40 55
41/* -------------* 56/* -------------*
42 * DECLARATIONS * 57 * DECLARATIONS *
@@ -54,11 +69,17 @@ typedef struct {
54 int massvirtual; 69 int massvirtual;
55 int createtables; 70 int createtables;
56 int forcepreserve; 71 int forcepreserve;
57 int disablepreserve; 72 char *tabletype;
73 char *dbname;
74 char *dbhost;
75 char *dbuser;
76 char *dbpwd;
58 char *machid; 77 char *machid;
59 int announce; 78 char *socketfile;
60 logsql_dbconnection db; 79 unsigned int tcpport;
61 logsql_dbdriver *driver; 80 int insertdelayed;
81 MYSQL server;
82 MYSQL *server_p;
62} global_config_t; 83} global_config_t;
63 84
64static global_config_t global_config; 85static global_config_t global_config;
@@ -66,11 +87,11 @@ static global_config_t global_config;
66/* structure to hold helper function info */ 87/* structure to hold helper function info */
67typedef struct { 88typedef struct {
68 char key; /* item letter character */ 89 char key; /* item letter character */
69 logsql_item_func *func; /* its extraction function */ 90 log_sql_item_func *func; /* its extraction function */
70 const char *sql_field_name; /* its column in SQL */ 91 const char *sql_field_name; /* its column in SQL */
71 int want_orig_default; /* if it requires the original request prior to internal redirection */ 92 int want_orig_default; /* if it requires the original request prior to internal redirection */
72 int string_contents; /* if it returns a string */ 93 int string_contents; /* if it returns a string */
73} logsql_item; 94} log_sql_item;
74 95
75/* But the contents of this structure will vary by virtual server. 96/* But the contents of this structure will vary by virtual server.
76 * This permits each virtual server to vary its configuration slightly 97 * This permits each virtual server to vary its configuration slightly
@@ -93,28 +114,33 @@ typedef struct {
93 const char *transfer_table_name; 114 const char *transfer_table_name;
94 const char *transfer_log_format; 115 const char *transfer_log_format;
95 apr_pool_t *parsed_pool; 116 apr_pool_t *parsed_pool;
96 logsql_item **parsed_log_format; 117 log_sql_item **parsed_log_format;
97 const char *preserve_file; 118 const char *preserve_file;
98 const char *cookie_name; 119 const char *cookie_name;
99} logsql_state; 120} logsql_state;
100 121
101 122
102/* list of "handlers" for log types */ 123/* -----------------*
103static apr_array_header_t *logsql_item_list; 124 * HELPER FUNCTIONS *
125 * -----------------*/
126
127static int safe_create_tables(logsql_state *cls, request_rec *r);
104 128
105/* Registration function for extract functions * 129static apr_array_header_t *log_sql_item_list;
130
131/* Registration Function for extract functions *
106 * and update parse cache for transfer_log_format * 132 * and update parse cache for transfer_log_format *
107 * this is exported from the module */ 133 * this is exported from the module */
108LOGSQL_DECLARE(void) log_sql_register_item(server_rec *s, apr_pool_t *p, 134LOGSQL_DECLARE(void) log_sql_register_item(server_rec *s, apr_pool_t *p,
109 char key, logsql_item_func *func, const char *sql_field_name, 135 char key, log_sql_item_func *func, const char *sql_field_name,
110 int want_orig_default, int string_contents) 136 int want_orig_default, int string_contents)
111{ 137{
112 server_rec *ts; 138 server_rec *ts;
113 logsql_item *item; 139 log_sql_item *item;
114 if (!logsql_item_list) 140 if (!log_sql_item_list)
115 logsql_item_list = apr_array_make(p,10, sizeof(logsql_item)); 141 log_sql_item_list = apr_array_make(p,10, sizeof(log_sql_item));
116 142
117 item= apr_array_push(logsql_item_list); 143 item= apr_array_push(log_sql_item_list);
118 item->key = key; 144 item->key = key;
119 item->func = func; 145 item->func = func;
120 item->sql_field_name = sql_field_name; 146 item->sql_field_name = sql_field_name;
@@ -128,21 +154,14 @@ LOGSQL_DECLARE(void) log_sql_register_item(server_rec *s, apr_pool_t *p,
128 char *pos; 154 char *pos;
129 155
130 if (cfg->transfer_log_format) { 156 if (cfg->transfer_log_format) {
131 if ( (pos = ap_strchr_c(cfg->transfer_log_format,key))!=NULL) { 157 if ( (pos = strchr(cfg->transfer_log_format,key))!=NULL) {
132 cfg->parsed_log_format[pos - cfg->transfer_log_format] = item; 158 cfg->parsed_log_format[pos - cfg->transfer_log_format] = item;
133 } 159 }
134 } 160 }
135 } 161 }
136} 162}
137 163
138/* Registration function for database drivers */ 164/* Include all the extract functions */
139LOGSQL_DECLARE(void) log_sql_register_driver(apr_pool_t *p,
140 logsql_dbdriver *driver)
141{
142 global_config.driver = driver;
143}
144
145/* Include all the core extract functions */
146#include "functions.h" 165#include "functions.h"
147#if defined(WITH_APACHE13) 166#if defined(WITH_APACHE13)
148# include "functions13.h" 167# include "functions13.h"
@@ -150,33 +169,82 @@ LOGSQL_DECLARE(void) log_sql_register_driver(apr_pool_t *p,
150# include "functions20.h" 169# include "functions20.h"
151#endif 170#endif
152 171
153static logsql_opendb_ret log_sql_opendb_link(server_rec* s) 172/* Routine to escape the 'dangerous' characters that would otherwise
173 * corrupt the INSERT string: ', \, and "
174 */
175static const char *escape_query(const char *from_str, apr_pool_t *p)
154{ 176{
155 logsql_opendb_ret result; 177 if (!from_str)
156 if (global_config.forcepreserve) { 178 return NULL;
157 global_config.db.connected = 1; 179 else {
158 return LOGSQL_OPENDB_PRESERVE; 180 char *to_str;
159 } 181 unsigned long length = strlen(from_str);
160 if (global_config.db.connected) { 182 unsigned long retval;
161 return LOGSQL_OPENDB_ALREADY; 183
184 /* Pre-allocate a new string that could hold twice the original, which would only
185 * happen if the whole original string was 'dangerous' characters.
186 */
187 to_str = (char *) apr_palloc(p, length * 2 + 1);
188 if (!to_str) {
189 return from_str;
190 }
191
192 if (!global_config.server_p) {
193 /* Well, I would have liked to use the current database charset. mysql is
194 * unavailable, however, so I fall back to the slightly less respectful
195 * mysql_escape_string() function that uses the default charset.
196 */
197 retval = mysql_escape_string(to_str, from_str, length);
198 } else {
199 /* MySQL is available, so I'll go ahead and respect the current charset when
200 * I perform the escape.
201 */
202 retval = mysql_real_escape_string(global_config.server_p, to_str, from_str, length);
203 }
204
205 if (retval)
206 return to_str;
207 else
208 return from_str;
162 } 209 }
163 /* database 210}
164 host 211
165 user 212static int open_logdb_link(server_rec* s)
166 passwd 213{
214 /* Returns:
215 3 if preserve forced
216 2 if already connected
217 1 if successful
218 0 if unsuccessful
167 */ 219 */
168 if (global_config.db.parms) { 220
169 result = global_config.driver->connect(s, &global_config.db); 221 if (global_config.forcepreserve)
170 if (result==LOGSQL_OPENDB_FAIL) { 222 return 3;
171 global_config.db.connected = 0; 223
224 if (global_config.server_p)
225 return 2;
226
227 if ((global_config.dbname) && (global_config.dbhost) && (global_config.dbuser) && (global_config.dbpwd)) {
228 mysql_init(&global_config.server);
229 global_config.server_p = mysql_real_connect(&global_config.server, global_config.dbhost, global_config.dbuser, global_config.dbpwd, global_config.dbname, global_config.tcpport, global_config.socketfile, 0);
230
231 if (global_config.server_p) {
232 #ifdef DEBUG
233 log_error(APLOG_MARK,APLOG_DEBUG,s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'",
234 global_config.dbhost, global_config.tcpport, global_config.dbname, global_config.dbuser, global_config.socketfile);
235 #endif
236 return 1;
172 } else { 237 } else {
173 global_config.db.connected = 1; 238 #ifdef DEBUG
239 log_error(APLOG_MARK,APLOG_DEBUG,s,"mod_log_sql: database connection error: %s",MYSQL_ERROR(&global_config.server));
240 log_error(APLOG_MARK,APLOG_DEBUG,s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'",
241 global_config.dbhost, global_config.tcpport, global_config.dbname, global_config.dbuser, global_config.socketfile);
242 #endif
243 return 0;
174 } 244 }
175 return result;
176 } else { 245 } else {
177 log_error(APLOG_MARK, APLOG_ERR, 0, s, 246 log_error(APLOG_MARK,APLOG_ERR,s,"mod_log_sql: insufficient configuration info to establish database link");
178 "mod_log_sql: insufficient configuration info to establish database link"); 247 return 0;
179 return LOGSQL_OPENDB_FAIL;
180 } 248 }
181} 249}
182 250
@@ -194,22 +262,15 @@ static void preserve_entry(request_rec *r, const char *query)
194 #if defined(WITH_APACHE20) 262 #if defined(WITH_APACHE20)
195 apr_file_t *fp; 263 apr_file_t *fp;
196 apr_status_t result; 264 apr_status_t result;
265 result = apr_file_open(&fp, cls->preserve_file,APR_APPEND, APR_OS_DEFAULT, r->pool);
197 #elif defined(WITH_APACHE13) 266 #elif defined(WITH_APACHE13)
198 FILE *fp; 267 FILE *fp;
199 int result; 268 int result;
200 #endif
201 /* If preserve file is disabled bail out */
202 if (global_config.disablepreserve)
203 return;
204 #if defined(WITH_APACHE20)
205 result = apr_file_open(&fp, cls->preserve_file,APR_APPEND | APR_WRITE | APR_CREATE, APR_OS_DEFAULT, r->pool);
206 #elif defined(WITH_APACHE13)
207 fp = ap_pfopen(r->pool, cls->preserve_file, "a"); 269 fp = ap_pfopen(r->pool, cls->preserve_file, "a");
208 result = (fp)?0:errno; 270 result = (fp)?0:1;
209 #endif 271 #endif
210 if (result != APR_SUCCESS) { 272 if (result != APR_SUCCESS) {
211 log_error(APLOG_MARK, APLOG_ERR, result, r->server, 273 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: attempted append of local preserve file but failed.");
212 "attempted append of local preserve file '%s' but failed.",cls->preserve_file);
213 } else { 274 } else {
214 #if defined(WITH_APACHE20) 275 #if defined(WITH_APACHE20)
215 apr_file_printf(fp,"%s;\n", query); 276 apr_file_printf(fp,"%s;\n", query);
@@ -218,12 +279,252 @@ static void preserve_entry(request_rec *r, const char *query)
218 fprintf(fp,"%s;\n", query); 279 fprintf(fp,"%s;\n", query);
219 ap_pfclose(r->pool, fp); 280 ap_pfclose(r->pool, fp);
220 #endif 281 #endif
221 log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, 282 #ifdef DEBUG
222 "mod_log_sql: entry preserved in %s", cls->preserve_file); 283 log_error(APLOG_MARK,APLOG_DEBUG,r->server,"mod_log_sql: entry preserved in %s", cls->preserve_file);
284 #endif
223 } 285 }
224} 286}
225 287
226 288
289/*-----------------------------------------------------*
290 * safe_sql_query: perform a database query with *
291 * a degree of safety and error checking. *
292 * *
293 * Parms: request record, SQL insert statement *
294 * Returns: 0 (OK) on success *
295 * 1 if have no log handle *
296 * 2 if insert delayed failed (kluge) *
297 * the actual MySQL return code on error *
298 *-----------------------------------------------------*/
299static unsigned int safe_sql_query(request_rec *r, const char *query)
300{
301 int retval;
302 struct timespec delay, remainder;
303 int ret;
304 void (*handler) (int);
305 logsql_state *cls;
306 unsigned int real_error = 0;
307 const char *real_error_str = NULL;
308
309 /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */
310 handler = signal(SIGPIPE, SIG_IGN);
311
312 /* First attempt for the query */
313 if (!global_config.server_p) {
314 signal(SIGPIPE, handler);
315 return 1;
316 } else if (!(retval = mysql_query(global_config.server_p, query))) {
317 signal(SIGPIPE, handler);
318 return 0;
319 }
320
321 /* If we ran the query and it returned an error, try to be robust.
322 * (After all, the module thought it had a valid mysql_log connection but the query
323 * could have failed for a number of reasons, so we have to be extra-safe and check.) */
324 if (global_config.insertdelayed) {
325 real_error_str = MYSQL_ERROR(global_config.server_p);
326 } else {
327 real_error = mysql_errno(global_config.server_p);
328 }
329
330 /* Check to see if the error is "nonexistent table" */
331 if (global_config.insertdelayed) {
332 retval = (strstr(real_error_str, "Table")) && (strstr(real_error_str,"doesn't exist"));
333 } else {
334 retval = (real_error == ER_NO_SUCH_TABLE);
335 }
336 if (retval) {
337 if (global_config.createtables) {
338 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: table doesn't exist...creating now");
339 cls = ap_get_module_config(r->server->module_config, &log_sql_module);
340 if (safe_create_tables(cls, r)) {
341 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: child attempted but failed to create one or more tables for %s, preserving query", ap_get_server_name(r));
342 preserve_entry(r, query);
343 retval = mysql_errno(global_config.server_p);
344 } else {
345 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: tables successfully created - retrying query");
346 if (mysql_query(global_config.server_p, query)) {
347 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: giving up, preserving query");
348 preserve_entry(r, query);
349 retval = mysql_errno(global_config.server_p);
350 } else
351 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: query successful after table creation");
352 retval = 0;
353 }
354 } else {
355 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql, table doesn't exist, creation denied by configuration, preserving query");
356 preserve_entry(r, query);
357 retval = ER_NO_SUCH_TABLE;
358 }
359 /* Restore SIGPIPE to its original handler function */
360 signal(SIGPIPE, handler);
361 return retval;
362 }
363
364 /* Handle all other types of errors */
365
366 cls = ap_get_module_config(r->server->module_config, &log_sql_module);
367
368 /* Something went wrong, so start by trying to restart the db link. */
369 if (global_config.insertdelayed) {
370 real_error = 2;
371 } else {
372 real_error = mysql_errno(global_config.server_p);
373 }
374
375 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: first attempt failed, API said: error %d, \"%s\"", real_error, MYSQL_ERROR(global_config.server_p));
376 mysql_close(global_config.server_p);
377 global_config.server_p = NULL;
378 open_logdb_link(r->server);
379
380 if (global_config.server_p == NULL) { /* still unable to link */
381 signal(SIGPIPE, handler);
382 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: reconnect failed, unable to reach database. SQL logging stopped until child regains a db connection.");
383 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: log entries are being preserved in %s", cls->preserve_file);
384 return 1;
385 } else
386 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: db reconnect successful");
387
388 /* First sleep for a tiny amount of time. */
389 delay.tv_sec = 0;
390 delay.tv_nsec = 250000000; /* max is 999999999 (nine nines) */
391 ret = nanosleep(&delay, &remainder);
392 if (ret && errno != EINTR)
393 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: nanosleep unsuccessful");
394
395 /* Then make our second attempt */
396 retval = mysql_query(global_config.server_p,query);
397
398 /* If this one also failed, log that and append to our local offline file */
399 if (retval) {
400 if (global_config.insertdelayed) {
401 real_error = 2;
402 } else {
403 real_error = mysql_errno(global_config.server_p);
404 }
405
406 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: second attempt failed, API said: error %d, \"%s\" -- preserving", real_error, MYSQL_ERROR(global_config.server_p));
407 preserve_entry(r, query);
408 retval = real_error;
409 } else
410 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: second attempt successful");
411
412 /* Restore SIGPIPE to its original handler function */
413 signal(SIGPIPE, handler);
414 return retval;
415}
416
417/*-----------------------------------------------------*
418 * safe_create_tables: create SQL table set for the *
419 * virtual server represented by cls. *
420 * *
421 * Parms: virtserver structure, request record *
422 * Returns: 0 on no errors *
423 * mysql error code on failure *
424 *-----------------------------------------------------*/
425static int safe_create_tables(logsql_state *cls, request_rec *r)
426{
427 int retval;
428 unsigned int create_results;
429 char *create_access = NULL;
430 char *create_notes = NULL;
431 char *create_hout = NULL;
432 char *create_hin = NULL;
433 char *create_cookies = NULL;
434
435 char *type_suffix = NULL;
436
437 char *createprefix = "create table if not exists `";
438 char *access_suffix =
439 "` (id char(19),\
440 agent varchar(255),\
441 bytes_sent int unsigned,\
442 child_pid smallint unsigned,\
443 cookie varchar(255),\
444 machine_id varchar(25),\
445 request_file varchar(255),\
446 referer varchar(255),\
447 remote_host varchar(50),\
448 remote_logname varchar(50),\
449 remote_user varchar(50),\
450 request_duration smallint unsigned,\
451 request_line varchar(255),\
452 request_method varchar(10),\
453 request_protocol varchar(10),\
454 request_time char(28),\
455 request_uri varchar(255),\
456 request_args varchar(255),\
457 server_port smallint unsigned,\
458 ssl_cipher varchar(25),\
459 ssl_keysize smallint unsigned,\
460 ssl_maxkeysize smallint unsigned,\
461 status smallint unsigned,\
462 time_stamp int unsigned,\
463 virtual_host varchar(255))";
464
465 char *notes_suffix =
466 "` (id char(19),\
467 item varchar(80),\
468 val varchar(80))";
469
470 char *headers_suffix =
471 "` (id char(19),\
472 item varchar(80),\
473 val varchar(80))";
474
475 char *cookies_suffix =
476 "` (id char(19),\
477 item varchar(80),\
478 val varchar(80))";
479 if (global_config.tabletype) {
480 type_suffix = apr_pstrcat(r->pool, " TYPE=", global_config.tabletype, NULL);
481 }
482 /* Find memory long enough to hold the whole CREATE string + \0 */
483 create_access = apr_pstrcat(r->pool, createprefix, cls->transfer_table_name, access_suffix, type_suffix, NULL);
484 create_notes = apr_pstrcat(r->pool, createprefix, cls->notes_table_name, notes_suffix, type_suffix, NULL);
485 create_hout = apr_pstrcat(r->pool, createprefix, cls->hout_table_name, headers_suffix, type_suffix, NULL);
486 create_hin = apr_pstrcat(r->pool, createprefix, cls->hin_table_name, headers_suffix, type_suffix, NULL);
487 create_cookies= apr_pstrcat(r->pool, createprefix, cls->cookie_table_name, cookies_suffix, type_suffix, NULL);
488
489 #ifdef DEBUG
490 log_error(APLOG_MARK,APLOG_DEBUG,r->server,"mod_log_sql: create string: %s", create_access);
491 log_error(APLOG_MARK,APLOG_DEBUG,r->server,"mod_log_sql: create string: %s", create_notes);
492 log_error(APLOG_MARK,APLOG_DEBUG,r->server,"mod_log_sql: create string: %s", create_hout);
493 log_error(APLOG_MARK,APLOG_DEBUG,r->server,"mod_log_sql: create string: %s", create_hin);
494 log_error(APLOG_MARK,APLOG_DEBUG,r->server,"mod_log_sql: create string: %s", create_cookies);
495 #endif
496
497 /* Assume that things worked unless told otherwise */
498 retval = 0;
499
500 if ((create_results = safe_sql_query(r, create_access))) {
501 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: failed to create access table");
502 retval = create_results;
503 }
504
505 if ((create_results = safe_sql_query(r, create_notes))) {
506 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: failed to create notes table");
507 retval = create_results;
508 }
509
510 if ((create_results = safe_sql_query(r, create_hin))) {
511 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: failed to create header_in table");
512 retval = create_results;
513 }
514
515 if ((create_results = safe_sql_query(r, create_hout))) {
516 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: failed to create header_out table");
517 retval = create_results;
518 }
519
520 if ((create_results = safe_sql_query(r, create_cookies))) {
521 log_error(APLOG_MARK,APLOG_ERR,r->server,"mod_log_sql: failed to create cookies table");
522 retval = create_results;
523 }
524
525 return retval;
526}
527
227/* ------------------------------------------------* 528/* ------------------------------------------------*
228 * Command handlers that are called according * 529 * Command handlers that are called according *
229 * to the directives found at Apache runtime. * 530 * to the directives found at Apache runtime. *
@@ -266,6 +567,7 @@ static const char *set_global_string_slot(cmd_parms *cmd,
266 *(const char **)((char *)ptr + offset) = apr_pstrdup(cmd->pool,arg); 567 *(const char **)((char *)ptr + offset) = apr_pstrdup(cmd->pool,arg);
267 return NULL; 568 return NULL;
268} 569}
570
269static const char *set_server_string_slot(cmd_parms *cmd, 571static const char *set_server_string_slot(cmd_parms *cmd,
270 void *struct_ptr, 572 void *struct_ptr,
271 const char *arg) 573 const char *arg)
@@ -279,27 +581,6 @@ static const char *set_server_string_slot(cmd_parms *cmd,
279 return NULL; 581 return NULL;
280} 582}
281 583
282static const char *set_server_file_slot(cmd_parms *cmd,
283 void *struct_ptr,
284 const char *arg)
285{
286 void *ptr = ap_get_module_config(cmd->server->module_config,
287 &log_sql_module);
288 int offset = (int)(long)cmd->info;
289 const char *path;
290
291 path = ap_server_root_relative(cmd->pool, (char *)arg);
292
293 if (!path) {
294 return apr_pstrcat(cmd->pool, "Invalid file path ",
295 arg, NULL);
296 }
297
298 *(const char **)((char*)ptr + offset) = path;
299
300 return NULL;
301}
302
303static const char *set_logformat_slot(cmd_parms *cmd, 584static const char *set_logformat_slot(cmd_parms *cmd,
304 void *struct_ptr, 585 void *struct_ptr,
305 const char *arg) 586 const char *arg)
@@ -310,7 +591,7 @@ static const char *set_logformat_slot(cmd_parms *cmd,
310 cfg->transfer_log_format = arg; 591 cfg->transfer_log_format = arg;
311/* apr_pool_clear(cfg->parsed_pool);*/ 592/* apr_pool_clear(cfg->parsed_pool);*/
312 cfg->parsed_log_format = apr_pcalloc(cfg->parsed_pool, 593 cfg->parsed_log_format = apr_pcalloc(cfg->parsed_pool,
313 strlen(arg) * sizeof(logsql_item *)); 594 strlen(arg) * sizeof(log_sql_item *));
314 return NULL; 595 return NULL;
315} 596}
316 597
@@ -326,69 +607,16 @@ static const char *set_server_nmv_string_slot(cmd_parms *parms,
326 return set_server_string_slot(parms,struct_ptr,arg); 607 return set_server_string_slot(parms,struct_ptr,arg);
327} 608}
328 609
329/* Set a DB connection parameter */ 610static const char *set_log_sql_info(cmd_parms *cmd, void *dummy, const char *host, const char *user, const char *pwd)
330static const char *set_dbparam(cmd_parms *cmd,
331 void *struct_ptr,
332 const char *key,
333 const char *val)
334{ 611{
335 if (!global_config.db.parms) { 612 if (*host != '.') {
336 global_config.db.parms = apr_table_make(cmd->pool,5); 613 global_config.dbhost = apr_pstrdup(cmd->pool,host);
337 } 614 }
338 apr_table_set(global_config.db.parms,key,val); 615 if (*user != '.') {
339 return NULL; 616 global_config.dbuser = apr_pstrdup(cmd->pool,user);
340} 617 }
341 618 if (*pwd != '.') {
342static const char *set_dbparam_slot(cmd_parms *cmd, 619 global_config.dbpwd = apr_pstrdup(cmd->pool,pwd);
343 void *struct_ptr,
344 const char *arg)
345{
346 const char *param = (char *)cmd->info;
347 set_dbparam(cmd,NULL,param,arg);
348 return NULL;
349}
350
351/* Sets basic connection info */
352static const char *set_log_sql_info(cmd_parms *cmd, void *dummy,
353 const char *host, const char *user, const char *pwd)
354{
355 if (!user) { /* user is null, so only one arg passed */
356 /* TODO: to more error checking/force all params to be set */
357 apr_uri_t uri;
358 apr_uri_parse(cmd->pool, host, &uri);
359 if (uri.scheme) {
360 set_dbparam(cmd, NULL, "driver", uri.scheme);
361 }
362 if (uri.hostname) {
363 set_dbparam(cmd, NULL, "hostname", uri.hostname);
364 }
365 if (uri.user) {
366 set_dbparam(cmd, NULL, "username", uri.user);
367 }
368 if (uri.password) {
369 set_dbparam(cmd, NULL, "password", uri.password);
370 }
371 if (uri.port_str) {
372 set_dbparam(cmd, NULL, "port", uri.port_str);
373 }
374 if (uri.path) {
375 /* extract Database name */
376 char *off = ap_strchr(++uri.path,'/');
377 if (off)
378 *off='\0';
379 set_dbparam(cmd, NULL, "database", uri.path);
380
381 }
382 } else {
383 if (*host != '.') {
384 set_dbparam(cmd, NULL, "hostname", host);
385 }
386 if (*user != '.') {
387 set_dbparam(cmd, NULL, "username", user);
388 }
389 if (*pwd != '.') {
390 set_dbparam(cmd, NULL, "password", pwd);
391 }
392 } 620 }
393 return NULL; 621 return NULL;
394} 622}
@@ -401,13 +629,20 @@ static const char *add_server_string_slot(cmd_parms *cmd,
401 void *ptr = ap_get_module_config(cmd->server->module_config, 629 void *ptr = ap_get_module_config(cmd->server->module_config,
402 &log_sql_module); 630 &log_sql_module);
403 int offset = (int)(long)cmd->info; 631 int offset = (int)(long)cmd->info;
404 apr_array_header_t *ary = *(apr_array_header_t **)((char *)ptr + offset); 632 apr_array_header_t *ary = *(apr_array_header_t **)(ptr + offset);
405 addme = apr_array_push(ary); 633 addme = apr_array_push(ary);
406 *addme = apr_pstrdup(ary->pool, arg); 634 *addme = apr_pstrdup(ary->pool, arg);
407 635
408 return NULL; 636 return NULL;
409} 637}
410 638
639static const char *set_log_sql_tcp_port(cmd_parms *parms, void *dummy, const char *arg)
640{
641 global_config.tcpport = (unsigned int)atoi(arg);
642
643 return NULL;
644}
645
411/*------------------------------------------------------------* 646/*------------------------------------------------------------*
412 * Apache-specific hooks into the module code * 647 * Apache-specific hooks into the module code *
413 * that are defined in the array 'mysql_lgog_module' (at EOF) * 648 * that are defined in the array 'mysql_lgog_module' (at EOF) *
@@ -416,47 +651,59 @@ static const char *add_server_string_slot(cmd_parms *cmd,
416#if defined(WITH_APACHE20) 651#if defined(WITH_APACHE20)
417static apr_status_t log_sql_close_link(void *data) 652static apr_status_t log_sql_close_link(void *data)
418{ 653{
419 global_config.driver->disconnect(&global_config.db); 654 mysql_close(global_config.server_p);
420 return APR_SUCCESS; 655 return APR_SUCCESS;
421} 656}
422#elif defined(WITH_APACHE13) 657#elif defined(WITH_APACHE13)
423static void log_sql_child_exit(server_rec *s, apr_pool_t *p) 658static void log_sql_child_exit(server_rec *s, apr_pool_t *p)
424{ 659{
425 global_config.driver->disconnect(&global_config.db); 660 mysql_close(global_config.server_p);
426} 661}
427#endif 662#endif
428 663
429/* Child Init */ 664/* Child Init */
430#if defined(WITH_APACHE20) 665#if defined(WITH_APACHE20)
431static void log_sql_child_init(apr_pool_t *p, server_rec *s) 666static void log_sql_child_init(apr_pool_t *p, server_rec *s)
667{
668 apr_pool_cleanup_register(p, NULL, log_sql_close_link, log_sql_close_link);
669}
670
671static int log_sql_open(apr_pool_t *pc, apr_pool_t *p, apr_pool_t *pt, server_rec *s)
432#elif defined(WITH_APACHE13) 672#elif defined(WITH_APACHE13)
433static void log_sql_child_init(server_rec *s, apr_pool_t *p) 673static void log_sql_child_init(server_rec *s, apr_pool_t *p)
434#endif 674#endif
435{ 675{
436 logsql_opendb_ret retval; 676 int retval;
437# if defined(WITH_APACHE20) 677 /* Open a link to the database */
438 /* Register cleanup hook to close DDB connection (apache 2 doesn't have child_exit) */ 678 retval = open_logdb_link(s);
439 apr_pool_cleanup_register(p, NULL, log_sql_close_link, log_sql_close_link); 679 if (!retval)
440# endif 680 log_error(APLOG_MARK,APLOG_ERR,s,"mod_log_sql: child spawned but unable to open database link");
441 /* Open a link to the database */ 681
442 retval = log_sql_opendb_link(s); 682 #ifdef DEBUG
443 switch (retval) { 683 if ( (retval == 1) || (retval == 2) )
444 case LOGSQL_OPENDB_FAIL: 684 log_error(APLOG_MARK,APLOG_DEBUG,s,"mod_log_sql: open_logdb_link successful");
445 log_error(APLOG_MARK, APLOG_ERR, 0, s, 685 if (retval == 3)
446 "mod_log_sql: child spawned but unable to open database link"); 686 log_error(APLOG_MARK,APLOG_DEBUG,s,"mod_log_sql: open_logdb_link said that preservation is forced");
447 break; 687 #endif
448 case LOGSQL_OPENDB_SUCCESS: 688#if defined(WITH_APACHE20)
449 case LOGSQL_OPENDB_ALREADY: 689 return OK;
450 log_error(APLOG_MARK,APLOG_DEBUG,0, s, 690#endif
451 "mod_log_sql: open_logdb_link successful");
452 break;
453 case LOGSQL_OPENDB_PRESERVE:
454 log_error(APLOG_MARK,APLOG_DEBUG, 0, s,
455 "mod_log_sql: open_logdb_link said that preservation is forced");
456 break;
457 }
458} 691}
692/*
693void *log_sql_initializer(server_rec *main_server, apr_pool_t *p)
694{
695 server_rec *s;
696
697 logsql_state main_conf = ap_get_module_config(main_server->module_config, &log_sql_module);
698
699 for (server_rec *s = main_server; s; s = s->next) {
700 conf = ap_get_module_config(s->module_config, &log_sql_module);
701 if (conf->transfer_log_format == NULL && s != main_server) {
702 *conf = *main_conf;
703 }
459 704
705}
706 */
460/* post_config / module_init */ 707/* post_config / module_init */
461#if defined(WITH_APACHE20) 708#if defined(WITH_APACHE20)
462static int log_sql_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) 709static int log_sql_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
@@ -464,6 +711,12 @@ static int log_sql_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptem
464static void log_sql_module_init(server_rec *s, apr_pool_t *p) 711static void log_sql_module_init(server_rec *s, apr_pool_t *p)
465#endif 712#endif
466{ 713{
714 /* Initialize Global configuration */
715 if (!global_config.socketfile)
716 global_config.socketfile = "/tmp/mysql.sock";
717 if (!global_config.tcpport)
718 global_config.tcpport = 3306;
719
467 /* TODO: Add local_address, remote_address, server_name, connection_status */ 720 /* TODO: Add local_address, remote_address, server_name, connection_status */
468 /* Register handlers */ 721 /* Register handlers */
469 log_sql_register_item(s,p,'A', extract_agent, "agent", 1, 1); 722 log_sql_register_item(s,p,'A', extract_agent, "agent", 1, 1);
@@ -490,136 +743,11 @@ static void log_sql_module_init(server_rec *s, apr_pool_t *p)
490 log_sql_register_item(s,p,'U', extract_request_uri, "request_uri", 1, 1); 743 log_sql_register_item(s,p,'U', extract_request_uri, "request_uri", 1, 1);
491 log_sql_register_item(s,p,'v', extract_virtual_host, "virtual_host", 0, 1); 744 log_sql_register_item(s,p,'v', extract_virtual_host, "virtual_host", 0, 1);
492 745
493 if (global_config.announce) {
494 ap_add_version_component(p, PACKAGE_NAME"/"PACKAGE_VERSION);
495 }
496 /* ap_server_root_relative any default preserve file locations */
497 {
498 server_rec *cur_s;
499 const char *default_p = ap_server_root_relative(p, DEFAULT_PRESERVE_FILE);
500 for (cur_s = s; cur_s != NULL; cur_s= cur_s->next) {
501 logsql_state *cls = ap_get_module_config(cur_s->module_config,
502 &log_sql_module);
503 if (cls->preserve_file == DEFAULT_PRESERVE_FILE)
504 cls->preserve_file = default_p;
505 }
506 }
507#if defined(WITH_APACHE20) 746#if defined(WITH_APACHE20)
508 return OK; 747 return OK;
509#endif 748#endif
510} 749}
511 750
512/* This function handles calling the DB module, handling errors
513 * of missing tables and lost DB connections, and falling back to
514 * preserving the DB query.
515 *
516 * Parms: request record, table type, table name, and the full SQL command
517 */
518
519static logsql_query_ret safe_sql_insert(request_rec *r, logsql_tabletype table_type,
520 const char *table_name, const char *query) {
521
522 logsql_query_ret result;
523 logsql_state *cls = ap_get_module_config(r->server->module_config,
524 &log_sql_module);
525
526 if (!global_config.db.connected) {
527 /* preserve query */
528 return LOGSQL_QUERY_NOLINK;
529 }
530
531 result = global_config.driver->insert(r,&global_config.db,query);
532
533 /* If we ran the query and it returned an error, try to be robust.
534 * (After all, the module thought it had a valid mysql_log connection but the query
535 * could have failed for a number of reasons, so we have to be extra-safe and check.) */
536 switch (result) {
537 case LOGSQL_QUERY_SUCCESS:
538 return LOGSQL_QUERY_SUCCESS;
539 case LOGSQL_QUERY_NOLINK:
540 return LOGSQL_QUERY_FAIL;
541 /* TODO: What do we do here */
542 case LOGSQL_QUERY_FAIL:
543 global_config.driver->disconnect(&global_config.db);
544 global_config.db.connected = 0;
545 /* re-open the connection and try again */
546 if (log_sql_opendb_link(r->server) != LOGSQL_OPENDB_FAIL) {
547 log_error(APLOG_MARK,APLOG_NOTICE,0, r->server,"db reconnect successful");
548# if defined(WITH_APACHE20)
549 apr_sleep(apr_time_from_sec(0.25)); /* pause for a quarter second */
550# elif defined(WITH_APACHE13)
551# if defined(WIN32)
552 Sleep((DWORD)0.25);
553# else
554 {
555 struct timespec delay, remainder;
556 int nanoret;
557 delay.tv_sec = 0;
558 delay.tv_nsec = 250000000; /* pause for a quarter second */
559 nanoret = nanosleep(&delay, &remainder);
560 if (nanoret && errno != EINTR) {
561 log_error(APLOG_MARK,APLOG_ERR, errno, r->server,"nanosleep unsuccessful");
562 }
563 }
564# endif /* win32 */
565# endif
566 result = global_config.driver->insert(r,&global_config.db,query);
567 if (result == LOGSQL_QUERY_SUCCESS) {
568 return LOGSQL_QUERY_SUCCESS;
569 } else {
570 log_error(APLOG_MARK,APLOG_ERR,0,r->server,"second attempt failed");
571 preserve_entry(r, query);
572 return LOGSQL_QUERY_PRESERVED;
573 }
574 } else {
575 log_error(APLOG_MARK,APLOG_ERR,0,r->server,
576 "reconnect failed, unable to reach database. SQL logging stopped until child regains a db connection.");
577 log_error(APLOG_MARK,APLOG_ERR,0,r->server,
578 "log entries are being preserved in %s",cls->preserve_file);
579 preserve_entry(r, query);
580 return LOGSQL_QUERY_PRESERVED;
581 }
582 break;
583 case LOGSQL_QUERY_NOTABLE:
584 if (global_config.createtables) {
585 log_error(APLOG_MARK,APLOG_ERR,0,r->server,
586 "table doesn't exist...creating now");
587 if ((result = global_config.driver->create_table(r, &global_config.db, table_type,
588 table_name))!=LOGSQL_TABLE_SUCCESS) {
589 log_error(APLOG_MARK,APLOG_ERR,result,r->server,
590 "child attempted but failed to create one or more tables for %s, preserving query", ap_get_server_name(r));
591 preserve_entry(r, query);
592 return LOGSQL_QUERY_PRESERVED;
593 } else {
594 log_error(APLOG_MARK,APLOG_ERR,result, r->server,
595 "tables successfully created - retrying query");
596 if ((result = global_config.driver->insert(r,&global_config.db,query))!=LOGSQL_QUERY_SUCCESS) {
597 log_error(APLOG_MARK,APLOG_ERR,result, r->server,
598 "giving up, preserving query");
599 preserve_entry(r, query);
600 return LOGSQL_QUERY_PRESERVED;
601 } else {
602 log_error(APLOG_MARK,APLOG_NOTICE,0, r->server,
603 "query successful after table creation");
604 return LOGSQL_QUERY_SUCCESS;
605 }
606 }
607 } else {
608 log_error(APLOG_MARK,APLOG_ERR,0,r->server,
609 "table doesn't exist, creation denied by configuration, preserving query");
610 preserve_entry(r, query);
611 return LOGSQL_QUERY_PRESERVED;
612 }
613 break;
614 default:
615 log_error(APLOG_MARK,APLOG_ERR,0, r->server,
616 "Invalid return code from mog_log_query");
617 return LOGSQL_QUERY_FAIL;
618 break;
619 }
620 return LOGSQL_QUERY_FAIL;
621}
622
623/* This function gets called to create a per-server configuration 751/* This function gets called to create a per-server configuration
624 * record. It will always be called for the main server and 752 * record. It will always be called for the main server and
625 * for each virtual server that is established. Each server maintains 753 * for each virtual server that is established. Each server maintains
@@ -636,7 +764,7 @@ static void *log_sql_make_state(apr_pool_t *p, server_rec *s)
636 cls->transfer_log_format = DEFAULT_TRANSFER_LOG_FMT; 764 cls->transfer_log_format = DEFAULT_TRANSFER_LOG_FMT;
637 apr_pool_create(&cls->parsed_pool, p); 765 apr_pool_create(&cls->parsed_pool, p);
638 cls->parsed_log_format = apr_pcalloc(cls->parsed_pool, 766 cls->parsed_log_format = apr_pcalloc(cls->parsed_pool,
639 strlen(cls->transfer_log_format) * sizeof(logsql_item *)); 767 strlen(cls->transfer_log_format) * sizeof(log_sql_item *));
640 cls->notes_table_name = DEFAULT_NOTES_TABLE_NAME; 768 cls->notes_table_name = DEFAULT_NOTES_TABLE_NAME;
641 cls->hin_table_name = DEFAULT_HIN_TABLE_NAME; 769 cls->hin_table_name = DEFAULT_HIN_TABLE_NAME;
642 cls->hout_table_name = DEFAULT_HOUT_TABLE_NAME; 770 cls->hout_table_name = DEFAULT_HOUT_TABLE_NAME;
@@ -654,92 +782,31 @@ static void *log_sql_make_state(apr_pool_t *p, server_rec *s)
654 return (void *) cls; 782 return (void *) cls;
655} 783}
656 784
657
658/* Iterates through an array of char* and searches for a matching element
659 * Returns 0 if not found, 1 if found */
660static int in_array(apr_array_header_t *ary, const char *elem)
661{
662 int itr;
663 for (itr = 0; itr < ary->nelts; itr++) {
664 if (!strcmp(elem,((char **)ary->elts)[itr])) {
665 return 1;
666 }
667 }
668 return 0;
669}
670
671
672/* Parse through cookie lists and merge based on +/- prefixes */
673#define DO_MERGE_ARRAY(parent,child,pool) \
674if (apr_is_empty_array(child)) { \
675 apr_array_cat(child, parent); \
676} else { \
677 apr_array_header_t *addlist, *dellist; \
678 char **elem, **ptr = (char **)(child->elts); \
679 int itr, overwrite = 0; \
680 addlist = apr_array_make(pool,5,sizeof(char *)); \
681 dellist = apr_array_make(subp,5,sizeof(char *)); \
682\
683 for (itr=0; itr<child->nelts; itr++) { \
684 if (*ptr[itr] == '+') { \
685 elem = (char **)apr_array_push(addlist); \
686 *elem = (ptr[itr]+1); \
687 } else if (*ptr[itr] == '-') { \
688 elem = (char **)apr_array_push(dellist); \
689 *elem = (ptr[itr]+1); \
690 } else { \
691 overwrite = 1; \
692 elem = (char **)apr_array_push(addlist); \
693 *elem = ptr[itr]; \
694 } \
695 } \
696 child = apr_array_make(p,1,sizeof(char *)); \
697 ptr = (char **)(parent->elts); \
698 if (overwrite==0) { \
699 /* if we are not overwriting the existing then prepare for merge */ \
700 for (itr=0; itr<parent->nelts; itr++) { \
701 if (!in_array(addlist, ptr[itr]) && !in_array(dellist,ptr[itr])) { \
702 elem = apr_array_push(child); \
703 *elem = apr_pstrdup(p, ptr[itr]); \
704 } \
705 } \
706 } \
707 apr_array_cat(child, addlist); \
708}
709
710static void *log_sql_merge_state(apr_pool_t *p, void *basev, void *addv) 785static void *log_sql_merge_state(apr_pool_t *p, void *basev, void *addv)
711{ 786{
712 /* Fetch the two states to merge */ 787 /* Fetch the two states to merge */
713 logsql_state *parent = (logsql_state *) basev; 788 logsql_state *parent = (logsql_state *) basev;
714 logsql_state *child = (logsql_state *) addv; 789 logsql_state *child = (logsql_state *) addv;
715 790
716 apr_pool_t *subp;
717
718 apr_pool_create(&subp,p);
719
720 /* Child can override these, otherwise they default to parent's choice. 791 /* Child can override these, otherwise they default to parent's choice.
721 * If the parent didn't set them, create reasonable defaults for the 792 * If the parent didn't set them, create reasonable defaults for the
722 * ones that should have such default settings. Leave the others null. */ 793 * ones that should have such default settings. Leave the others null. */
723 794
795 child->transfer_table_name = child->transfer_table_name ?
796 child->transfer_table_name : parent->transfer_table_name;
724 /* No default for transfer_table_name because we want its absence 797 /* No default for transfer_table_name because we want its absence
725 * to disable logging. */ 798 * to disable logging. */
726 if (!child->transfer_table_name) {
727 child->transfer_table_name = parent->transfer_table_name;
728 }
729 799
730 if (child->transfer_log_format == DEFAULT_TRANSFER_LOG_FMT) { 800 if (child->transfer_log_format == DEFAULT_TRANSFER_LOG_FMT) {
731 child->transfer_log_format = parent->transfer_log_format; 801 child->transfer_log_format = parent->transfer_log_format;
732 /*apr_pool_clear(child->parsed_pool);*/ 802 /*apr_pool_clear(child->parsed_pool);*/
733 child->parsed_log_format = apr_pcalloc(child->parsed_pool, 803 child->parsed_log_format = apr_pcalloc(child->parsed_pool,
734 strlen(child->transfer_log_format) * sizeof(logsql_item *)); 804 strlen(child->transfer_log_format) * sizeof(log_sql_item *));
735 } 805 }
736 806
737 if (child->preserve_file == DEFAULT_PRESERVE_FILE) 807 if (child->preserve_file == DEFAULT_PRESERVE_FILE)
738 child->preserve_file = parent->preserve_file; 808 child->preserve_file = parent->preserve_file;
739 /* server_root_relative the preserve file location */ 809
740 if (child->preserve_file == DEFAULT_PRESERVE_FILE)
741 child->preserve_file = ap_server_root_relative(p, DEFAULT_PRESERVE_FILE);
742
743 if (child->notes_table_name == DEFAULT_NOTES_TABLE_NAME) 810 if (child->notes_table_name == DEFAULT_NOTES_TABLE_NAME)
744 child->notes_table_name = parent->notes_table_name; 811 child->notes_table_name = parent->notes_table_name;
745 812
@@ -752,20 +819,30 @@ static void *log_sql_merge_state(apr_pool_t *p, void *basev, void *addv)
752 if (child->cookie_table_name == DEFAULT_COOKIE_TABLE_NAME) 819 if (child->cookie_table_name == DEFAULT_COOKIE_TABLE_NAME)
753 child->cookie_table_name = parent->cookie_table_name; 820 child->cookie_table_name = parent->cookie_table_name;
754 821
755 DO_MERGE_ARRAY(parent->transfer_ignore_list, child->transfer_ignore_list, subp); 822 if (apr_is_empty_array(child->transfer_ignore_list))
756 DO_MERGE_ARRAY(parent->transfer_accept_list, child->transfer_accept_list, subp); 823 apr_array_cat(child->transfer_ignore_list, parent->transfer_ignore_list);
757 DO_MERGE_ARRAY(parent->remhost_ignore_list, child->remhost_ignore_list, subp); 824
758 DO_MERGE_ARRAY(parent->notes_list, child->notes_list, subp); 825 if (apr_is_empty_array(child->transfer_accept_list))
759 DO_MERGE_ARRAY(parent->hin_list, child->hin_list, subp); 826 apr_array_cat(child->transfer_accept_list, parent->transfer_accept_list);
760 DO_MERGE_ARRAY(parent->hout_list, child->hout_list, subp); 827
761 DO_MERGE_ARRAY(parent->cookie_list,child->cookie_list, subp); 828 if (apr_is_empty_array(child->remhost_ignore_list))
829 apr_array_cat(child->remhost_ignore_list, parent->remhost_ignore_list);
762 830
763 apr_pool_destroy(subp); 831 if (apr_is_empty_array(child->notes_list))
832 apr_array_cat(child->notes_list, parent->notes_list);
833
834 if (apr_is_empty_array(child->hin_list))
835 apr_array_cat(child->hin_list, parent->hin_list);
836
837 if (apr_is_empty_array(child->hout_list))
838 apr_array_cat(child->hout_list, parent->hout_list);
839
840 if (apr_is_empty_array(child->cookie_list))
841 apr_array_cat(child->cookie_list, parent->cookie_list);
764 842
765 if (!child->cookie_name) 843 if (!child->cookie_name)
766 child->cookie_name = parent->cookie_name; 844 child->cookie_name = parent->cookie_name;
767 845
768
769 return (void*) child; 846 return (void*) child;
770} 847}
771 848
@@ -850,7 +927,7 @@ static int log_sql_transaction(request_rec *orig)
850 if ((r->uri) && (cls->transfer_accept_list->nelts)) { 927 if ((r->uri) && (cls->transfer_accept_list->nelts)) {
851 proceed = 0; 928 proceed = 0;
852 for (ptrptr = (char **) cls->transfer_accept_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->transfer_accept_list->elt_size)) 929 for (ptrptr = (char **) cls->transfer_accept_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->transfer_accept_list->elt_size))
853 if (ap_strstr(r->uri, *ptrptr)) { 930 if (strstr(r->uri, *ptrptr)) {
854 proceed = 1; 931 proceed = 1;
855 break; 932 break;
856 } 933 }
@@ -863,7 +940,7 @@ static int log_sql_transaction(request_rec *orig)
863 ptrptr2 = (char **) (cls->transfer_ignore_list->elts + (cls->transfer_ignore_list->nelts * cls->transfer_ignore_list->elt_size)); 940 ptrptr2 = (char **) (cls->transfer_ignore_list->elts + (cls->transfer_ignore_list->nelts * cls->transfer_ignore_list->elt_size));
864 if (r->uri) { 941 if (r->uri) {
865 for (ptrptr = (char **) cls->transfer_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->transfer_ignore_list->elt_size)) 942 for (ptrptr = (char **) cls->transfer_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->transfer_ignore_list->elt_size))
866 if (ap_strstr(r->uri, *ptrptr)) { 943 if (strstr(r->uri, *ptrptr)) {
867 return OK; 944 return OK;
868 } 945 }
869 } 946 }
@@ -874,7 +951,7 @@ static int log_sql_transaction(request_rec *orig)
874 thehost = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME, NULL); 951 thehost = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME, NULL);
875 if (thehost) { 952 if (thehost) {
876 for (ptrptr = (char **) cls->remhost_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->remhost_ignore_list->elt_size)) 953 for (ptrptr = (char **) cls->remhost_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->remhost_ignore_list->elt_size))
877 if (ap_strstr(thehost, *ptrptr)) { 954 if (strstr(thehost, *ptrptr)) {
878 return OK; 955 return OK;
879 } 956 }
880 } 957 }
@@ -884,9 +961,9 @@ static int log_sql_transaction(request_rec *orig)
884 * what the user has configured. */ 961 * what the user has configured. */
885 length = strlen(cls->transfer_log_format); 962 length = strlen(cls->transfer_log_format);
886 for (i = 0; i<length; i++) { 963 for (i = 0; i<length; i++) {
887 logsql_item *item = cls->parsed_log_format[i]; 964 log_sql_item *item = cls->parsed_log_format[i];
888 if (item==NULL) { 965 if (item==NULL) {
889 log_error(APLOG_MARK, APLOG_ERR, 0, orig->server, 966 log_error(APLOG_MARK, APLOG_ERR, orig->server,
890 "Log Format '%c' unknown",cls->transfer_log_format[i]); 967 "Log Format '%c' unknown",cls->transfer_log_format[i]);
891 continue; 968 continue;
892 } 969 }
@@ -909,7 +986,7 @@ static int log_sql_transaction(request_rec *orig)
909 item->sql_field_name, NULL); 986 item->sql_field_name, NULL);
910 values = apr_pstrcat(r->pool, values, (i ? "," : ""), 987 values = apr_pstrcat(r->pool, values, (i ? "," : ""),
911 (item->string_contents ? "'" : ""), 988 (item->string_contents ? "'" : ""),
912 global_config.driver->escape(formatted_item, r->pool,&global_config.db), 989 escape_query(formatted_item, r->pool),
913 (item->string_contents ? "'" : ""), NULL); 990 (item->string_contents ? "'" : ""), NULL);
914 } 991 }
915 992
@@ -926,9 +1003,9 @@ static int log_sql_transaction(request_rec *orig)
926 "('", 1003 "('",
927 unique_id, 1004 unique_id,
928 "','", 1005 "','",
929 global_config.driver->escape(*ptrptr, r->pool,&global_config.db), 1006 escape_query(*ptrptr, r->pool),
930 "','", 1007 "','",
931 global_config.driver->escape(theitem, r->pool,&global_config.db), 1008 escape_query(theitem, r->pool),
932 "')", 1009 "')",
933 NULL); 1010 NULL);
934 i++; 1011 i++;
@@ -936,9 +1013,11 @@ static int log_sql_transaction(request_rec *orig)
936 } 1013 }
937 if ( itemsets != "" ) { 1014 if ( itemsets != "" ) {
938 note_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s", 1015 note_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s",
939 /*global_config.insertdelayed?"delayed":*/"", notes_tablename, itemsets); 1016 global_config.insertdelayed?"delayed":"", notes_tablename, itemsets);
940 1017
941 log_error(APLOG_MARK,APLOG_DEBUG,0, orig->server,"mod_log_sql: note string: %s", note_query); 1018 #ifdef DEBUG
1019 log_error(APLOG_MARK,APLOG_DEBUG,orig->server,"mod_log_sql: note string: %s", note_query);
1020 #endif
942 } 1021 }
943 1022
944 /* Work through the list of headers-out defined by LogSQLWhichHeadersOut*/ 1023 /* Work through the list of headers-out defined by LogSQLWhichHeadersOut*/
@@ -954,9 +1033,9 @@ static int log_sql_transaction(request_rec *orig)
954 "('", 1033 "('",
955 unique_id, 1034 unique_id,
956 "','", 1035 "','",
957 global_config.driver->escape(*ptrptr, r->pool,&global_config.db), 1036 escape_query(*ptrptr, r->pool),
958 "','", 1037 "','",
959 global_config.driver->escape(theitem, r->pool,&global_config.db), 1038 escape_query(theitem, r->pool),
960 "')", 1039 "')",
961 NULL); 1040 NULL);
962 i++; 1041 i++;
@@ -964,9 +1043,11 @@ static int log_sql_transaction(request_rec *orig)
964 } 1043 }
965 if ( itemsets != "" ) { 1044 if ( itemsets != "" ) {
966 hout_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s", 1045 hout_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s",
967 /*global_config.insertdelayed?"delayed":*/"", hout_tablename, itemsets); 1046 global_config.insertdelayed?"delayed":"", hout_tablename, itemsets);
968 1047
969 log_error(APLOG_MARK,APLOG_DEBUG,0, orig->server,"mod_log_sql: header_out string: %s", hout_query); 1048 #ifdef DEBUG
1049 log_error(APLOG_MARK,APLOG_DEBUG,orig->server,"mod_log_sql: header_out string: %s", hout_query);
1050 #endif
970 } 1051 }
971 1052
972 1053
@@ -983,9 +1064,9 @@ static int log_sql_transaction(request_rec *orig)
983 "('", 1064 "('",
984 unique_id, 1065 unique_id,
985 "','", 1066 "','",
986 global_config.driver->escape(*ptrptr, r->pool,&global_config.db), 1067 escape_query(*ptrptr, r->pool),
987 "','", 1068 "','",
988 global_config.driver->escape(theitem, r->pool,&global_config.db), 1069 escape_query(theitem, r->pool),
989 "')", 1070 "')",
990 NULL); 1071 NULL);
991 i++; 1072 i++;
@@ -993,9 +1074,11 @@ static int log_sql_transaction(request_rec *orig)
993 } 1074 }
994 if ( itemsets != "" ) { 1075 if ( itemsets != "" ) {
995 hin_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s", 1076 hin_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s",
996 /*global_config.insertdelayed?"delayed":*/"", hin_tablename, itemsets); 1077 global_config.insertdelayed?"delayed":"", hin_tablename, itemsets);
997 1078
998 log_error(APLOG_MARK,APLOG_DEBUG,0, orig->server,"mod_log_sql: header_in string: %s", hin_query); 1079 #ifdef DEBUG
1080 log_error(APLOG_MARK,APLOG_DEBUG,orig->server,"mod_log_sql: header_in string: %s", hin_query);
1081 #endif
999 } 1082 }
1000 1083
1001 1084
@@ -1012,9 +1095,9 @@ static int log_sql_transaction(request_rec *orig)
1012 "('", 1095 "('",
1013 unique_id, 1096 unique_id,
1014 "','", 1097 "','",
1015 global_config.driver->escape(*ptrptr, r->pool,&global_config.db), 1098 escape_query(*ptrptr, r->pool),
1016 "','", 1099 "','",
1017 global_config.driver->escape(theitem, r->pool,&global_config.db), 1100 escape_query(theitem, r->pool),
1018 "')", 1101 "')",
1019 NULL); 1102 NULL);
1020 i++; 1103 i++;
@@ -1023,23 +1106,29 @@ static int log_sql_transaction(request_rec *orig)
1023 } 1106 }
1024 if ( itemsets != "" ) { 1107 if ( itemsets != "" ) {
1025 cookie_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s", 1108 cookie_query = apr_psprintf(r->pool, "insert %s into `%s` (id, item, val) values %s",
1026 /*global_config.insertdelayed?"delayed":*/"", cookie_tablename, itemsets); 1109 global_config.insertdelayed?"delayed":"", cookie_tablename, itemsets);
1027 1110
1028 log_error(APLOG_MARK,APLOG_DEBUG,0, orig->server,"mod_log_sql: cookie string: %s", cookie_query); 1111 #ifdef DEBUG
1112 log_error(APLOG_MARK,APLOG_DEBUG,orig->server,"mod_log_sql: cookie string: %s", cookie_query);
1113 #endif
1029 } 1114 }
1030 1115
1031 1116
1032 /* Set up the actual INSERT statement */ 1117 /* Set up the actual INSERT statement */
1033 access_query = apr_psprintf(r->pool, "insert %s into `%s` (%s) values (%s)", 1118 access_query = apr_psprintf(r->pool, "insert %s into `%s` (%s) values (%s)",
1034 /*global_config.insertdelayed?"delayed":*/"", transfer_tablename, fields, values); 1119 global_config.insertdelayed?"delayed":"", transfer_tablename, fields, values);
1035 1120
1036 log_error(APLOG_MARK,APLOG_DEBUG,0, r->server,"mod_log_sql: access string: %s", access_query); 1121 #ifdef DEBUG
1122 log_error(APLOG_MARK,APLOG_DEBUG,r->server,"mod_log_sql: access string: %s", access_query);
1123 #endif
1037 1124
1038 /* If the person activated force-preserve, go ahead and push all the entries 1125 /* If the person activated force-preserve, go ahead and push all the entries
1039 * into the preserve file, then return. 1126 * into the preserve file, then return.
1040 */ 1127 */
1041 if (global_config.forcepreserve) { 1128 if (global_config.forcepreserve) {
1042 log_error(APLOG_MARK,APLOG_DEBUG,0, orig->server,"mod_log_sql: preservation forced"); 1129 #ifdef DEBUG
1130 log_error(APLOG_MARK,APLOG_DEBUG,orig->server,"mod_log_sql: preservation forced");
1131 #endif
1043 preserve_entry(orig, access_query); 1132 preserve_entry(orig, access_query);
1044 if ( note_query != NULL ) 1133 if ( note_query != NULL )
1045 preserve_entry(orig, note_query); 1134 preserve_entry(orig, note_query);
@@ -1053,12 +1142,12 @@ static int log_sql_transaction(request_rec *orig)
1053 } 1142 }
1054 1143
1055 /* How's our mysql link integrity? */ 1144 /* How's our mysql link integrity? */
1056 if (!global_config.db.connected) { 1145 if (global_config.server_p == NULL) {
1057 1146
1058 /* Make a try to establish the link */ 1147 /* Make a try to establish the link */
1059 log_sql_opendb_link(r->server); 1148 open_logdb_link(r->server);
1060 1149
1061 if (!global_config.db.connected) { 1150 if (global_config.server_p == NULL) {
1062 /* Unable to re-establish a DB link, so assume that it's really 1151 /* Unable to re-establish a DB link, so assume that it's really
1063 * gone and send the entry to the preserve file instead. 1152 * gone and send the entry to the preserve file instead.
1064 * This short-circuits safe_sql_query() during a db outage and therefore 1153 * This short-circuits safe_sql_query() during a db outage and therefore
@@ -1077,7 +1166,7 @@ static int log_sql_transaction(request_rec *orig)
1077 return OK; 1166 return OK;
1078 } else { 1167 } else {
1079 /* Whew, we got the DB link back */ 1168 /* Whew, we got the DB link back */
1080 log_error(APLOG_MARK,APLOG_NOTICE,0, orig->server,"mod_log_sql: child established database connection"); 1169 log_error(APLOG_MARK,APLOG_NOTICE,orig->server,"mod_log_sql: child established database connection");
1081 } 1170 }
1082 } 1171 }
1083 1172
@@ -1086,20 +1175,20 @@ static int log_sql_transaction(request_rec *orig)
1086 /* ---> i.e. we have a good MySQL connection. <--- */ 1175 /* ---> i.e. we have a good MySQL connection. <--- */
1087 1176
1088 /* Make the access-table insert */ 1177 /* Make the access-table insert */
1089 safe_sql_insert(orig,LOGSQL_TABLE_ACCESS,transfer_tablename,access_query); 1178 safe_sql_query(orig, access_query);
1090 1179
1091 /* Log the optional notes, headers, etc. */ 1180 /* Log the optional notes, headers, etc. */
1092 if (note_query) 1181 if (note_query)
1093 safe_sql_insert(orig, LOGSQL_TABLE_NOTES,notes_tablename,note_query); 1182 safe_sql_query(orig, note_query);
1094 1183
1095 if (hout_query) 1184 if (hout_query)
1096 safe_sql_insert(orig, LOGSQL_TABLE_HEADERSOUT,hout_tablename,hout_query); 1185 safe_sql_query(orig, hout_query);
1097 1186
1098 if (hin_query) 1187 if (hin_query)
1099 safe_sql_insert(orig, LOGSQL_TABLE_HEADERSIN,hin_tablename,hin_query); 1188 safe_sql_query(orig, hin_query);
1100 1189
1101 if (cookie_query) 1190 if (cookie_query)
1102 safe_sql_insert(orig, LOGSQL_TABLE_COOKIES,cookie_tablename,cookie_query); 1191 safe_sql_query(orig, cookie_query);
1103 1192
1104 return OK; 1193 return OK;
1105 } 1194 }
@@ -1110,38 +1199,6 @@ static int log_sql_transaction(request_rec *orig)
1110 * Structure: command, function called, NULL, where available, how many arguments, verbose description 1199 * Structure: command, function called, NULL, where available, how many arguments, verbose description
1111 */ 1200 */
1112static const command_rec log_sql_cmds[] = { 1201static const command_rec log_sql_cmds[] = {
1113 AP_INIT_FLAG("LogSQLAnnounce", set_global_flag_slot,
1114 (void *)APR_OFFSETOF(global_config_t, announce), RSRC_CONF,
1115 "Whether to announce that mod_log_sql is loaded in the server header")
1116 ,
1117 /* DB connection parameters */
1118 AP_INIT_TAKE13("LogSQLLoginInfo", set_log_sql_info, NULL, RSRC_CONF,
1119 "The database connection URI in the form &quot;driver://user:password@hostname:port/database&quot;")
1120 ,
1121 AP_INIT_TAKE2("LogSQLDBParam", set_dbparam, NULL, RSRC_CONF,
1122 "First argument is the DB parameter, second is the value to assign")
1123 ,
1124 AP_INIT_FLAG("LogSQLForcePreserve", set_global_flag_slot,
1125 (void *)APR_OFFSETOF(global_config_t, forcepreserve), RSRC_CONF,
1126 "Forces logging to preserve file and bypasses database")
1127 ,
1128 AP_INIT_FLAG("LogSQLDisablePreserve", set_global_flag_slot,
1129 (void *)APR_OFFSETOF(global_config_t, disablepreserve), RSRC_CONF,
1130 "Completely disables use of the preserve file")
1131 ,
1132 AP_INIT_TAKE1("LogSQLPreserveFile", set_server_file_slot,
1133 (void *)APR_OFFSETOF(logsql_state,preserve_file), RSRC_CONF,
1134 "Name of the file to use for data preservation during database downtime")
1135 ,
1136 AP_INIT_FLAG("LogSQLCreateTables", set_global_nmv_flag_slot,
1137 (void *)APR_OFFSETOF(global_config_t, createtables), RSRC_CONF,
1138 "Turn on module's capability to create its SQL tables on the fly")
1139 ,
1140 /* Table names */
1141 AP_INIT_FLAG("LogSQLMassVirtualHosting", set_global_flag_slot,
1142 (void *)APR_OFFSETOF(global_config_t, massvirtual), RSRC_CONF,
1143 "Activates option(s) useful for ISPs performing mass virutal hosting")
1144 ,
1145 AP_INIT_TAKE1("LogSQLTransferLogTable", set_server_nmv_string_slot, 1202 AP_INIT_TAKE1("LogSQLTransferLogTable", set_server_nmv_string_slot,
1146 (void *)APR_OFFSETOF(logsql_state, transfer_table_name), RSRC_CONF, 1203 (void *)APR_OFFSETOF(logsql_state, transfer_table_name), RSRC_CONF,
1147 "The database table that holds the transfer log") 1204 "The database table that holds the transfer log")
@@ -1162,17 +1219,14 @@ static const command_rec log_sql_cmds[] = {
1162 (void *)APR_OFFSETOF(logsql_state, cookie_table_name), RSRC_CONF, 1219 (void *)APR_OFFSETOF(logsql_state, cookie_table_name), RSRC_CONF,
1163 "The database table that holds the cookie info") 1220 "The database table that holds the cookie info")
1164 , 1221 ,
1165 /* Log format */
1166 AP_INIT_TAKE1("LogSQLTransferLogFormat", set_logformat_slot, 1222 AP_INIT_TAKE1("LogSQLTransferLogFormat", set_logformat_slot,
1167 NULL, RSRC_CONF, 1223 NULL, RSRC_CONF,
1168 "Instruct the module what information to log to the database transfer log") 1224 "Instruct the module what information to log to the database transfer log")
1169 , 1225 ,
1170 /* Machine ID */
1171 AP_INIT_TAKE1("LogSQLMachineID", set_global_string_slot, 1226 AP_INIT_TAKE1("LogSQLMachineID", set_global_string_slot,
1172 (void *)APR_OFFSETOF(global_config_t, machid), RSRC_CONF, 1227 (void *)APR_OFFSETOF(global_config_t, machid), RSRC_CONF,
1173 "Machine ID that the module will log, useful in web clusters to differentiate machines") 1228 "Machine ID that the module will log, useful in web clusters to differentiate machines")
1174 , 1229 ,
1175 /* Limits on logging */
1176 AP_INIT_ITERATE("LogSQLRequestAccept", add_server_string_slot, 1230 AP_INIT_ITERATE("LogSQLRequestAccept", add_server_string_slot,
1177 (void *)APR_OFFSETOF(logsql_state, transfer_accept_list), RSRC_CONF, 1231 (void *)APR_OFFSETOF(logsql_state, transfer_accept_list), RSRC_CONF,
1178 "List of URIs to accept for logging. Accesses that don't match will not be logged") 1232 "List of URIs to accept for logging. Accesses that don't match will not be logged")
@@ -1185,11 +1239,48 @@ static const command_rec log_sql_cmds[] = {
1185 (void *)APR_OFFSETOF(logsql_state, remhost_ignore_list), RSRC_CONF, 1239 (void *)APR_OFFSETOF(logsql_state, remhost_ignore_list), RSRC_CONF,
1186 "List of remote hosts to ignore. Accesses that match will not be logged to database") 1240 "List of remote hosts to ignore. Accesses that match will not be logged to database")
1187 , 1241 ,
1188 /* Special loggin table configuration */ 1242 AP_INIT_TAKE1("LogSQLDatabase", set_global_string_slot,
1243 (void *)APR_OFFSETOF(global_config_t, dbname), RSRC_CONF,
1244 "The name of the database database for logging")
1245 ,
1189 AP_INIT_TAKE1("LogSQLWhichCookie", set_server_string_slot, 1246 AP_INIT_TAKE1("LogSQLWhichCookie", set_server_string_slot,
1190 (void *)APR_OFFSETOF(logsql_state, cookie_name), RSRC_CONF, 1247 (void *)APR_OFFSETOF(logsql_state, cookie_name), RSRC_CONF,
1191 "The single cookie that you want logged in the access_log when using the 'c' config directive") 1248 "The single cookie that you want logged in the access_log when using the 'c' config directive")
1192 , 1249 ,
1250 AP_INIT_TAKE3("LogSQLLoginInfo", set_log_sql_info, NULL, RSRC_CONF,
1251 "The database host, user-id and password for logging")
1252 ,
1253 AP_INIT_FLAG("LogSQLCreateTables", set_global_nmv_flag_slot,
1254 (void *)APR_OFFSETOF(global_config_t, createtables), RSRC_CONF,
1255 "Turn on module's capability to create its SQL tables on the fly")
1256 ,
1257 AP_INIT_FLAG("LogSQLMassVirtualHosting", set_global_flag_slot,
1258 (void *)APR_OFFSETOF(global_config_t, massvirtual), RSRC_CONF,
1259 "Activates option(s) useful for ISPs performing mass virutal hosting")
1260 ,
1261 AP_INIT_FLAG("LogSQLDelayedInserts", set_global_flag_slot,
1262 (void *)APR_OFFSETOF(global_config_t, insertdelayed), RSRC_CONF,
1263 "Whether to use delayed inserts")
1264 ,
1265 AP_INIT_FLAG("LogSQLForcePreserve", set_global_flag_slot,
1266 (void *)APR_OFFSETOF(global_config_t, forcepreserve), RSRC_CONF,
1267 "Forces logging to preserve file and bypasses database")
1268 ,
1269 AP_INIT_TAKE1("LogSQLPreserveFile", set_global_string_slot,
1270 (void *)APR_OFFSETOF(logsql_state,preserve_file), RSRC_CONF,
1271 "Name of the file to use for data preservation during database downtime")
1272 ,
1273 AP_INIT_TAKE1("LogSQLSocketFile", set_global_string_slot,
1274 (void *)APR_OFFSETOF(global_config_t, socketfile), RSRC_CONF,
1275 "Name of the file to employ for socket connections to database")
1276 ,
1277 AP_INIT_TAKE1("LogSQLTableType", set_global_string_slot,
1278 (void *)APR_OFFSETOF(global_config_t, tabletype), RSRC_CONF,
1279 "What kind of table to create (MyISAM, InnoDB,...) when creating tables")
1280 ,
1281 AP_INIT_TAKE1("LogSQLTCPPort", set_log_sql_tcp_port, NULL, RSRC_CONF,
1282 "Port number to use for TCP connections to database, defaults to 3306 if not set")
1283 ,
1193 AP_INIT_ITERATE("LogSQLWhichNotes", add_server_string_slot, 1284 AP_INIT_ITERATE("LogSQLWhichNotes", add_server_string_slot,
1194 (void *)APR_OFFSETOF(logsql_state, notes_list), RSRC_CONF, 1285 (void *)APR_OFFSETOF(logsql_state, notes_list), RSRC_CONF,
1195 "Notes that you would like to log in a separate table") 1286 "Notes that you would like to log in a separate table")
@@ -1206,26 +1297,6 @@ static const command_rec log_sql_cmds[] = {
1206 (void *)APR_OFFSETOF(logsql_state, cookie_list), RSRC_CONF, 1297 (void *)APR_OFFSETOF(logsql_state, cookie_list), RSRC_CONF,
1207 "The cookie(s) that you would like to log in a separate table") 1298 "The cookie(s) that you would like to log in a separate table")
1208 , 1299 ,
1209 AP_INIT_RAW_ARGS("LogSQLDeprecated", ap_set_deprecated, NULL, RSRC_CONF,
1210 "<br><b>Deprecated</b><br>The following Commands are deprecated and should not be used.. <br>Read the documentation for more information<br><b>Deprecated</b>")
1211 ,
1212 /* Deprecated commands */
1213 AP_INIT_TAKE1("LogSQLDatabase", set_dbparam_slot,
1214 (void *)"database", RSRC_CONF,
1215 "<b>(Deprecated) Use LogSQLDBParam database dbname.</b> The name of the database database for logging")
1216 ,
1217 AP_INIT_TAKE1("LogSQLTableType", set_dbparam_slot,
1218 (void *)"tabletype", RSRC_CONF,
1219 "<b>(Deprecated) Use LogSQLDBParam tabletype type.</b> What kind of table to create (MyISAM, InnoDB,...) when creating tables")
1220 ,
1221 AP_INIT_TAKE1("LogSQLSocketFile", set_dbparam_slot,
1222 (void *)"socketfile", RSRC_CONF,
1223 "<b>(Deprecated) Use LogSQLDBParam socketfile socket.</b> Name of the file to employ for socket connections to database")
1224 ,
1225 AP_INIT_TAKE1("LogSQLTCPPort", set_dbparam_slot,
1226 (void *)"port", RSRC_CONF,
1227 "<b>(Deprecated) Use LogSQLDBParam port port.</b> Port number to use for TCP connections to database, defaults to 3306 if not set")
1228 ,
1229 {NULL} 1300 {NULL}
1230}; 1301};
1231/* The configuration array that sets up the hooks into the module. */ 1302/* The configuration array that sets up the hooks into the module. */
@@ -1233,6 +1304,7 @@ static const command_rec log_sql_cmds[] = {
1233static void register_hooks(apr_pool_t *p) { 1304static void register_hooks(apr_pool_t *p) {
1234 ap_hook_post_config(log_sql_post_config, NULL, NULL, APR_HOOK_REALLY_FIRST); 1305 ap_hook_post_config(log_sql_post_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
1235 ap_hook_child_init(log_sql_child_init, NULL, NULL, APR_HOOK_MIDDLE); 1306 ap_hook_child_init(log_sql_child_init, NULL, NULL, APR_HOOK_MIDDLE);
1307 ap_hook_open_logs(log_sql_open, NULL, NULL, APR_HOOK_MIDDLE);
1236 ap_hook_log_transaction(log_sql_transaction, NULL, NULL, APR_HOOK_MIDDLE); 1308 ap_hook_log_transaction(log_sql_transaction, NULL, NULL, APR_HOOK_MIDDLE);
1237} 1309}
1238 1310
@@ -1246,7 +1318,7 @@ module AP_MODULE_DECLARE_DATA log_sql_module = {
1246 register_hooks /* register hooks */ 1318 register_hooks /* register hooks */
1247}; 1319};
1248#elif defined(WITH_APACHE13) 1320#elif defined(WITH_APACHE13)
1249module MODULE_VAR_EXPORT log_sql_module = { 1321module log_sql_module = {
1250 STANDARD_MODULE_STUFF, 1322 STANDARD_MODULE_STUFF,
1251 log_sql_module_init, /* module initializer */ 1323 log_sql_module_init, /* module initializer */
1252 NULL, /* create per-dir config */ 1324 NULL, /* create per-dir config */
diff --git a/mod_log_sql.h b/mod_log_sql.h
index 56aa2c3..f54ab54 100644
--- a/mod_log_sql.h
+++ b/mod_log_sql.h
@@ -1,5 +1,4 @@
1/* $Id$ */ 1/* $Header: /home/cvs/mod_log_sql/mod_log_sql.h,v 1.3 2004/01/22 05:26:56 urkle Exp $ */
2
3#ifndef MOD_LOG_SQL_H 2#ifndef MOD_LOG_SQL_H
4#define MOD_LOG_SQL_H 3#define MOD_LOG_SQL_H
5 4
@@ -24,104 +23,10 @@
24#define LOGSQL_DECLARE_DATA __declspec(dllimport) 23#define LOGSQL_DECLARE_DATA __declspec(dllimport)
25#endif 24#endif
26 25
27/* Registration function for extract functions */ 26typedef const char *log_sql_item_func(request_rec *r, char *a);
28
29typedef const char *logsql_item_func(request_rec *r, char *a);
30 27
28/* Registration Function for extract functions */
31LOGSQL_DECLARE(void) log_sql_register_item(server_rec *s, apr_pool_t *p, 29LOGSQL_DECLARE(void) log_sql_register_item(server_rec *s, apr_pool_t *p,
32 char key, logsql_item_func *func, const char *sql_field_name, 30 char key, log_sql_item_func *func, const char *sql_field_name,
33 int want_orig_default, int string_contents); 31 int want_orig_default, int string_contents);
34
35/* DB Connection structure holds connection handle */
36typedef struct {
37 int connected; /* Are we connected to the DB */
38 void *handle; /* DB specific connection pointer */
39 apr_table_t *parms; /* DB connection parameters */
40} logsql_dbconnection;
41
42/* open db handle return values*/
43typedef enum {
44 LOGSQL_OPENDB_FAIL = 0,
45 LOGSQL_OPENDB_SUCCESS,
46 LOGSQL_OPENDB_ALREADY,
47 LOGSQL_OPENDB_PRESERVE
48} logsql_opendb_ret;
49
50typedef enum {
51 LOGSQL_QUERY_SUCCESS = 0,
52 LOGSQL_QUERY_FAIL,
53 LOGSQL_QUERY_NOLINK,
54 LOGSQL_QUERY_NOTABLE,
55 LOGSQL_QUERY_PRESERVED
56} logsql_query_ret;
57
58typedef enum {
59 LOGSQL_TABLE_SUCCESS = 0,
60 LOGSQL_TABLE_FAIL
61} logsql_table_ret;
62
63/* Table type to create/log to */
64typedef enum {
65 LOGSQL_TABLE_ACCESS = 0,
66 LOGSQL_TABLE_NOTES,
67 LOGSQL_TABLE_HEADERSOUT,
68 LOGSQL_TABLE_HEADERSIN,
69 LOGSQL_TABLE_COOKIES
70} logsql_tabletype;
71
72/* All Tables */
73#define LOGSQL_TABLE_ALL LOGSQL_TABLE_ACCESS | LOGSQL_TABLE_NOTES | \
74 LOGSQL_TABLE_HEADERSIN | LOGSQL_TABLE_HEADERSOUT | LOGSQL_TABLE_COOKIES
75
76/* MySQL module calls */
77
78/* Registration function for database drivers */
79
80typedef struct {
81 /* NULL terminated list of drivers strings */
82 char **provided_drivers;
83 /* create a connection to the underlying database layer */
84 logsql_opendb_ret (*connect)(server_rec *s, logsql_dbconnection *db);
85 /* disconnect from the underlying database layer */
86 void (*disconnect)(logsql_dbconnection *db);
87 /* escape the SQL statement according to database rules */
88 const char *(*escape)(const char *from_str, apr_pool_t *p,
89 logsql_dbconnection *db);
90 /* insert a SQL query statement */
91 logsql_query_ret (*insert)(request_rec *r,logsql_dbconnection *db,
92 const char *query);
93 /* create a SQL table named table_name of table_type */
94 logsql_table_ret (*create_table)(request_rec *r, logsql_dbconnection *db,
95 logsql_tabletype table_type, const char *table_name);
96} logsql_dbdriver;
97
98LOGSQL_DECLARE(void) log_sql_register_driver(apr_pool_t *p,
99 logsql_dbdriver *driver);
100
101/* Module initialization Macros */
102#if defined(WITH_APACHE20)
103# define LOGSQL_REGISTER(driver) \
104 static int post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s); \
105 static void register_hooks(apr_pool_t *p) { \
106 ap_hook_post_config(post_config, NULL, NULL, APR_HOOK_REALLY_FIRST); \
107 } \
108 \
109 module AP_MODULE_DECLARE_DATA log_sql_##driver##_module = { \
110 STANDARD20_MODULE_STUFF, \
111 NULL, NULL, NULL, NULL, NULL, register_hooks }; \
112 static int post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
113#elif defined(WITH_APACHE13)
114# define LOGSQL_REGISTER(driver) \
115 static void module_init(server_rec *s, apr_pool_t *p); \
116 module MODULE_VAR_EXPORT log_sql_##driver##_module = { \
117 STANDARD_MODULE_STUFF, module_init }; \
118 static void module_init(server_rec *s, apr_pool_t *p)
119#endif
120
121#if defined(WITH_APACHE20)
122#define LOGSQL_REGISTER_RETURN return OK;
123#elif defined(WITH_APACHE13)
124#define LOGSQL_REGISTER_RETURN
125#endif
126
127#endif /* MOD_LOG_SQL_H */ 32#endif /* MOD_LOG_SQL_H */
diff --git a/mod_log_sql.prj b/mod_log_sql.prj
index bb04bb2..ad294d5 100644
--- a/mod_log_sql.prj
+++ b/mod_log_sql.prj
@@ -66,11 +66,9 @@ module.source.type=
66module.source.expanded=1 66module.source.expanded=1
67module.source.files=\ 67module.source.files=\
68 mod_log_sql.c\ 68 mod_log_sql.c\
69 make_combined_log.pl\
69 contrib/mysql_import_combined_log.pl\ 70 contrib/mysql_import_combined_log.pl\
70 mod_log_sql_ssl.c\ 71 mod_log_sql_ssl.c
71 mod_log_sql_mysql.c\
72 contrib/make_combined_log.pl\
73 mod_log_sql_pgsql.c
74 72
75module.pixmap.name=. 73module.pixmap.name=.
76module.pixmap.type= 74module.pixmap.type=
@@ -98,12 +96,10 @@ module.doc.expanded=1
98module.doc.files=\ 96module.doc.files=\
99 Documentation/README\ 97 Documentation/README\
100 INSTALL\ 98 INSTALL\
99 Documentation/documentation.lyx\
101 CHANGELOG\ 100 CHANGELOG\
102 LICENSE\ 101 LICENSE\
103 AUTHORS\ 102 AUTHORS
104 TODO\
105 Documentation/manual.xml\
106 TODO.in
107 103
108module.po.expanded=0 104module.po.expanded=0
109module.po.files= 105module.po.files=
@@ -111,7 +107,8 @@ module.po.files=
111compiler.options.supports= 107compiler.options.supports=
112compiler.options.include.paths=\ 108compiler.options.include.paths=\
113 .\ 109 .\
114 /usr/include/apache 110 ..\
111 /opt/apache2/include
115compiler.options.library.paths= 112compiler.options.library.paths=
116compiler.options.libraries= 113compiler.options.libraries=
117compiler.options.libraries.selected= 114compiler.options.libraries.selected=
diff --git a/mod_log_sql_mysql.c b/mod_log_sql_mysql.c
deleted file mode 100644
index e64044e..0000000
--- a/mod_log_sql_mysql.c
+++ /dev/null
@@ -1,259 +0,0 @@
1/* $Id$ */
2
3#if defined(WITH_APACHE20)
4# include "apache20.h"
5#elif defined(WITH_APACHE13)
6# include "apache13.h"
7#else
8# error Unsupported Apache version
9#endif
10
11#ifdef HAVE_CONFIG_H
12/* Undefine these to prevent conflicts between Apache ap_config_auto.h and
13 * my config.h. Only really needed for Apache < 2.0.48, but it can't hurt.
14 */
15#undef PACKAGE_BUGREPORT
16#undef PACKAGE_NAME
17#undef PACKAGE_STRING
18#undef PACKAGE_TARNAME
19#undef PACKAGE_VERSION
20
21#include "config.h"
22#endif
23
24#include "mod_log_sql.h"
25
26#include "mysql.h"
27#include "mysqld_error.h"
28
29/* The enduser won't modify these */
30#define MYSQL_ERROR(mysql) ((mysql)?(mysql_error(mysql)):"MySQL server has gone away")
31
32/* Connect to the MYSQL database */
33static logsql_opendb_ret log_sql_mysql_connect(server_rec *s, logsql_dbconnection *db)
34{
35 const char *host = apr_table_get(db->parms,"hostname");
36 const char *user = apr_table_get(db->parms,"username");
37 const char *passwd = apr_table_get(db->parms,"password");
38 const char *database = apr_table_get(db->parms,"database");
39 const char *s_tcpport = apr_table_get(db->parms,"port");
40 unsigned int tcpport = (s_tcpport)?atoi(s_tcpport):3306;
41 const char *socketfile = apr_table_get(db->parms,"socketfile");
42 MYSQL *dblink = db->handle;
43
44 dblink = mysql_init(dblink);
45 db->handle = (void *)dblink;
46
47
48 if (!socketfile) {
49 socketfile = "/var/lib/mysql/mysql.sock";
50 }
51
52 if (mysql_real_connect(dblink, host, user, passwd, database, tcpport,
53 socketfile, 0)) {
54 log_error(APLOG_MARK,APLOG_DEBUG,0, s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'",
55 host, tcpport, database, user, socketfile);
56 return LOGSQL_OPENDB_SUCCESS;
57 } else {
58 log_error(APLOG_MARK,APLOG_DEBUG,0, s,"mod_log_sql: database connection error: %s",
59 MYSQL_ERROR(dblink));
60 log_error(APLOG_MARK,APLOG_DEBUG, 0, s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'",
61 host, tcpport, database, user, socketfile);
62 return LOGSQL_OPENDB_FAIL;
63 }
64}
65
66/* Close the DB link */
67static void log_sql_mysql_close(logsql_dbconnection *db)
68{
69 mysql_close((MYSQL *)db->handle);
70}
71
72/* Routine to escape the 'dangerous' characters that would otherwise
73 * corrupt the INSERT string: ', \, and "
74 */
75static const char *log_sql_mysql_escape(const char *from_str, apr_pool_t *p,
76 logsql_dbconnection *db)
77{
78 if (!from_str)
79 return NULL;
80 else {
81 char *to_str;
82 unsigned long length = strlen(from_str);
83 unsigned long retval;
84
85 /* Pre-allocate a new string that could hold twice the original, which would only
86 * happen if the whole original string was 'dangerous' characters.
87 */
88 to_str = (char *) apr_palloc(p, length * 2 + 1);
89 if (!to_str) {
90 return from_str;
91 }
92
93 if (!db->connected) {
94 /* Well, I would have liked to use the current database charset. mysql is
95 * unavailable, however, so I fall back to the slightly less respectful
96 * mysql_escape_string() function that uses the default charset.
97 */
98 retval = mysql_escape_string(to_str, from_str, length);
99 } else {
100 /* MySQL is available, so I'll go ahead and respect the current charset when
101 * I perform the escape.
102 */
103 retval = mysql_real_escape_string((MYSQL *)db->handle, to_str, from_str, length);
104 }
105
106 if (retval)
107 return to_str;
108 else
109 return from_str;
110 }
111}
112#if defined(WIN32)
113#define SIGNAL_GRAB
114#define SIGNAL_RELEASE
115#define SIGNAL_VAR
116#else
117#define SIGNAL_VAR void (*handler) (int);
118#define SIGNAL_GRAB handler = signal(SIGPIPE, SIG_IGN);
119#define SIGNAL_RELEASE signal(SIGPIPE, handler);
120#endif
121/* Run a mysql insert query and return a categorized error or success */
122static logsql_query_ret log_sql_mysql_query(request_rec *r,logsql_dbconnection *db,
123 const char *query)
124{
125 int retval;
126 SIGNAL_VAR
127
128 unsigned int real_error = 0;
129 /*const char *real_error_str = NULL;*/
130
131 MYSQL *dblink = (MYSQL *)db->handle;
132
133 if (!dblink) {
134 return LOGSQL_QUERY_NOLINK;
135 }
136
137 /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */
138 SIGNAL_GRAB
139
140 /* Run the query */
141 if (!(retval = mysql_query(dblink, query))) {
142 SIGNAL_RELEASE
143 return LOGSQL_QUERY_SUCCESS;
144 }
145 /* Check to see if the error is "nonexistent table" */
146 real_error = mysql_errno(dblink);
147
148 if (real_error == ER_NO_SUCH_TABLE) {
149 log_error(APLOG_MARK,APLOG_ERR,0, r->server,"table does not exist, preserving query");
150 /* Restore SIGPIPE to its original handler function */
151 SIGNAL_RELEASE
152 return LOGSQL_QUERY_NOTABLE;
153 }
154
155 /* Restore SIGPIPE to its original handler function */
156 SIGNAL_RELEASE
157 return LOGSQL_QUERY_FAIL;
158}
159
160/* Create table table_name of type table_type. */
161static logsql_table_ret log_sql_mysql_create(request_rec *r, logsql_dbconnection *db,
162 logsql_tabletype table_type, const char *table_name)
163{
164 int retval;
165 const char *tabletype = apr_table_get(db->parms,"tabletype");
166 SIGNAL_VAR
167 char *type_suffix = NULL;
168
169 char *create_prefix = "create table if not exists `";
170 char *create_suffix = NULL;
171 char *create_sql;
172
173 MYSQL *dblink = (MYSQL *)db->handle;
174
175/* if (!global_config.createtables) {
176 return APR_SUCCESS;
177 }*/
178
179 switch (table_type) {
180 case LOGSQL_TABLE_ACCESS:
181 create_suffix =
182 "` (id char(19),\
183 agent varchar(255),\
184 bytes_sent int unsigned,\
185 child_pid smallint unsigned,\
186 cookie varchar(255),\
187 machine_id varchar(25),\
188 request_file varchar(255),\
189 referer varchar(255),\
190 remote_host varchar(50),\
191 remote_logname varchar(50),\
192 remote_user varchar(50),\
193 request_duration smallint unsigned,\
194 request_line varchar(255),\
195 request_method varchar(10),\
196 request_protocol varchar(10),\
197 request_time char(28),\
198 request_uri varchar(255),\
199 request_args varchar(255),\
200 server_port smallint unsigned,\
201 ssl_cipher varchar(25),\
202 ssl_keysize smallint unsigned,\
203 ssl_maxkeysize smallint unsigned,\
204 status smallint unsigned,\
205 time_stamp int unsigned,\
206 virtual_host varchar(255))";
207 break;
208 case LOGSQL_TABLE_COOKIES:
209 case LOGSQL_TABLE_HEADERSIN:
210 case LOGSQL_TABLE_HEADERSOUT:
211 case LOGSQL_TABLE_NOTES:
212 create_suffix =
213 "` (id char(19),\
214 item varchar(80),\
215 val varchar(80))";
216 break;
217 }
218
219 if (tabletype) {
220 type_suffix = apr_pstrcat(r->pool, " TYPE=",
221 tabletype, NULL);
222 }
223 /* Find memory long enough to hold the whole CREATE string + \0 */
224 create_sql = apr_pstrcat(r->pool, create_prefix, table_name, create_suffix,
225 type_suffix, NULL);
226
227 log_error(APLOG_MARK,APLOG_DEBUG,0, r->server,"create string: %s", create_sql);
228
229 if (!dblink) {
230 return LOGSQL_QUERY_NOLINK;
231 }
232 /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */
233 SIGNAL_GRAB
234
235 /* Run the create query */
236 if ((retval = mysql_query(dblink, create_sql))) {
237 log_error(APLOG_MARK,APLOG_ERR,0, r->server,"failed to create table: %s",
238 table_name);
239 SIGNAL_RELEASE
240 return LOGSQL_TABLE_FAIL;
241 }
242 SIGNAL_RELEASE
243 return LOGSQL_TABLE_SUCCESS;
244}
245
246static char *supported_drivers[] = {"mysql",NULL};
247static logsql_dbdriver mysql_driver = {
248 supported_drivers,
249 log_sql_mysql_connect, /* open DB connection */
250 log_sql_mysql_close, /* close DB connection */
251 log_sql_mysql_escape, /* escape query */
252 log_sql_mysql_query, /* insert query */
253 log_sql_mysql_create /* create table */
254};
255
256LOGSQL_REGISTER(mysql) {
257 log_sql_register_driver(p,&mysql_driver);
258 LOGSQL_REGISTER_RETURN;
259}
diff --git a/mod_log_sql_pgsql.c b/mod_log_sql_pgsql.c
deleted file mode 100644
index 7ac4053..0000000
--- a/mod_log_sql_pgsql.c
+++ /dev/null
@@ -1,251 +0,0 @@
1/* $Id$ */
2
3#if defined(WITH_APACHE20)
4# include "apache20.h"
5#elif defined(WITH_APACHE13)
6# include "apache13.h"
7#else
8# error Unsupported Apache version
9#endif
10
11
12#ifdef HAVE_CONFIG_H
13/* Undefine these to prevent conflicts between Apache ap_config_auto.h and
14 * my config.h. Only really needed for Apache < 2.0.48, but it can't hurt.
15 */
16#undef PACKAGE_BUGREPORT
17#undef PACKAGE_NAME
18#undef PACKAGE_STRING
19#undef PACKAGE_TARNAME
20#undef PACKAGE_VERSION
21
22#include "config.h"
23#endif
24
25#include "mod_log_sql.h"
26
27#include "libpq-fe.h"
28
29typedef struct {
30 PGconn *PG;
31 char *connectioninfo;
32} pg_conn_rec;
33
34/* Connect to the MYSQL database */
35static logsql_opendb_ret log_sql_pgsql_connect(server_rec *s, logsql_dbconnection *db)
36{
37 const char *host = apr_table_get(db->parms,"hostname");
38 const char *user = apr_table_get(db->parms,"username");
39 const char *passwd = apr_table_get(db->parms,"password");
40 const char *database = apr_table_get(db->parms,"database");
41 const char *s_tcpport = apr_table_get(db->parms,"port");
42 unsigned int tcpport = (s_tcpport)?atoi(s_tcpport):3306;
43 const char *socketfile = apr_table_get(db->parms,"socketfile");
44 pg_conn_rec *dblink = db->handle;
45
46 dblink = mysql_init(dblink);
47 db->handle = (void *)dblink;
48
49
50 if (!socketfile) {
51 socketfile = "/var/lib/mysql/mysql.sock";
52 }
53
54 if (PQconnectdb(dblink, host, user, passwd, database, tcpport,
55 socketfile, 0)) {
56 log_error(APLOG_MARK,APLOG_DEBUG,0, s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'",
57 host, tcpport, database, user, socketfile);
58 return LOGSQL_OPENDB_SUCCESS;
59 } else {
60 log_error(APLOG_MARK,APLOG_DEBUG,0, s,"mod_log_sql: database connection error: %s",
61 MYSQL_ERROR(dblink));
62 log_error(APLOG_MARK,APLOG_DEBUG, 0, s,"HOST: '%s' PORT: '%d' DB: '%s' USER: '%s' SOCKET: '%s'",
63 host, tcpport, database, user, socketfile);
64 return LOGSQL_OPENDB_FAIL;
65 }
66}
67
68/* Close the DB link */
69static void log_sql_pgsql_close(logsql_dbconnection *db)
70{
71 PQfinish(((pg_conn_rec *)db->handle)->PG);
72}
73
74/* Routine to escape the 'dangerous' characters that would otherwise
75 * corrupt the INSERT string: ', \, and "
76 */
77static const char *log_sql_pgsql_escape(const char *from_str, apr_pool_t *p,
78 logsql_dbconnection *db)
79{
80 if (!from_str)
81 return NULL;
82 else {
83 char *to_str;
84 unsigned long length = strlen(from_str);
85 unsigned long retval;
86
87 /* Pre-allocate a new string that could hold twice the original, which would only
88 * happen if the whole original string was 'dangerous' characters.
89 */
90 to_str = (char *) apr_palloc(p, length * 2 + 1);
91 if (!to_str) {
92 return from_str;
93 }
94
95 if (!db->connected) {
96 /* Well, I would have liked to use the current database charset. mysql is
97 * unavailable, however, so I fall back to the slightly less respectful
98 * mysql_escape_string() function that uses the default charset.
99 */
100 retval = mysql_escape_string(to_str, from_str, length);
101 } else {
102 /* MySQL is available, so I'll go ahead and respect the current charset when
103 * I perform the escape.
104 */
105 retval = mysql_real_escape_string((MYSQL *)db->handle, to_str, from_str, length);
106 }
107
108 if (retval)
109 return to_str;
110 else
111 return from_str;
112 }
113}
114
115/* Run a mysql insert query and return a categorized error or success */
116static logsql_query_ret log_sql_pgsql_query(request_rec *r,logsql_dbconnection *db,
117 const char *query)
118{
119 int retval;
120 void (*handler) (int);
121 unsigned int real_error = 0;
122 /*const char *real_error_str = NULL;*/
123
124 pg_conn_rec *dblink = db->handle;
125
126 if (!dblink) {
127 return LOGSQL_QUERY_NOLINK;
128 }
129 /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */
130 handler = signal(SIGPIPE, SIG_IGN);
131
132 /* Run the query */
133 if (!(retval = mysql_query(dblink, query))) {
134 signal(SIGPIPE, handler);
135 return LOGSQL_QUERY_SUCCESS;
136 }
137 /* Check to see if the error is "nonexistent table" */
138 real_error = mysql_errno(dblink);
139
140 if (real_error == ER_NO_SUCH_TABLE) {
141 log_error(APLOG_MARK,APLOG_ERR,0, r->server,"table does not exist, preserving query");
142 /* Restore SIGPIPE to its original handler function */
143 signal(SIGPIPE, handler);
144 return LOGSQL_QUERY_NOTABLE;
145 }
146
147 /* Restore SIGPIPE to its original handler function */
148 signal(SIGPIPE, handler);
149 return LOGSQL_QUERY_FAIL;
150}
151
152/* Create table table_name of type table_type. */
153static logsql_table_ret log_sql_pgsql_create(request_rec *r, logsql_dbconnection *db,
154 logsql_tabletype table_type, const char *table_name)
155{
156 int retval;
157 const char *tabletype = apr_table_get(db->parms,"tabletype");
158 void (*handler) (int);
159 char *type_suffix = NULL;
160
161 char *create_prefix = "create table if not exists `";
162 char *create_suffix = NULL;
163 char *create_sql;
164
165 pg_conn_rec *dblink = db->handle;
166
167/* if (!global_config.createtables) {
168 return APR_SUCCESS;
169 }*/
170
171 switch (table_type) {
172 case LOGSQL_TABLE_ACCESS:
173 create_suffix =
174 "` (id char(19),\
175 agent varchar(255),\
176 bytes_sent int unsigned,\
177 child_pid smallint unsigned,\
178 cookie varchar(255),\
179 machine_id varchar(25),\
180 request_file varchar(255),\
181 referer varchar(255),\
182 remote_host varchar(50),\
183 remote_logname varchar(50),\
184 remote_user varchar(50),\
185 request_duration smallint unsigned,\
186 request_line varchar(255),\
187 request_method varchar(10),\
188 request_protocol varchar(10),\
189 request_time char(28),\
190 request_uri varchar(255),\
191 request_args varchar(255),\
192 server_port smallint unsigned,\
193 ssl_cipher varchar(25),\
194 ssl_keysize smallint unsigned,\
195 ssl_maxkeysize smallint unsigned,\
196 status smallint unsigned,\
197 time_stamp int unsigned,\
198 virtual_host varchar(255))";
199 break;
200 case LOGSQL_TABLE_COOKIES:
201 case LOGSQL_TABLE_HEADERSIN:
202 case LOGSQL_TABLE_HEADERSOUT:
203 case LOGSQL_TABLE_NOTES:
204 create_suffix =
205 "` (id char(19),\
206 item varchar(80),\
207 val varchar(80))";
208 break;
209 }
210
211 if (tabletype) {
212 type_suffix = apr_pstrcat(r->pool, " TYPE=",
213 tabletype, NULL);
214 }
215 /* Find memory long enough to hold the whole CREATE string + \0 */
216 create_sql = apr_pstrcat(r->pool, create_prefix, table_name, create_suffix,
217 type_suffix, NULL);
218
219 log_error(APLOG_MARK,APLOG_DEBUG,0, r->server,"create string: %s", create_sql);
220
221 if (!dblink) {
222 return LOGSQL_QUERY_NOLINK;
223 }
224 /* A failed mysql_query() may send a SIGPIPE, so we ignore that signal momentarily. */
225 handler = signal(SIGPIPE, SIG_IGN);
226
227 /* Run the create query */
228 if ((retval = mysql_query(dblink, create_sql))) {
229 log_error(APLOG_MARK,APLOG_ERR,0, r->server,"failed to create table: %s",
230 table_name);
231 signal(SIGPIPE, handler);
232 return LOGSQL_TABLE_FAIL;
233 }
234 signal(SIGPIPE, handler);
235 return LOGSQL_TABLE_SUCCESS;
236}
237
238static char *supported_drivers[] = {"pgsql",NULL};
239static logsql_dbdriver pgsql_driver = {
240 supported_drivers,
241 log_sql_pgsql_connect, /* open DB connection */
242 log_sql_pgsql_close, /* close DB connection */
243 log_sql_pgsql_escape, /* escape query */
244 log_sql_pgsql_query, /* insert query */
245 log_sql_pgsql_create /* create table */
246};
247
248LOGSQL_REGISTER(pgsql) {
249 log_sql_register_driver(p,&pgsql_driver);
250 LOGSQL_REGISTER_RETURN;
251}
diff --git a/mod_log_sql_ssl.c b/mod_log_sql_ssl.c
index 8b792db..c874a2b 100644
--- a/mod_log_sql_ssl.c
+++ b/mod_log_sql_ssl.c
@@ -1,4 +1,5 @@
1/* $Id$ */ 1/* $Header: /home/cvs/mod_log_sql/mod_log_sql_ssl.c,v 1.4 2004/01/22 05:26:56 urkle Exp $ */
2/* mod_log_sql_ssl */
2 3
3#if defined(WITH_APACHE20) 4#if defined(WITH_APACHE20)
4# include "apache20.h" 5# include "apache20.h"
@@ -22,7 +23,6 @@
22#endif 23#endif
23 24
24#include "mod_log_sql.h" 25#include "mod_log_sql.h"
25
26#include "mod_ssl.h" 26#include "mod_ssl.h"
27 27
28#if defined(WITH_APACHE20) 28#if defined(WITH_APACHE20)
@@ -37,7 +37,9 @@ static const char *extract_ssl_keysize(request_rec *r, char *a)
37 if (TEST_SSL(r) != NULL) 37 if (TEST_SSL(r) != NULL)
38 { 38 {
39 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER_USEKEYSIZE"); 39 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER_USEKEYSIZE");
40 log_error(APLOG_MARK,APLOG_DEBUG,0, r->server,"SSL_KEYSIZE: %s", result); 40 #ifdef DEBUG
41 log_error(APLOG_MARK,APLOG_DEBUG,0,r->server,"SSL_KEYSIZE: %s", result);
42 #endif
41 if (result != NULL && result[0] == '\0') 43 if (result != NULL && result[0] == '\0')
42 result = NULL; 44 result = NULL;
43 return result; 45 return result;
@@ -52,7 +54,9 @@ static const char *extract_ssl_maxkeysize(request_rec *r, char *a)
52 if (TEST_SSL(r) != NULL) 54 if (TEST_SSL(r) != NULL)
53 { 55 {
54 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER_ALGKEYSIZE"); 56 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER_ALGKEYSIZE");
55 log_error(APLOG_MARK,APLOG_DEBUG,0, r->server,"SSL_ALGKEYSIZE: %s", result); 57 #ifdef DEBUG
58 log_error(APLOG_MARK,APLOG_DEBUG,0,r->server,"SSL_ALGKEYSIZE: %s", result);
59 #endif
56 if (result != NULL && result[0] == '\0') 60 if (result != NULL && result[0] == '\0')
57 result = NULL; 61 result = NULL;
58 return result; 62 return result;
@@ -67,7 +71,9 @@ static const char *extract_ssl_cipher(request_rec *r, char *a)
67 if (TEST_SSL(r) != NULL) 71 if (TEST_SSL(r) != NULL)
68 { 72 {
69 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER"); 73 result = ssl_var_lookup(r->pool, r->server, r->connection, r, "SSL_CIPHER");
70 log_error(APLOG_MARK,APLOG_DEBUG,0, r->server,"SSL_CIPHER: %s", result); 74 #ifdef DEBUG
75 log_error(APLOG_MARK,APLOG_DEBUG,0,r->server,"SSL_CIPHER: %s", result);
76 #endif
71 if (result != NULL && result[0] == '\0') 77 if (result != NULL && result[0] == '\0')
72 result = NULL; 78 result = NULL;
73 return result; 79 return result;
@@ -76,11 +82,58 @@ static const char *extract_ssl_cipher(request_rec *r, char *a)
76 } 82 }
77} 83}
78 84
79 85#if defined(WITH_APACHE20)
80LOGSQL_REGISTER(ssl) 86static int post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
87#elif defined(WITH_APACHE13)
88static void module_init(server_rec *s, apr_pool_t *p)
89#endif
81{ 90{
82 log_sql_register_item(s,p,'q', extract_ssl_keysize, "ssl_keysize", 0, 1); 91 log_sql_register_item(s,p,'q', extract_ssl_keysize, "ssl_keysize", 0, 1);
83 log_sql_register_item(s,p,'Q', extract_ssl_maxkeysize, "ssl_maxkeysize", 0, 1); 92 log_sql_register_item(s,p,'Q', extract_ssl_maxkeysize, "ssl_maxkeysize", 0, 1);
84 log_sql_register_item(s,p,'z', extract_ssl_cipher, "ssl_cipher", 0, 1); 93 log_sql_register_item(s,p,'z', extract_ssl_cipher, "ssl_cipher", 0, 1);
85 LOGSQL_REGISTER_RETURN; 94#if defined(WITH_APACHE20)
95 return OK;
96#endif
86} 97}
98
99/* The configuration array that sets up the hooks into the module. */
100#if defined(WITH_APACHE20)
101static void register_hooks(apr_pool_t *p) {
102 ap_hook_post_config(post_config, NULL, NULL, APR_HOOK_REALLY_FIRST);
103}
104
105module AP_MODULE_DECLARE_DATA log_sql_ssl_module = {
106 STANDARD20_MODULE_STUFF,
107 NULL, /* create per-directory config structures */
108 NULL, /* merge per-directory config structures */
109 NULL, /* create per-server config structures */
110 NULL, /* merge per-server config structures */
111 NULL, /* command handlers */
112 register_hooks /* register hooks */
113};
114#elif defined(WITH_APACHE13)
115module log_sql_ssl_module = {
116 STANDARD_MODULE_STUFF,
117 module_init, /* module initializer */
118 NULL, /* create per-dir config */
119 NULL, /* merge per-dir config */
120 NULL, /* create server config */
121 NULL, /* merge server config */
122 NULL, /* config directive table */
123 NULL, /* [9] content handlers */
124 NULL, /* [2] URI-to-filename translation */
125 NULL, /* [5] check/validate user_id */
126 NULL, /* [6] check authorization */
127 NULL, /* [4] check access by host */
128 NULL, /* [7] MIME type checker/setter */
129 NULL, /* [8] fixups */
130 NULL, /* [10] logger */
131 NULL /* [3] header parser */
132#if MODULE_MAGIC_NUMBER >= 19970728 /* 1.3-dev or later support these additionals... */
133 ,NULL, /* child process initializer */
134 NULL, /* process exit/cleanup */
135 NULL /* [1] post read-request */
136#endif
137
138};
139#endif
diff --git a/winconfig.h b/winconfig.h
deleted file mode 100644
index c4b4353..0000000
--- a/winconfig.h
+++ /dev/null
@@ -1,78 +0,0 @@
1/* config.h. Generated by configure. */
2/* config.h.in. Generated from configure.ac by autoheader. */
3
4/* Define to 1 if you have the <inttypes.h> header file. */
5/* #undef HAVE_INTTYPES_H */
6
7/* Define to 1 if you have the `m' library (-lm). */
8/* #undef HAVE_LIBM */
9
10/* Define to 1 if you have the `mysqlclient' library (-lmysqlclient). */
11#define HAVE_LIBMYSQLCLIENT 1
12
13/* Define to 1 if you have the `z' library (-lz). */
14/* #undef HAVE_LIBZ */
15
16/* Define to 1 if you have the <limits.h> header file. */
17#define HAVE_LIMITS_H 1
18
19/* Define to 1 if you have the <memory.h> header file. */
20#define HAVE_MEMORY_H 1
21
22/* Define to 1 if you have the <mod_ssl.h> header file. */
23/* #undef HAVE_MOD_SSL_H */
24
25/* Define to 1 if you have the `mysql_real_escape_string' function. */
26#define HAVE_MYSQL_REAL_ESCAPE_STRING 1
27
28/* Define to 1 if you have the <stdint.h> header file. */
29/* #undef HAVE_STDINT_H */
30
31/* Define to 1 if you have the <stdlib.h> header file. */
32/* #undef HAVE_STDLIB_H 1
33
34/* Define to 1 if you have the <strings.h> header file. */
35/* #undef HAVE_STRINGS_H */
36
37/* Define to 1 if you have the <string.h> header file. */
38/* #undef HAVE_STRING_H */
39
40/* Define to 1 if you have the <sys/stat.h> header file. */
41/* #undef HAVE_SYS_STAT_H */
42
43/* Define to 1 if you have the <sys/types.h> header file. */
44/* #undef HAVE_SYS_TYPES_H */
45
46/* Define to 1 if you have the <unistd.h> header file. */
47/* #undef HAVE_UNISTD_H */
48
49/* Define to the address where bug reports for this package should be sent. */
50#define PACKAGE_BUGREPORT ""
51
52/* Define to the full name of this package. */
53#define PACKAGE_NAME "mod_log_sql"
54
55/* Define to the full name and version of this package. */
56#define PACKAGE_STRING "mod_log_sql 1.97"
57
58/* Define to the one symbol short name of this package. */
59#define PACKAGE_TARNAME "mod-log-sql"
60
61/* Define to the version of this package. */
62#define PACKAGE_VERSION "1.97"
63
64/* Define to 1 if you have the ANSI C header files. */
65/* #undef STDC_HEADERS */
66
67/* Define if we want to compile in SSL support. */
68/* #undef WANT_SSL_LOGGING */
69
70/* Define to 1 if we are compiling with Apache 1.3.x */
71/* #undef WITH_APACHE13 */
72
73/* Define to 1 if we are compiling with Apache 2.0.x */
74/* #undef WITH_APACHE20 */
75
76/* Define to 1 if we are compiling with mysql */
77#define WITH_MYSQL 1
78