123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- import inspect
- import logging
- import os
- from sys import stderr, stdout
- from loguru import logger
- from core import path_conf
- from core.conf import settings
- class InterceptHandler(logging.Handler):
- """
- Default handler from examples in loguru documentation.
- See https://loguru.readthedocs.io/en/stable/overview.html#entirely-compatible-with-standard-logging
- """
- def emit(self, record: logging.LogRecord):
- # Get corresponding Loguru level if it exists
- try:
- level = logger.level(record.levelname).name
- except ValueError:
- level = record.levelno
- # Find caller from where originated the logged message.
- frame, depth = inspect.currentframe(), 0
- while frame and (depth == 0 or frame.f_code.co_filename == logging.__file__):
- frame = frame.f_back
- depth += 1
- logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage())
- def setup_logging():
- """
- From https://pawamoy.github.io/posts/unify-logging-for-a-gunicorn-uvicorn-app/
- https://github.com/pawamoy/pawamoy.github.io/issues/17
- """
- # Intercept everything at the root logger
- logging.root.handlers = [InterceptHandler()]
- logging.root.setLevel(settings.LOG_LEVEL)
- # Remove all log handlers and propagate to root logger
- for name in logging.root.manager.loggerDict.keys():
- logging.getLogger(name).handlers = []
- if 'uvicorn.access' in name or 'watchfiles.main' in name:
- logging.getLogger(name).propagate = False
- else:
- logging.getLogger(name).propagate = True
- logging.debug(f'{logging.getLogger(name)}, {logging.getLogger(name).propagate}')
- # Remove every other logger's handlers
- logger.remove()
- # Configure logger before starts logging
- logger.configure(handlers=[{'sink': stdout, 'level': settings.LOG_LEVEL, 'format': settings.LOG_FORMAT}])
- logger.configure(handlers=[{'sink': stderr, 'level': settings.LOG_LEVEL, 'format': settings.LOG_FORMAT}])
- def set_customize_logfile():
- log_path = path_conf.LOG_DIR
- if not os.path.exists(log_path):
- os.mkdir(log_path)
- # log files
- log_stdout_file = os.path.join(log_path, settings.LOG_STDOUT_FILENAME)
- log_stderr_file = os.path.join(log_path, settings.LOG_STDERR_FILENAME)
- # loguru logger: https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.add
- log_config = {
- 'rotation': '10 MB',
- 'retention': '15 days',
- 'compression': 'tar.gz',
- 'enqueue': True,
- 'format': settings.LOG_FORMAT,
- }
- # stdout
- logger.add(
- log_stdout_file,
- level='INFO',
- filter=lambda record: record['level'].name == 'INFO' or record['level'].no <= 25,
- **log_config,
- backtrace=False,
- diagnose=False,
- )
- # stderr
- logger.add(
- log_stderr_file,
- level='ERROR',
- filter=lambda record: record['level'].name == 'ERROR' or record['level'].no >= 30,
- **log_config,
- backtrace=True,
- diagnose=True,
- )
- log = logger
|