e1772da0d6e518b4a47d55cf1970d4e520d57655
[apachelog.git] / apachelog / __init__.py
1 r"""Apache Log Parser
2
3 Parser for Apache log files. This is a port to python of Peter Hickman's
4 `Apache::LogEntry Perl module`__.
5
6 .. __: http://cpan.uwinnipeg.ca/~peterhi/Apache-LogRegex
7
8 Takes the `Apache logging format`__ defined in your ``httpd.conf`` and
9 generates a regular expression which is used to a line from the log
10 file and return it as a dictionary with keys corresponding to the
11 fields defined in the log format.
12
13 .. __: http://httpd.apache.org/docs/current/mod/mod_log_config.html#formats
14
15 Import libraries used in the example:
16
17 >>> import apachelog.parser, sys, StringIO, pprint
18
19 You should generally be able to copy and paste the format string from
20 your Apache configuration, but remember to place it in a raw string
21 using single-quotes, so that backslashes are handled correctly.
22
23 >>> format = r'%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"'
24 >>> p = apachelog.parser.Parser(format)
25
26 Now open your log file.  For this example, we'll fake a log file with
27 ``StringIO``.
28
29 >>> #log_stream = open('/var/apache/access.log')
30 >>> log_stream = StringIO.StringIO('\n'.join([
31 ...         '192.168.0.1 - - [18/Feb/2012:10:25:43 -0500] "GET / HTTP/1.1" 200 561 "-" "Mozilla/5.0 (...)"',
32 ...         'junk line',
33 ...         ]))
34 >>> for line in log_stream:
35 ...     try:
36 ...         data = p.parse(line)
37 ...     except:
38 ...         print("Unable to parse %s" % line.rstrip())
39 ...     else:
40 ...         pprint.pprint(data)
41 {'%>s': '200',
42  '%b': '561',
43  '%h': '192.168.0.1',
44  '%l': '-',
45  '%r': 'GET / HTTP/1.1',
46  '%t': '[18/Feb/2012:10:25:43 -0500]',
47  '%u': '-',
48  '%{Referer}i': '-',
49  '%{User-Agent}i': 'Mozilla/5.0 (...)'}
50 Unable to parse junk line
51
52 The return dictionary from the parse method has values for each
53 directive in the format string.
54
55 You can also re-map the field names by subclassing (or clobbering) the
56 alias method.
57
58 This module provides some common log formats in the ``FORMATS``
59 dictionary;
60
61 >>> # Common Log Format (CLF)
62 >>> p = apachelog.parser.Parser(apachelog.parser.FORMATS['common'])
63 >>> # Common Log Format with Virtual Host
64 >>> p = apachelog.parser.Parser(apachelog.parser.FORMATS['vhcommon'])
65 >>> # NCSA extended/combined log format
66 >>> p = apachelog.parser.Parser(apachelog.parser.FORMATS['extended'])
67 >>> # Nginx log format (extended + "$gzip_ratio")
68 >>> p = apachelog.parser.Parser(apachelog.parser.FORMATS['nginx'])
69
70 For some older notes regarding performance while reading lines from a
71 file in Python, see `this post`__ by Fredrik Lundh.  Further
72 performance boost can be gained by using psyco_.
73
74 .. __: http://effbot.org/zone/readline-performance.htm
75 .. _psycho: http://psyco.sourceforge.net/
76
77 On my system, using a loop like::
78
79     for line in open('access.log'):
80         p.parse(line)
81
82 was able to parse ~60,000 lines / second. Adding psyco to the mix,
83 up that to ~75,000 lines / second.
84 """
85
86 __version__ = "1.2"
87 __license__ = """Released under the same terms as Perl.
88 See: http://dev.perl.org/licenses/
89 """
90 __author__ = "Harry Fuecks <hfuecks@gmail.com>"
91 __contributors__ = [
92     "Peter Hickman <peterhi@ntlworld.com>",
93     "Loic Dachary <loic@dachary.org>",
94     "W. Trevor King <wking@drexel.edu>",
95     ]