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

1"""Logger Adaptor with JSON and extra handling.""" 

2from functools import wraps 

3from logging import LoggerAdapter 

4 

5from logzero import setup_logger 

6 

7from .config import DEFAULT_LOGLEVEL 

8 

9 

10class Logger(LoggerAdapter): 

11 """LoggerAdapter to handle extra variables nicely for common logging.""" 

12 

13 def process(self, msg, kwargs): 

14 """Process the extra variables. 

15 

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} 

25 

26 def log_return(self, msg=None, level=DEFAULT_LOGLEVEL, **logger_kwargs): 

27 """Return a decorator which logs the outputs of a function.""" 

28 

29 def wrapper_factory(fn): 

30 """Build the wrapper.""" 

31 

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 

40 

41 return wrapper 

42 

43 return wrapper_factory 

44 

45 def log_inputs(self, msg=None, level=DEFAULT_LOGLEVEL, **logger_kwargs): 

46 """Return a decorator which logs the inputs of a function.""" 

47 

48 def wrapper_factory(fn): 

49 

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) 

57 

58 return wrapper 

59 

60 return wrapper_factory 

61 

62 

63def get_logger(name, config=None, **kwargs): 

64 """Get the logger object. 

65 

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)