diff options
-rw-r--r-- | contrib/Makefile.in | 86 | ||||
-rw-r--r-- | contrib/mysql_import_combined_log.pl | 203 |
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. | ||
4 | SUBDIRS = | ||
5 | |||
6 | EXTRA_DIST = README documentation.lyx | ||
7 | |||
8 | #Don't modify anything below here | ||
9 | |||
10 | srcdir = @abs_srcdir@ | ||
11 | builddir = @abs_builddir@ | ||
12 | |||
13 | STD_DIST = Makefile.in | ||
14 | |||
15 | DISTFILES = $(STD_DIST) $(EXTRA_DIST) | ||
16 | |||
17 | all: $(TARGET) all-subdirs | ||
18 | |||
19 | all-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 | |||
34 | include: | ||
35 | rm -rf include | ||
36 | ln -s @APACHE_INCDIR@ include | ||
37 | |||
38 | install: install-subdirs | ||
39 | @APXS_BIN@ -i -a -n $(subst mod_,,@PACKAGE_NAME@) $(TARGET) | ||
40 | |||
41 | update: update-subdirs | ||
42 | |||
43 | clean: clean-subdirs | ||
44 | |||
45 | distclean: clean distclean-subdirs | ||
46 | $(RM) Makefile | ||
47 | |||
48 | DESTDIR = @PACKAGE_TARNAME@-@PACKAGE_VERSION@ | ||
49 | DESTTGZ = $(DESTDIR).tar.gz | ||
50 | dist: | ||
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 | |||
72 | local-dist: $(DISTFILES) | ||
73 | mkdir -p $(DESTDIR) | ||
74 | cp -dp --parents $(DISTFILES) $(DESTDIR) | ||
75 | |||
76 | $(builddir)/.deps: depend | ||
77 | |||
78 | depend: $(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 | |||
83 | include $(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 | ||
2 | use strict; | ||
3 | use Getopt::Std; | ||
4 | use DBI; | ||
5 | use Time::ParseDate; | ||
6 | |||
7 | my %options = (); | ||
8 | my $i = 0; | ||
9 | my $sql = ''; | ||
10 | my $valuesSql = ''; | ||
11 | my $line = ''; | ||
12 | my $dbh = 0; | ||
13 | my $sth = 0; | ||
14 | my @parts = (); | ||
15 | my $part; | ||
16 | my $TIMESTAMP = 3; | ||
17 | my $REQUEST_LINE = 4; | ||
18 | my @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 | ); | ||
33 | my $col = ''; | ||
34 | |||
35 | $Getopt::Std::STANDARD_HELP_VERSION = 1; ## if we show the help, exit afterwards. | ||
36 | getopts('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 | |||
45 | if( ! $options{d} ) | ||
46 | { | ||
47 | print "Must supply a database to connect to.\n"; | ||
48 | exit 1; | ||
49 | } | ||
50 | |||
51 | if( ! $options{t} ) | ||
52 | { | ||
53 | print "Must supply table name.\n"; | ||
54 | exit 1; | ||
55 | } | ||
56 | |||
57 | if( $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} ("; | ||
70 | foreach $col (@cols) | ||
71 | { | ||
72 | $sql .= "$col," if( $col ); | ||
73 | } | ||
74 | chop($sql); | ||
75 | $sql .= ') VALUES ('; | ||
76 | |||
77 | while($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 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # | ||
102 | sub 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 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # | ||
112 | sub 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 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # | ||
174 | sub HELP_MESSAGE | ||
175 | { | ||
176 | print<<EOF; | ||
177 | Imports an Apache combined log into a MySQL database. | ||
178 | Usage: 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. | ||
187 | EOF | ||
188 | } | ||
189 | |||
190 | |||
191 | |||
192 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # | ||
193 | # Prints the version information for this program | ||
194 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # | ||
195 | sub VERSION_MESSAGE | ||
196 | { | ||
197 | print "mysql_import_combined_log.pl version 1.0\n"; | ||
198 | } | ||
199 | |||
200 | 1; | ||
201 | |||
202 | 1; | ||
203 | |||