Source code for FabLabKasse.scripts.logWatchAndCleanup

#!/usr/bin/env python2.7
# -*- coding: utf-8 -*-
#
# FabLabKasse, a Point-of-Sale Software for FabLabs and other public and trust-based workshops.
# Copyright (C) 2015 Maximilian Gaukler <max@fablab.fau.de>
#
# 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 <http://www.gnu.org/licenses/>.


"""
a cronjob for cleaning up and gzipping old logfiles

- report errors and warnings in the newest logfiles (the current one, foo.log, and the archive files foo.log.2012-12-31 created after the last run of this script [i.e. the non-gzipped ones])
- gzip old logfiles and remove too old ones

run this script by starting logWatchAndCleanup.sh which lives in the same directory

# it is recommended to run this script before midnight, because the logs wrap over at midnight and might change in the middle of running this script

"""
# this script should work without changes under python3. ScriptHelpers dependencies (ConfigParser) are currently not ported to python3, so this remains python2.7

from __future__ import print_function
import sys
import os
import re
import subprocess
import dateutil.parser
import datetime


[docs]def main(): os.chdir(os.path.dirname(os.path.realpath(__file__)) + "/../") def isWarningLine(line): return "CRITICAL" in line or "ERROR" in line or "WARN" in line MAX_ERRORS_PER_LOG = 1000 LOG_MAX_AGE = 14 # after how many days will the log be deleted errorLines = {} # gzip all old logfiles blafu.log.2014-12-24 for f in os.listdir("."): isOldUnzippedLog = bool(re.match(r'[^/]*\.log\.[0-9]{4}-[0-9]{2}-[0-9]{2}$', f)) isNewLog = f.endswith(".log") oldZippedLog = re.match(r'[^/]*\.log\.([0-9]{4}-[0-9]{2}-[0-9]{2}).gz$', f) if oldZippedLog: # something like "asf.log.2015-04-12.gz" fileDate = dateutil.parser.parse(oldZippedLog.group(1)) # get file date if datetime.datetime.now() - fileDate > datetime.timedelta(LOG_MAX_AGE, 0, 0): # print("cleaning up: "+f) os.unlink(f) if isOldUnzippedLog or isNewLog: for line in open(f, "r"): if isWarningLine(line): if f not in errorLines: errorLines[f] = [] errorLines[f].append(line) if len(errorLines[f]) > MAX_ERRORS_PER_LOG: break # found gzip old logfile if isOldUnzippedLog: assert subprocess.call(["gzip", f]) == 0, "calling gzip failed" if not errorLines: sys.exit(0) print("Hi, this is FabLabKasse/scripts/logWatch.sh.\nThere were warnings or errors in the recent logfile.\nPrinting the recent {0} ones per file:\n".format(MAX_ERRORS_PER_LOG)) for file in sorted(errorLines.keys()): print("\n\n========\n{0}\n========".format(file)) for line in errorLines[file]: print(line.strip()) if len(errorLines[file]) >= MAX_ERRORS_PER_LOG: print("...") sys.exit(0)
if __name__ == "__main__": main()