#!/usr/bin/python3
#
# Copyright (C) 2021 FreeIPA Contributors see COPYING for license
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
from __future__ import division
from datetime import datetime
import logging
import re
from ipapython import admintool
from ipalib.facts import is_ipa_configured
# r'(?P\S+)/1\(.*\): (?P\S+) etime=(?P\d+)'
TIME_RE = re.compile(
r'\[(?P.*)\] \[.*\].* \[pid \d+:tid \d+\] \[remote .*\] '
r'ipa: DEBUG: FINAL: Hits (?P\d+) Misses (?P\d+) '
r'Size (?P\d+)'
)
DATE_FORMAT = '%a %b %d %H:%M:%S.%f %Y'
logger = logging.getLogger(__name__)
class cachelog(admintool.AdminTool):
command_name = "cachelog"
usage = "%prog [options]"
description = "Parse the Apache error log for cache performance data. " \
"Enable debugging by creating /etc/ipa/server.conf with " \
"the contents: [global]\\ndebug = True"
def __init__(self, options, args):
super(cachelog, self).__init__(options, args)
self.since = None
@classmethod
def add_options(cls, parser):
super(cachelog, cls).add_options(parser, debug_option=True)
parser.add_option(
"--command",
dest="command",
action="store",
default=None,
help="Command to analyze",
)
parser.add_option(
"--start-time",
dest="start_time",
action="store",
default=None,
help="time to begin analyzing logfile from, e.g. "
"Fri May 7 16:33:08.0 2021",
)
parser.add_option(
"--file",
dest="file",
action="store",
default="/var/log/httpd/error_log",
help="Log file to parse",
)
def validate_options(self):
super(cachelog, self).validate_options(needs_root=True)
if self.options.start_time:
self.since = datetime.strptime(
self.options.start_time,
DATE_FORMAT
)
def run(self):
super(cachelog, self).run()
if not is_ipa_configured():
logger.error("IPA server is not configured on this system.")
raise admintool.ScriptError()
with open(self.options.file, 'r') as f:
data = f.read()
matches = list(re.finditer(TIME_RE, data))
hits = 0
misses = 0
count = 0
for match in matches:
if self.since:
logtime = datetime.strptime(match.group('date'), DATE_FORMAT)
if logtime < self.since:
continue
hits += int(match.group('hits'))
misses += int(match.group('misses'))
count += 1
print('Total reads %d, hits %d, misses %d, avg %1.4f' %
(hits + misses, hits, misses, hits / (hits + misses)))
if __name__ == '__main__':
cachelog.run_cli()