From 6fc6399ff375d210ee41474e45e998a358dd0bc0 Mon Sep 17 00:00:00 2001 From: Andrew Lorimer Date: Sat, 31 Aug 2019 22:54:21 +1000 Subject: [PATCH] fix logrotate functionality --- logparse/interface.py | 54 +++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/logparse/interface.py b/logparse/interface.py index c37ec9a..583d6b6 100644 --- a/logparse/interface.py +++ b/logparse/interface.py @@ -10,6 +10,7 @@ import argparse import os import glob import sys +from subprocess import check_output from datetime import datetime import logparse @@ -17,19 +18,31 @@ from .config import * from logparse import formatting, mail, config from .parsers import load_parsers -def rotate(): - # rotate logs using systemd logrotate - if argparser.parse_args().function is None: - if (prefs['rotate'] == 'y'): - subprocess.call("/usr/sbin/logrotate -f /etc/logrotate.conf", shell=True) - logger.info("rotated logfiles") +def rotate(): # Rotate logs using systemd logrotate + try: + if not os.geteuid() == 0: + if sys.stdin.isatty(): + logger.warning("Not running as root, using sudo (may require password to be entered)") + rotate_shell = check_output("sudo logrotate /etc/logrotate.conf", shell=True) + else: + raise PermissionError("Root priviliges are required to run logrotate but are not provided") else: - logger.debug("user doesn't want to rotate logs") - if (prefs['rotate'] == 's'): - logger.debug("Here is the output of `logrotate -d /etc/logrotate.conf` (simulated):") - sim = subprocess.check_output("/usr/sbin/logrotate -d /etc/logrotate.conf", shell=True) - logger.debug(sim) - + rotate_shell = check_output("/usr/sbin/logrotate /etc/logrotate.conf", shell=True) + logger.info("Rotated logfiles") + logger.debug("logrotate output: " + rotate_shell) + except Exception as e: + logger.warning("Failed to rotate log files: " + str(e)) + +def rotate_sim(): # Simulate log rotation + try: + if not os.geteuid() == 0: + logger.warning("Cannot run logrotate as root - you will see permission errors in the output below") + sim_cmd = "logrotate -d /etc/logrotate.conf" + logger.debug("Here is the output of `{0}` (simulated):".format(sim_cmd) + sim = check_output(sim_cmd, shell=True) + logger.debug(sim) + except Exception as e: + logger.warning("Failed to get logrotate simulation: " + str(e)) def main(): @@ -41,8 +54,9 @@ def main(): argparser.add_argument('-d', '--destination', help='file to output HTML', required=False) argparser.add_argument('-f', '--overwrite', help='force overwrite an existing output file', required=False, action='store_true', default=False) argparser.add_argument('-v', '--verbose', help='verbose console/syslog output (for debugging)', required=False, default=False, action='store_true') - argparser.add_argument('-r', '--rotate', help='force rotate log files using systemd logrotate', required=False, default=False, action='store_true') - argparser.add_argument('-nr', '--no-rotate', help='do not rotate logfiles (overrides logparse.conf)', required=False, default=False, action='store_true') + argparser.add_argument('-r', '--rotate', help='force rotate log files using systemd logrotate (overrides --rotate and "rotate" in logparse.conf)', required=False, default=False, action='store_true') + argparser.add_argument('-nr', '--no-rotate', help='do not rotate logfiles (overrides --rotate and logparse.conf)', required=False, default=False, action='store_true') + argparser.add_argument('-s', '--simulate', help="test run logrotate (do not actually change files)", required=False, default=False, action="store_true") argparser.add_argument('-l', '--logs', help='services to analyse', required=False) argparser.add_argument('-nl', '--ignore-logs', help='skip these services (takes precedence over -l)', required=False) argparser.add_argument('-es', '--embed-styles', help='make CSS rules inline rather than linking the file', required=False, default=False, action='store_true') @@ -59,7 +73,7 @@ def main(): # Set up logging logger = logging.getLogger(__name__) loghandler = logging.handlers.SysLogHandler(address = '/dev/log') - loghandler.setFormatter(logging.Formatter(fmt='logparse.py[' + str(os.getpid()) + ']: %(message)s')) + loghandler.setFormatter(logging.Formatter(fmt='logparse[' + str(os.getpid()) + ']: %(message)s')) loghandler.setLevel(logging.INFO) # don't spam syslog with debug messages if argparser.parse_args().quiet or config.prefs['quiet']: logging.basicConfig(level=logging.CRITICAL) @@ -158,6 +172,16 @@ def main(): to = prefs['mail']['to'] mail.sendmail(mailbin=prefs['mail']['mailbin'], body=(output.embed_css(prefs['css']) if isinstance(output, formatting.HtmlOutput) else output.content), recipient=to, subject=formatting.fsubject(config.prefs['mail']['subject']), html=isinstance(output, formatting.HtmlOutput), sender=prefs['mail']['from']) + if not argparser.parse_args().no_rotate: + if argparser.parse_args().simulate or prefs['rotate'] == 's': + rotate_sim() + elif prefs['rotate'] or argparser.parse_args().rotate: + rotate() + else: + logger.debug("User doesn't want to rotate logs") + else: + logger.debug("User doesn't want to rotate logs") + # Print end message finish = datetime.now() logger.info("Finished parsing logs at {0} {1} (total time: {2})".format(finish.strftime(formatting.DATEFMT), finish.strftime(formatting.TIMEFMT), finish - start)) -- 2.43.2