simplified rich logging with dictconfig

This commit is contained in:
John Lancaster
2024-04-27 10:24:45 -05:00
parent dc7151549b
commit 6250b6b20c
2 changed files with 79 additions and 57 deletions

View File

@@ -1,11 +1,11 @@
import logging
import logging.config
import re
from dataclasses import asdict, dataclass
from appdaemon.adapi import ADAPI
from appdaemon.logging import AppNameFormatter
from rich.console import Console
from rich.highlighter import RegexHighlighter
from rich.logging import RichHandler
from rich.theme import Theme
@@ -43,6 +43,19 @@ console = Console(
)
class ContextSettingFilter(logging.Filter):
def filter(self, record: logging.LogRecord):
for name, val in asdict(self).items():
setattr(record, name, val)
return record
@dataclass
class RoomControllerFilter(ContextSettingFilter):
room: str
component: str
class UnMarkupFormatter(AppNameFormatter):
md_regex = re.compile(r'(?P<open>\[.*?\])(?P<text>.*?)(?P<close>\[\/\])')
@@ -51,56 +64,63 @@ class UnMarkupFormatter(AppNameFormatter):
return self.md_regex.sub(r'\g<text>', result)
class RoomControllerFormatter(logging.Formatter):
def __init__(self, room: str, component: str = None):
self.log_fields = {'room': room}
def create_rich_logging_dict(parent_room: str, typ: str = None):
logger_name = f'room_control.{parent_room}'
if typ is not None:
logger_name += f'.{typ}'
fmt = '[room]{room:>12}[/] [component]{component:<9}[/]{message}'
else:
fmt = '[room]{room:>12}[/] {message}'
fmt = '[room]{room:>12}[/]'
if component is not None:
fmt += ' [component]{component:<9}[/]'
self.log_fields['component'] = component
fmt += ' {message}'
datefmt = '%Y-%m-%d %I:%M:%S %p'
style = '{'
validate = True
super().__init__(fmt, datefmt, style, validate)
# console.print(f'Format: [bold yellow]{fmt}[/]')
def format(self, record: logging.LogRecord):
parts = record.name.split('.')
record.room = parts[1]
if len(parts) == 3:
record.component = parts[2]
return super().format(record)
def new_handler() -> RichHandler:
return RichHandler(
console=console,
# highlighter=NullHighlighter(),
highlighter=RCHighlighter(),
markup=True,
show_path=False,
omit_repeated_times=False,
log_time_format='%Y-%m-%d %I:%M:%S %p',
)
def setup_handler(**kwargs) -> RichHandler:
handler = new_handler()
handler.setFormatter(RoomControllerFormatter(**kwargs))
return handler
LOG_CFG = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
logger_name: {
'()': 'console.RoomControllerFilter',
# '.': {'room': parent_room, 'component': typ},
'room': parent_room,
'component': typ,
}
},
'formatters': {
logger_name: {
'style': '{',
'format': fmt,
# 'datefmt': '%Y-%m-%d %I:%M:%S %p',
}
},
'handlers': {
logger_name: {
'filters': [logger_name],
'formatter': logger_name,
'()': 'rich.logging.RichHandler',
'markup': True,
'log_time_format': '%Y-%m-%d %I:%M:%S %p',
'show_path': False,
'omit_repeated_times': False,
'highlighter': RCHighlighter(),
'console': console,
},
},
'loggers': {
logger_name: {
'level': 'INFO',
'propagate': False,
'handlers': [logger_name],
}
},
}
return LOG_CFG
def setup_component_logging(self):
typ = type(self).__name__
logger = logging.getLogger(f'room_control.{self.args["app"]}')
self.logger = logger.getChild(typ)
if len(self.logger.handlers) == 0:
self.logger.setLevel(logging.INFO)
self.logger.addHandler(setup_handler(room=self.args['app'], component=typ))
self.logger.propagate = False
cfg_dict = create_rich_logging_dict(parent_room=self.args['app'], typ=type(self).__name__)
logger_name = next(iter(cfg_dict['loggers']))
try:
logging.config.dictConfig(cfg_dict)
except Exception:
console.print_exception()
else:
self.logger = logging.getLogger(logger_name)