# # httpd.py # # Analyse Apache (httpd) server logs, including data transferred, requests, # clients, and errors. Note that Apache's logs can get filled up very quickly # with the default verbosity, leading to logparse taking a very long time to # analyse them. In general the default verbosity is good, but logs should be # cleared as soon as they are analysed (make sure 'rotate' is set to 'y'). # import re from logparse.formatting import * from logparse.util import readlog, resolve from logparse import config from logparse.load_parsers import Parser ACCESS_REGEX = "^\s*(\S+).*\"GET (\S+) HTTP(?:\/\d\.\d)?\" (\d{3}) (\d*) \".+\" \"(.*)\"" class AccessLine(object): def __init__(self, line): self.line = line fields = re.search(ACCESS_REGEX, line) self.client = fields.group(1) self.file = fields.group(2) self.statuscode = int(fields.group(3)) self.bytes = int(fields.group(4)) self.useragent = fields.group(5) class Httpd(Parser): def __init__(self): super().__init__() self.name = "httpd" self.info = "Analyse Apache (httpd) server logs, including data transferred, requests, clients, and errors." def parse_log(self): logger.debug("Starting httpd section") section = Section("httpd") accesslog = readlog(config.prefs.get("logs", "httpd-access")) errorlog= readlog(config.prefs.get("logs", "httpd-error")) total_errors = len(errorlog.splitlines()) logger.debug("Retrieved log data") logger.debug("Searching through access log") accesses = [] for line in accesslog.splitlines(): if "GET" in line: accesses.append(AccessLine(line)) total_requests = len(accesses) section.append_data(Data("Total of " + plural("request", total_requests))) section.append_data(Data(plural("error", total_errors))) size = Data() size.subtitle = "Transferred " + parsesize(sum([ac.bytes for ac in accesses])) section.append_data(size) clients = Data() clients.items = [resolve(ac.client, config.prefs.get("httpd", "httpd-resolve-domains")) for ac in accesses] clients.orderbyfreq() clients.subtitle = "Received requests from " + plural("client", len(clients.items)) clients.truncl(config.prefs.getint("logparse", "maxlist")) section.append_data(clients) files = Data() files.items = [ac.file for ac in accesses] files.orderbyfreq() files.subtitle = plural("file", len(files.items)) + " requested" files.truncl(config.prefs.getint("logparse", "maxlist")) section.append_data(files) useragents = Data() useragents.items = [ac.useragent for ac in accesses] useragents.orderbyfreq() useragents.subtitle = plural("user agent", len(useragents.items)) useragents.truncl(config.prefs.getint("logparse", "maxlist")) section.append_data(useragents) logger.info("httpd has received " + str(total_requests) + " requests with " + str(total_errors) + " errors") logger.info("Finished httpd section") return section