Coverage for .nox/test-3-9/lib/python3.9/site-packages/nskit/common/logging/logger.py: 55%
42 statements
« prev ^ index » next coverage.py v7.4.2, created at 2024-02-25 17:38 +0000
« prev ^ index » next coverage.py v7.4.2, created at 2024-02-25 17:38 +0000
1"""Logger Adaptor with JSON and extra handling."""
2from functools import wraps
3from logging import LoggerAdapter
5from logzero import setup_logger
7from .config import DEFAULT_LOGLEVEL
10class Logger(LoggerAdapter):
11 """LoggerAdapter to handle extra variables nicely for common logging."""
13 def process(self, msg, kwargs):
14 """Process the extra variables.
16 Add any extra kwargs into the record as a sub-dictionary called extra for the log.
17 Also add exc_info into the record if provided.
18 """
19 exc_info = kwargs.pop('exc_info', None)
20 kwargs['extra'] = kwargs.get('extra', {})
21 extra = self.extra.copy()
22 extra.update(kwargs.pop('extra', {}))
23 extra.update(kwargs)
24 return msg, {'extra': {'extra': extra}, 'exc_info': exc_info}
26 def log_return(self, msg=None, level=DEFAULT_LOGLEVEL, **logger_kwargs):
27 """Return a decorator which logs the outputs of a function."""
29 def wrapper_factory(fn):
30 """Build the wrapper."""
32 @wraps(fn)
33 def wrapper(*args, **kwargs):
34 nonlocal msg, logger_kwargs
35 if msg is None:
36 msg = fn.__qualname__
37 result = fn(*args, **kwargs)
38 getattr(self, level.lower())(msg, result=result, **logger_kwargs)
39 return result
41 return wrapper
43 return wrapper_factory
45 def log_inputs(self, msg=None, level=DEFAULT_LOGLEVEL, **logger_kwargs):
46 """Return a decorator which logs the inputs of a function."""
48 def wrapper_factory(fn):
50 @wraps(fn)
51 def wrapper(*args, **kwargs):
52 nonlocal msg, logger_kwargs
53 if msg is None:
54 msg = fn.__qualname__
55 getattr(self, level.lower())(msg, inputs=(args, kwargs), **logger_kwargs)
56 return fn(*args, **kwargs)
58 return wrapper
60 return wrapper_factory
63def get_logger(name, config=None, **kwargs):
64 """Get the logger object.
66 You can set the json flag for json logging (or this can be set globally for all logs if required, using the LOG_JSON env var.).
67 """
68 if config is None:
69 config = {}
70 if isinstance(config, dict):
71 from .config import LoggingConfig
72 logging_config = LoggingConfig(**config)
73 else:
74 logging_config = config
75 logger = setup_logger(name, **logging_config.model_dump(by_alias=True, exclude={'format_string', 'extra'}), **kwargs)
76 return Logger(logger, extra=logging_config.extra)