Luxx/run.py

93 lines
2.8 KiB
Python

#!/usr/bin/env python3
"""Application entry point"""
import logging
import logging.config
from copy import copy
import uvicorn
from uvicorn.logging import ColourizedFormatter
from luxx.config import config
# Custom formatter extending uvicorn's ColourizedFormatter
class ModuleFormatter(ColourizedFormatter):
"""Add module name after level prefix for non-uvicorn loggers"""
def formatMessage(self, record: logging.LogRecord) -> str:
# Copy record to avoid modifying the original
recordcopy = copy(record)
# Get level name with color
levelname = recordcopy.levelname
separator = " " * (8 - len(recordcopy.levelname))
if self.use_colors:
levelname = self.color_level_name(levelname, recordcopy.levelno)
if "color_message" in recordcopy.__dict__:
recordcopy.msg = recordcopy.__dict__["color_message"]
recordcopy.__dict__["message"] = recordcopy.getMessage()
# Add module name for all loggers
name = record.name
# For uvicorn.error, show "uvicorn" not "error"
if name.startswith('uvicorn.'):
module = 'uvicorn'
else:
module = name
levelprefix = levelname + ":" + separator
recordcopy.__dict__["levelprefix"] = f"{levelprefix} [{module}]"
return super(ColourizedFormatter, self).formatMessage(recordcopy)
def get_log_config() -> dict:
"""Get log configuration from config.yaml"""
log_level = getattr(config, 'log_level', 'INFO')
return {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"default": {
"()": ModuleFormatter,
"fmt": "%(levelprefix)s %(message)s",
},
},
"handlers": {
"default": {
"formatter": "default",
"class": "logging.StreamHandler",
"stream": "ext://sys.stderr",
},
},
"loggers": {
"uvicorn": {"handlers": ["default"], "level": log_level, "propagate": False},
"uvicorn.error": {"handlers": ["default"], "level": log_level, "propagate": False},
"uvicorn.access": {"handlers": [], "level": "WARNING", "propagate": False},
"uvicorn.asgi": {"handlers": [], "level": "WARNING", "propagate": False},
},
"root": {
"handlers": ["default"],
"level": log_level,
},
}
LOG_CONFIG = get_log_config()
def main():
"""Start the application"""
logging.config.dictConfig(LOG_CONFIG)
uvicorn.run(
"luxx:app",
host=config.app_host,
port=config.app_port,
reload=config.debug,
log_level=config.log_level.lower(),
log_config=LOG_CONFIG
)
if __name__ == "__main__":
main()