2e6ae2ff6e8c3dec92f11b8d8fedb4271d34e7bd
1#
2# httpd.py
3#
4# Analyse Apache (httpd) server logs, including data transferred, requests,
5# clients, and errors. Note that Apache's logs can get filled up very quickly
6# with the default verbosity, leading to logparse taking a very long time to
7# analyse them. In general the default verbosity is good, but logs should be
8# cleared as soon as they are analysed (make sure 'rotate' is set to 'y').
9#
10
11import re
12
13from logparse.formatting import *
14from logparse.util import readlog, resolve
15from logparse import config
16from logparse.load_parsers import Parser
17
18ACCESS_REGEX = "^\s*(\S+).*\"GET (\S+) HTTP(?:\/\d\.\d)?\" (\d{3}) (\d*) \".+\" \"(.*)\""
19
20class AccessLine(object):
21
22 def __init__(self, line):
23 self.line = line
24 fields = re.search(ACCESS_REGEX, line)
25
26 self.client = fields.group(1)
27 self.file = fields.group(2)
28 self.statuscode = int(fields.group(3))
29 self.bytes = int(fields.group(4))
30 self.useragent = fields.group(5)
31
32class Httpd(Parser):
33
34 def __init__(self):
35 super().__init__()
36 self.name = "httpd"
37 self.info = "Analyse Apache (httpd) server logs, including data transferred, requests, clients, and errors."
38
39 def parse_log(self):
40
41 logger.debug("Starting httpd section")
42 section = Section("httpd")
43
44 accesslog = readlog(prefs("logs", "httpd-access"))
45
46 errorlog= readlog(prefs("logs", "httpd-error"))
47 total_errors = len(errorlog.splitlines())
48
49 logger.debug("Retrieved log data")
50
51 logger.debug("Searching through access log")
52
53 accesses = []
54
55 for line in accesslog.splitlines():
56 if "GET" in line:
57 accesses.append(AccessLine(line))
58
59 total_requests = len(accesses)
60
61 section.append_data(Data("Total of " + plural("request", total_requests)))
62 section.append_data(Data(plural("error", total_errors)))
63
64 size = Data()
65 size.subtitle = "Transferred " + parsesize(sum([ac.bytes for ac in accesses]))
66 section.append_data(size)
67
68 clients = Data()
69 clients.items = [resolve(ac.client, config.prefs.get("httpd", "httpd-resolve-domains")) for ac in accesses]
70 clients.orderbyfreq()
71 clients.subtitle = "Received requests from " + plural("client", len(clients.items))
72 clients.truncl(config.prefs.getint("logparse", "maxlist"))
73 section.append_data(clients)
74
75 files = Data()
76 files.items = [ac.file for ac in accesses]
77 files.orderbyfreq()
78 files.subtitle = plural("file", len(files.items)) + " requested"
79 files.truncl(config.prefs.getint("logparse", "maxlist"))
80 section.append_data(files)
81
82 useragents = Data()
83 useragents.items = [ac.useragent for ac in accesses]
84 useragents.orderbyfreq()
85 useragents.subtitle = plural("user agent", len(useragents.items))
86 useragents.truncl(config.prefs.getint("logparse", "maxlist"))
87 section.append_data(useragents)
88
89 logger.info("httpd has received " + str(total_requests) + " requests with " + str(total_errors) + " errors")
90
91
92 logger.info("Finished httpd section")
93 return section