Coverage for harbor_cli/logs.py: 68%

40 statements  

« prev     ^ index     » next       coverage.py v6.5.0, created at 2023-02-09 12:09 +0100

1from __future__ import annotations 

2 

3import sys 

4from enum import Enum 

5from typing import TYPE_CHECKING 

6 

7from loguru import logger as logger # re-export 

8 

9if TYPE_CHECKING: 

10 from loguru import Record 

11 

12 

13class LogLevel(Enum): 

14 """Enum for log levels.""" 

15 

16 TRACE = "TRACE" 

17 DEBUG = "DEBUG" 

18 INFO = "INFO" 

19 SUCCESS = "SUCCESS" 

20 WARNING = "WARNING" 

21 ERROR = "ERROR" 

22 CRITICAL = "CRITICAL" 

23 

24 @classmethod 

25 def _missing_(cls, value: object) -> LogLevel: 

26 """Convert string to enum value. 

27 

28 Raises 

29 ------ 

30 ValueError 

31 If the value is not a valid log level. 

32 """ 

33 if not isinstance(value, str): 

34 raise TypeError(f"Expected str, got {type(value)}") 

35 for member in cls: 

36 if member.value == value.upper(): 

37 return member 

38 raise ValueError(f"{value} is not a valid log level.") 

39 

40 def __str__(self) -> str: 

41 """Return the enum value as a string.""" 

42 return self.value 

43 

44 

45COLOR_DEFAULT = "white" 

46COLORS = { 

47 "TRACE": "white", 

48 "DEBUG": "white", 

49 "INFO": "white", 

50 "SUCCESS": "white", 

51 "WARNING": "yellow", 

52 "ERROR": "red", 

53 "CRITICAL": "red", 

54} 

55 

56CONFIGURED_LOGLEVEL = None # type: str | None 

57 

58 

59def setup_logging(level: str | LogLevel = "INFO") -> None: 

60 # Avoid reconfiguring the logger if the level hasn't changed 

61 global CONFIGURED_LOGLEVEL 

62 if level == CONFIGURED_LOGLEVEL: 

63 return 

64 if isinstance(level, LogLevel): 64 ↛ 65line 64 didn't jump to line 65, because the condition on line 64 was never true

65 level = level.value 

66 logger.remove() 

67 logger.add( 

68 sink=sys.stderr, 

69 level=level, 

70 format=_formatter, 

71 ) 

72 CONFIGURED_LOGLEVEL = level 

73 

74 

75def disable_logging() -> None: 

76 """Disable logging.""" 

77 logger.remove() 

78 

79 

80def _formatter(record: Record) -> str: 

81 """Format log messages for Loguru logger.""" 

82 level = record["level"].name 

83 color = COLORS.get(level, COLOR_DEFAULT) 

84 return f"<{color}><bold>[{level}]</bold> {record['message']}</{color}>\n"