summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--contrib/Makefile.in86
-rw-r--r--contrib/mysql_import_combined_log.pl203
2 files changed, 289 insertions, 0 deletions
diff --git a/contrib/Makefile.in b/contrib/Makefile.in
new file mode 100644
index 0000000..ca70e2f
--- /dev/null
+++ b/contrib/Makefile.in
@@ -0,0 +1,86 @@
1# @configure_input@
2
3# Modify these top variables.
4SUBDIRS =
5
6EXTRA_DIST = README documentation.lyx
7
8#Don't modify anything below here
9
10srcdir = @abs_srcdir@
11builddir = @abs_builddir@
12
13STD_DIST = Makefile.in
14
15DISTFILES = $(STD_DIST) $(EXTRA_DIST)
16
17all: $(TARGET) all-subdirs
18
19all-subdirs install-subdirs update-subdirs clean-subdirs distclean-subdirs:
20 @otarget=`echo $@|sed s/-subdirs//`; \
21 list=' $(SUBDIRS)'; \
22 for i in $$list; do \
23 if test -d "$$i"; then \
24 target="$$otarget"; \
25 echo "Making $$target in $$i"; \
26 if test "$$i" = "."; then \
27 made_local=yes; \
28 target="local-$$target"; \
29 fi; \
30 (cd $$i && $(MAKE) $$target) || exit 1; \
31 fi; \
32 done; \
33
34include:
35 rm -rf include
36 ln -s @APACHE_INCDIR@ include
37
38install: install-subdirs
39 @APXS_BIN@ -i -a -n $(subst mod_,,@PACKAGE_NAME@) $(TARGET)
40
41update: update-subdirs
42
43clean: clean-subdirs
44
45distclean: clean distclean-subdirs
46 $(RM) Makefile
47
48DESTDIR = @PACKAGE_TARNAME@-@PACKAGE_VERSION@
49DESTTGZ = $(DESTDIR).tar.gz
50dist:
51 @rm -rf $(DESTDIR); \
52 list=' $(SUBDIRS)'; \
53 for i in $$list; do \
54 if test -d "$$i"; then \
55 target=local-dist; \
56 echo "Making $$target in $$i"; \
57 if test "$$i" = "."; then \
58 made_local=yes; \
59 target="local-dist"; \
60 fi; \
61 NEWDESTDIR=$(builddir)/$(DESTDIR)/$$i; \
62 echo $(NEWDESTDIR); \
63 (cd $$i && $(MAKE) DESTDIR=$(builddir)/$(DESTDIR)/$$i $$target) || exit 1; \
64 fi; \
65 done;
66 if test "$$made_local" != "yes"; then \
67 $(MAKE) "local-dist" || exit 1; \
68 fi
69 tar -zcf $(DESTTGZ) $(DESTDIR)
70 rm -rf $(DESTDIR)
71
72local-dist: $(DISTFILES)
73 mkdir -p $(DESTDIR)
74 cp -dp --parents $(DISTFILES) $(DESTDIR)
75
76$(builddir)/.deps: depend
77
78depend: $(SOURCES) $(HEADERS)
79 if test -n "`ls $(srcdir)/*.c 2> /dev/null`"; then \
80 $(CC) -MM -MT $(TARGET) -I@APACHE_INCDIR@ $(INCLUDES) $(srcdir)/*.c > $(builddir)/.deps || true; \
81 fi
82
83include $(builddir)/.deps
84
85.PHONY: include all-subdirs update-subdirs install-subdirs \
86 clean-subdirs distclean-subdirs dist
diff --git a/contrib/mysql_import_combined_log.pl b/contrib/mysql_import_combined_log.pl
new file mode 100644
index 0000000..3384b77
--- /dev/null
+++ b/contrib/mysql_import_combined_log.pl
@@ -0,0 +1,203 @@
1#!/usr/bin/perl
2use strict;
3use Getopt::Std;
4use DBI;
5use Time::ParseDate;
6
7my %options = ();
8my $i = 0;
9my $sql = '';
10my $valuesSql = '';
11my $line = '';
12my $dbh = 0;
13my $sth = 0;
14my @parts = ();
15my $part;
16my $TIMESTAMP = 3;
17my $REQUEST_LINE = 4;
18my @cols = (
19 'remote_host', ## 0
20 'remote_user', ## 1
21 '', ## 2
22 'time_stamp', ## 4
23 'request_line', ## 5
24 'request_method', ## 6
25 'request_uri', ## 7
26 'request_args', ## 8
27 'request_protocol', ## 9
28 'status', ## 10
29 'bytes_sent', ## 11
30 'referer', ## 12
31 'agent' ## 13
32);
33my $col = '';
34
35$Getopt::Std::STANDARD_HELP_VERSION = 1; ## if we show the help, exit afterwards.
36getopts('h:u:p:d:t:f:', \%options);
37
38
39$options{h} ||= 'localhost';
40$options{d} ||= '';
41$options{u} ||= '';
42$options{p} ||= '';
43$options{f} ||= '';
44
45if( ! $options{d} )
46{
47 print "Must supply a database to connect to.\n";
48 exit 1;
49}
50
51if( ! $options{t} )
52{
53 print "Must supply table name.\n";
54 exit 1;
55}
56
57if( $options{f} )
58{
59 if( ! -e $options{f} )
60 {
61 print "File '$options{f}' doesn't exist.\n";
62 exit 1;
63 }
64 open(STDIN, "<$options{f}") || die "Can't open $options{f} for reading.";
65}
66
67$dbh = Connect();
68
69$sql = "INSERT INTO $options{t} (";
70foreach $col (@cols)
71{
72 $sql .= "$col," if( $col );
73}
74chop($sql);
75$sql .= ') VALUES (';
76
77while($line = <STDIN>)
78{
79 @parts = SplitLogLine( $line );
80 next if( $parts[$TIMESTAMP] == 0 );
81 $valuesSql = '';
82 for( $i = 0; $i < @cols; ++$i )
83 {
84 $parts[$i] =~ s/\\/\\\\/g;
85 $parts[$i] =~ s/'/\\'/g;
86 $valuesSql .= "'$parts[$i]'," if( $cols[$i] );
87 }
88 chop($valuesSql);
89
90 $sth = $dbh->prepare("$sql$valuesSql)");
91 if( ! $sth->execute() )
92 {
93 print "Unable to perform specified query.\n$sql$valuesSql\n" . $sth->errstr() . "\n";
94 }
95 $sth->finish();
96}
97
98
99# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
100# Connects to a MySQL database and returns the connection.
101# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
102sub Connect
103{
104 my $dsn = "DBI:mysql:$options{d};hostname=$options{h}";
105 return DBI->connect( $dsn, $options{u}, $options{p} );
106}
107
108
109# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
110# Splits up a log line into its parts.
111# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
112sub SplitLogLine
113{
114 my $line = shift;
115 my $i = 0;
116 my $inQuote = 0;
117 my $char = '';
118 my $part = '';
119 my @parts = ();
120 my $count;
121 chomp($line);
122 for( $i = 0; $i < length($line); ++$i )
123 {
124 $char = substr($line, $i, 1);
125 if( $char eq ' ' && ! $inQuote )
126 {
127 ## print "Found part $part.\n";
128 if( $count == $TIMESTAMP )
129 {
130 $part = parsedate($part, WHOLE => 1, DATE_REQUIRED => 1, TIME_REQUIRED => 2);
131 }
132 push(@parts, $part);
133 if( $count == $REQUEST_LINE )
134 {
135 my @request = split(/[ ?]/, $part);
136 push(@parts, $request[0]);
137 push(@parts, $request[1]);
138 if( $request[3] )
139 {
140 push(@parts, $request[2]);
141 push(@parts, $request[3]);
142 }
143 else
144 {
145 push(@parts, '');
146 push(@parts, $request[2]);
147 }
148 $count += 5;
149 }
150 else
151 {
152 ++$count;
153 }
154 $part = '';
155 }
156 elsif( $char eq '"' || $char eq '[' || $char eq ']' )
157 {
158 $inQuote = !$inQuote;
159 }
160 else
161 {
162 $part .= $char;
163 }
164 }
165 push(@parts,$part) if $part;
166
167 return @parts;
168}
169
170
171# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
172# Prints the usage/help message for this program.
173# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
174sub HELP_MESSAGE
175{
176 print<<EOF;
177Imports an Apache combined log into a MySQL database.
178Usage: mysql_import_combined_log.pl -d <database name> -t <table name> [-h <hostname>] [-u <username>] [-p <password>] [-f <filename]
179 -h <host name> The host to connect to. Default is localhost.
180 -d <database name> The database to use. Required.
181 -u <username> The user to connect as.
182 -p <password> The user's password.
183 -t <table name> The name of the table in which to insert data.
184 -f <file name> The file to read from. If not given, data is read from stdin.
185 --help Print out this help message.
186 --version Print out the version of this software.
187EOF
188}
189
190
191
192# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
193# Prints the version information for this program
194# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
195sub VERSION_MESSAGE
196{
197 print "mysql_import_combined_log.pl version 1.0\n";
198}
199
2001;
201
2021;
203