Source code for spinningdiskanalyzer.logger

"""Handles setup of the debug log."""

from . import meta

import logging
import logging.handlers
from appdirs import user_log_dir
from pathlib import Path
import sys
import re


[docs] def setup(): """Configures event logging for the application.""" # Set log granularity on root logger. log = logging.getLogger() log.setLevel(logging.DEBUG) # Suppress noise from certain libraries in the log output. mute = ('pyvips', 'PIL', 'matplotlib') for package in mute: logging.getLogger(package).propagate = False # Store log files inside the system's application data folder. logs = logs_folder() logs.mkdir(exist_ok=True, parents=True) # Also log to the console. handler = logging.StreamHandler(sys.stdout) log.setLevel(logging.DEBUG) logging.setLogRecordFactory(timed_records) entry = '%(timestamp)s | %(levelname)-8s | %(message)s' times = '%Y-%m-%d %H:%M:%S' formatter = logging.Formatter(entry, datefmt=times) handler.setFormatter(formatter) log.addHandler(handler) # Rotate out old log entries to separate file once a day. handler = logging.handlers.TimedRotatingFileHandler( logs/'today.txt', encoding='UTF-8-sig', when='midnight') handler.rotation_filename = rotation_filename entry = '%(asctime)s | %(levelname)-8s | %(message)s | %(name)s' times = '%H:%M:%S' formatter = logging.Formatter(entry, datefmt=times) handler.setFormatter(formatter) log.addHandler(handler)
[docs] def logs_folder() -> Path: """Returns the folder containing the log files.""" return Path(user_log_dir(appname=meta.title, appauthor=''))
[docs] def rotation_filename(path: Path) -> Path: """ Monkey-patches the logging handler's file renaming mechanism so that, on roll-over, log files from previous days get the actual date, and only that, as the file name, and have `.txt` as the suffix. *Note*: A proper implementation would also have to override the `getFilesToDelete()` method. But this here works for our use case where we never purge logs. Refer to the [source code][1] for further details. [1]: https://github.com/python/cpython/blob/master/Lib/logging/handlers.py """ path = Path(path) date = re.match(r'\.(\d\d\d\d-\d\d-\d\d)', path.suffix).group(1) return path.with_name(f'{date}.txt')
original_records = logging.getLogRecordFactory()
[docs] def timed_records(*args, **kwargs) -> logging.LogRecord: """ Adds a relative `timestamp` to the log record attributes. Example usage: ``` logging.setLogRecordFactory(timed_records) logging.basicConfig(format='[%(timestamp)s] %(message)s') ``` """ record = original_records(*args, **kwargs) (minutes, seconds) = divmod(record.relativeCreated/1000, 60) record.timestamp = f'{minutes:02.0f}:{seconds:06.3f}' return record