Move to YAML-configured logging
This commit is contained in:
parent
342c0a2285
commit
3afcfd5856
52
app/log.py
Normal file → Executable file
52
app/log.py
Normal file → Executable file
@ -1,56 +1,54 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/env python3
|
||||||
# Standard library imports
|
# Standard library imports
|
||||||
import logging
|
import logging
|
||||||
|
import logging.config
|
||||||
import logging.handlers
|
import logging.handlers
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from traceback import print_exception
|
from traceback import print_exception
|
||||||
|
import yaml
|
||||||
|
|
||||||
# PyQt imports
|
# PyQt imports
|
||||||
|
|
||||||
# Third party imports
|
# Third party imports
|
||||||
import colorlog
|
|
||||||
import stackprinter # type: ignore
|
import stackprinter # type: ignore
|
||||||
|
|
||||||
# App imports
|
# App imports
|
||||||
from config import Config
|
from config import Config
|
||||||
|
|
||||||
|
|
||||||
|
class FunctionFilter(logging.Filter):
|
||||||
|
"""Filter to allow category-based logging to stderr."""
|
||||||
|
|
||||||
|
def __init__(self, functions: set[str]):
|
||||||
|
super().__init__()
|
||||||
|
self.functions = functions
|
||||||
|
|
||||||
|
def filter(self, record: logging.LogRecord) -> bool:
|
||||||
|
return (
|
||||||
|
getattr(record, "funcName", None) in self.functions
|
||||||
|
and getattr(record, "levelname", None) == "DEBUG"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class LevelTagFilter(logging.Filter):
|
class LevelTagFilter(logging.Filter):
|
||||||
"""Add leveltag"""
|
"""Add leveltag"""
|
||||||
|
|
||||||
def filter(self, record: logging.LogRecord) -> bool:
|
def filter(self, record: logging.LogRecord) -> bool:
|
||||||
# Extract the first character of the level name
|
# Extract the first character of the level name
|
||||||
record.leveltag = record.levelname[0]
|
record.leveltag = record.levelname[0]
|
||||||
|
# We never actually filter messages out, just add an extra field
|
||||||
# We never actually filter messages out, just abuse filtering to add an
|
# to the LogRecord
|
||||||
# extra field to the LogRecord
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
# Load YAML logging configuration
|
||||||
|
with open("app/logging.yaml", "r") as f:
|
||||||
|
config = yaml.safe_load(f)
|
||||||
|
logging.config.dictConfig(config)
|
||||||
|
|
||||||
|
# Get logger
|
||||||
log = logging.getLogger(Config.LOG_NAME)
|
log = logging.getLogger(Config.LOG_NAME)
|
||||||
log.setLevel(logging.DEBUG)
|
|
||||||
local_filter = LevelTagFilter()
|
|
||||||
|
|
||||||
# stderr
|
|
||||||
stderr = colorlog.StreamHandler()
|
|
||||||
stderr.setLevel(Config.LOG_LEVEL_STDERR)
|
|
||||||
stderr.addFilter(local_filter)
|
|
||||||
stderr_fmt = colorlog.ColoredFormatter(
|
|
||||||
"%(log_color)s[%(asctime)s] %(filename)s:%(lineno)s %(message)s", datefmt="%H:%M:%S"
|
|
||||||
)
|
|
||||||
stderr.setFormatter(stderr_fmt)
|
|
||||||
log.addHandler(stderr)
|
|
||||||
|
|
||||||
# syslog
|
|
||||||
syslog = logging.handlers.SysLogHandler(address="/dev/log")
|
|
||||||
syslog.setLevel(Config.LOG_LEVEL_SYSLOG)
|
|
||||||
syslog.addFilter(local_filter)
|
|
||||||
syslog_fmt = logging.Formatter(
|
|
||||||
"[%(name)s] %(filename)s:%(lineno)s %(leveltag)s: %(message)s"
|
|
||||||
)
|
|
||||||
syslog.setFormatter(syslog_fmt)
|
|
||||||
log.addHandler(syslog)
|
|
||||||
|
|
||||||
|
|
||||||
def log_uncaught_exceptions(type_, value, traceback):
|
def log_uncaught_exceptions(type_, value, traceback):
|
||||||
|
|||||||
46
app/logging.yaml
Normal file
46
app/logging.yaml
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
version: 1
|
||||||
|
disable_existing_loggers: True
|
||||||
|
|
||||||
|
formatters:
|
||||||
|
colored:
|
||||||
|
(): colorlog.ColoredFormatter
|
||||||
|
format: "%(log_color)s[%(asctime)s] %(filename)s:%(lineno)s %(message)s"
|
||||||
|
datefmt: "%H:%M:%S"
|
||||||
|
syslog:
|
||||||
|
format: "[%(name)s] %(filename)s:%(lineno)s %(leveltag)s: %(message)s"
|
||||||
|
|
||||||
|
filters:
|
||||||
|
leveltag:
|
||||||
|
(): newlogger.LevelTagFilter
|
||||||
|
category_filter:
|
||||||
|
(): newlogger.FunctionFilter
|
||||||
|
functions: !!set
|
||||||
|
fb: null
|
||||||
|
|
||||||
|
handlers:
|
||||||
|
stderr:
|
||||||
|
class: colorlog.StreamHandler
|
||||||
|
level: INFO
|
||||||
|
formatter: colored
|
||||||
|
filters: [leveltag]
|
||||||
|
stream: ext://sys.stderr
|
||||||
|
|
||||||
|
syslog:
|
||||||
|
class: logging.handlers.SysLogHandler
|
||||||
|
level: DEBUG
|
||||||
|
formatter: syslog
|
||||||
|
filters: [leveltag]
|
||||||
|
address: "/dev/log"
|
||||||
|
|
||||||
|
debug_stderr:
|
||||||
|
class: colorlog.StreamHandler
|
||||||
|
level: DEBUG
|
||||||
|
formatter: colored
|
||||||
|
filters: [leveltag, category_filter]
|
||||||
|
stream: ext://sys.stderr
|
||||||
|
|
||||||
|
loggers:
|
||||||
|
musicmuster:
|
||||||
|
level: DEBUG
|
||||||
|
handlers: [stderr, syslog, debug_stderr]
|
||||||
|
propagate: false
|
||||||
27
app/logging_tester.py
Executable file
27
app/logging_tester.py
Executable file
@ -0,0 +1,27 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
from newlogger import log
|
||||||
|
# Testing
|
||||||
|
def fa():
|
||||||
|
log.debug("fa Debug message")
|
||||||
|
log.info("fa Info message")
|
||||||
|
log.warning("fa Warning message")
|
||||||
|
log.error("fa Error message")
|
||||||
|
log.critical("fa Critical message")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
def fb():
|
||||||
|
log.debug("fb Debug message")
|
||||||
|
log.info("fb Info message")
|
||||||
|
log.warning("fb Warning message")
|
||||||
|
log.error("fb Error message")
|
||||||
|
log.critical("fb Critical message")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
def testing():
|
||||||
|
fa()
|
||||||
|
fb()
|
||||||
|
|
||||||
|
|
||||||
|
testing()
|
||||||
Loading…
Reference in New Issue
Block a user