-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlogging_config.py
More file actions
126 lines (105 loc) · 6.48 KB
/
Copy pathlogging_config.py
File metadata and controls
126 lines (105 loc) · 6.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# https://github.com/MartyshWin/config_logging.git
import logging
import traceback
class ColoredFormatter(logging.Formatter):
"""
Конфиг для логирования с поддержкой цветного вывода.
"""
# Цветовые коды ANSI для уровней логирования
COLORS: dict[str, str] = {
"DEBUG": "\033[94m", # Синий
"INFO": "\033[92m", # Зеленый
"SUCCESS": "\033[96m", # Ярко-голубой (Добавили новый уровень логирования)
"WARNING": "\033[93m", # Желтый
"ERROR": "\033[91m", # Красный
"CRITICAL": "\033[95m" # Фиолетовый
}
TIME_COLOR = FILENAME_COLOR = LINENO_COLOR = "\033[97m" # Белый
RESET = "\033[0m" # Сброс цвета
def format(self, record: logging.LogRecord) -> str:
"""
Собирает итоговую строку лога с цветами и «человеческим» расположением
частей сообщения.
Алгоритм по шагам
-----------------
1. ts ― дата-время события
* self.formatTime() берёт formatTime из базового Formatter.
* self.datefmt задаётся при создании ColoredFormatter
(у вас это "%Y-%m-%d %H:%M:%S").
* TIME_COLOR / RESET — ANSI-коды белого текста и сброса цвета.
2. lvl ― уровень логирования
* record.levelname — строка "DEBUG", "INFO", …
* По levelname достаём цвет из словаря COLORS.
* Окружая levelname скобками «(INFO)», делаем его более заметным.
3. file ― откуда пришло сообщение
* record.filename — файл, где вызвали логгер.
* record.lineno — номер строки.
* FILENAME_COLOR и LINENO_COLOR тоже белые, чтобы не спорили с lvl.
4. msg ― само сообщение
* record.getMessage() корректно подставит все %-форматные аргументы
или f-строки, переданные в logger.info(...).
* Для консистентности красим текст тем же цветом, что и уровень.
5. exc ― traceback (если был передан exc_info)
* traceback.format_exception() превращает кортеж exc_info
в список строк с переносами.
* Склеиваем, красим «ошибочным» цветом (красным) и добавляем \n
перед первым символом, чтобы стек оказался на новой строке.
6. Возврат
* Склеиваем всё одним f-string:
┌ ts ────────────────────┐
│ 2025-06-13 22:10:01 │
└────────────────────────┘
--- ← визуальный разделитель
(INFO) ← lvl
[main.py:42] ← файл и строка
== ← ещё один разделитель
Заголовок сообщения ← msg
\nTraceback … (если есть) ← exc
"""
ts = f"{self.TIME_COLOR}{self.formatTime(record, self.datefmt)}{self.RESET}" # Форматируем время
lvl = f"{self.COLORS.get(record.levelname, self.RESET)}({record.levelname}){self.RESET}" # Получаем цвет для уровня логирования
file = f"[{self.FILENAME_COLOR}{record.filename}{self.RESET}:{self.LINENO_COLOR}{record.lineno}{self.RESET}]" # Форматируем уровень, имя файла и номер строки с цветами
msg = record.getMessage()
msg = f"{self.COLORS.get(record.levelname, self.RESET)}{msg}{self.RESET}"
exc = ""
if record.exc_info: # Получаем сообщение, учитывая сложные аргументы
exc_lines = traceback.format_exception(*record.exc_info)
exc = f"\n{self.COLORS['ERROR']}{''.join(exc_lines).strip()}{self.RESET}"
return f"{ts} --- {lvl} {file} == {msg}{exc}"
def add_success_level() -> None:
"""
Добавляем новый уровень (SUCCESS) к стандартному модулю logging.
"""
SUCCESS_LEVEL: int = 25 # Уровень между INFO (20) и WARNING (30)
logging.addLevelName(SUCCESS_LEVEL, "SUCCESS")
def success(self, message, *args, **kwargs):
if self.isEnabledFor(SUCCESS_LEVEL):
self._log(SUCCESS_LEVEL, message, args, **kwargs)
logging.Logger.success = success
def setup_logger():
"""
Настраивает логгер с цветным выводом.
"""
add_success_level() # Добавляем уровень SUCCESS
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
# Создаем консольный обработчик
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
# Настраиваем цветной вывод
formatter = ColoredFormatter(
"%(message)s", # Выводим только сообщение (сформированное вручную в `ColoredFormatter`)
datefmt="%Y-%m-%d %H:%M:%S" # Формат даты
)
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
# Использования уровней логирования (Примеры)
if __name__ == "__main__":
setup_logger()
logger = logging.getLogger(__name__)
logger.debug("Это отладочное сообщение.")
logger.info("Это информационное сообщение.")
logger.success("Это сообщение об успехе!") # Наш добавленный уровень
logger.warning("Это предупреждение.")
logger.error("Это сообщение об ошибке.")
logger.critical("Это критическое сообщение.")