Skip to content

Commit

Permalink
refactor: Improve loggers patching
Browse files Browse the repository at this point in the history
  • Loading branch information
pawamoy committed Dec 31, 2021
1 parent aa1fce3 commit f4b262a
Showing 1 changed file with 43 additions and 6 deletions.
49 changes: 43 additions & 6 deletions src/griffe/logger.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
"""This module contains logging utilities.
We provide the [`get_logger`][griffe.logger.get_logger]
function so dependant libraries can patch it as they see fit.
We provide the [`patch_loggers`][griffe.logger.patch_loggers]
function so dependant libraries can patch loggers as they see fit.
For example, to fit in the MkDocs logging configuration
and prefix each log message with the module name:
```python
import logging
from griffe import logger as griffe_logger
from griffe import logger as patch_loggers
class LoggerAdapter(logging.LoggerAdapter):
def __init__(self, prefix, logger):
Expand All @@ -18,19 +19,46 @@ def __init__(self, prefix, logger):
def process(self, msg, kwargs):
return f"{self.prefix}: {msg}", kwargs
def get_logger(name):
logger = logging.getLogger(f"mkdocs.plugins.{name}")
return LoggerAdapter(name, logger)
griffe_logger.get_logger = get_logger
patch_loggers(get_logger)
```
""" # noqa: P102

from __future__ import annotations

import logging
from typing import Any, Callable


class _Logger:
_default_logger: Any = logging.getLogger
_instances: dict[str, _Logger] = {}

def __init__(self, name: str):
# default logger that can be patched by third-party
self._logger = self.__class__._default_logger(name) # noqa: WPS437
# register instance
self._instances[name] = self

def __getattr__(self, name: str) -> Any:
# forward everything to the logger
return getattr(self._logger, name)

@classmethod
def _patch_loggers(cls, get_logger_func):
# patch current instances
for name, instance in cls._instances.items():
instance._logger = get_logger_func(name) # noqa: WPS437
# future instances will be patched as well
cls._default_logger = get_logger_func

def get_logger(name: str) -> logging.Logger:

def get_logger(name: str) -> _Logger:
"""Create and return a new logger instance.
Parameters:
Expand All @@ -39,4 +67,13 @@ def get_logger(name: str) -> logging.Logger:
Returns:
The logger.
"""
return logging.getLogger(name)
return _Logger(name)


def patch_loggers(get_logger_func: Callable[[str], Any]) -> None:
"""Patch loggers.
Parameters:
get_logger_func: A function accepting a name as parameter and returning a logger.
"""
_Logger._patch_loggers(get_logger_func) # noqa: WPS437

0 comments on commit f4b262a

Please sign in to comment.