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
« prev ^ index » next coverage.py v6.5.0, created at 2023-02-09 12:09 +0100
1from __future__ import annotations
3import sys
4from enum import Enum
5from typing import TYPE_CHECKING
7from loguru import logger as logger # re-export
9if TYPE_CHECKING:
10 from loguru import Record
13class LogLevel(Enum):
14 """Enum for log levels."""
16 TRACE = "TRACE"
17 DEBUG = "DEBUG"
18 INFO = "INFO"
19 SUCCESS = "SUCCESS"
20 WARNING = "WARNING"
21 ERROR = "ERROR"
22 CRITICAL = "CRITICAL"
24 @classmethod
25 def _missing_(cls, value: object) -> LogLevel:
26 """Convert string to enum value.
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.")
40 def __str__(self) -> str:
41 """Return the enum value as a string."""
42 return self.value
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}
56CONFIGURED_LOGLEVEL = None # type: str | None
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
75def disable_logging() -> None:
76 """Disable logging."""
77 logger.remove()
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"