Coverage for adrs/logging.py: 38%

39 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-08-29 04:28 +0800

1import logging 

2import colorlog 

3from logging.handlers import TimedRotatingFileHandler 

4 

5from rich.logging import RichHandler 

6 

7from adrs.console import console 

8 

9LOG_FORMAT: str = ( 

10 "%(levelname)s %(name)s %(asctime)-15s %(filename)s:%(lineno)d %(message)s" 

11) 

12 

13 

14def make_colorlog_stream_handler( 

15 log_level: int = logging.INFO, 

16 format: str | None = LOG_FORMAT, 

17 filter: logging.Filter | None = None, 

18) -> logging.Handler: 

19 handler = colorlog.StreamHandler() 

20 handler.setLevel(log_level) 

21 handler.setFormatter(colorlog.ColoredFormatter(f"%(log_color)s{format}")) 

22 if filter is not None: 

23 handler.addFilter(filter) 

24 return handler 

25 

26 

27def make_rich_stream_handler( 

28 log_level: int = logging.INFO, 

29 filter: logging.Filter | None = None, 

30) -> logging.Handler: 

31 handler = RichHandler( 

32 console=console, 

33 show_path=True, 

34 rich_tracebacks=True, 

35 ) 

36 handler.setLevel(log_level) 

37 if filter is not None: 

38 handler.addFilter(filter) 

39 return handler 

40 

41 

42def make_logging_file_handler( 

43 filename: str, 

44 log_level: int = logging.INFO, 

45 format: str | None = LOG_FORMAT, 

46 filter: logging.Filter | None = None, 

47) -> logging.Handler: 

48 handler = logging.FileHandler(filename) 

49 handler.setLevel(log_level) 

50 handler.setFormatter(logging.Formatter(format)) 

51 if filter is not None: 

52 handler.addFilter(filter) 

53 return handler 

54 

55 

56def make_logging_timed_rotating_file_handler( 

57 filename: str, 

58 log_level: int = logging.INFO, 

59 format: str | None = LOG_FORMAT, 

60 filter: logging.Filter | None = None, 

61 when: str = "h", 

62 interval: int = 1, 

63 backupCount: int = 0, 

64 encoding: str | None = None, 

65 delay: bool = False, 

66 utc: bool = False, 

67) -> logging.Handler: 

68 handler = TimedRotatingFileHandler( 

69 filename=filename, 

70 when=when, 

71 interval=interval, 

72 backupCount=backupCount, 

73 encoding=encoding, 

74 delay=delay, 

75 utc=utc, 

76 ) 

77 handler.setLevel(log_level) 

78 handler.setFormatter(logging.Formatter(format)) 

79 if filter is not None: 

80 handler.addFilter(filter) 

81 return handler 

82 

83 

84def setup_logger( 

85 logger: logging.Logger = logging.root, 

86 log_level: int = logging.INFO, 

87 handlers: list[logging.Handler] = [make_rich_stream_handler()], 

88): 

89 logger.setLevel(log_level) 

90 

91 if not logging.root.hasHandlers(): 

92 for handler in handlers: 

93 logging.root.addHandler(handler) 

94 

95 logging.getLogger("httpx").setLevel(logging.WARNING)