Skip to content

Instantly share code, notes, and snippets.

@Amgarak
Last active July 12, 2024 18:39
Show Gist options
  • Save Amgarak/63e093a122d149e5c265114afd8d6ae4 to your computer and use it in GitHub Desktop.
Save Amgarak/63e093a122d149e5c265114afd8d6ae4 to your computer and use it in GitHub Desktop.

Логгер с поддержкой цветов ANSI для Python

Этот модуль представляет собой простой логгер для Python с поддержкой цветов ANSI в терминале Windows. Он позволяет настраивать уровни логирования и формат вывода для различных типов сообщений.


Установка

Не требует дополнительной установки. Просто скопируйте файл logger_manager.py в свой проект.


Использование

Создание и настройка логгера

from logger_manager import LoggerManager, logging

Создание менеджера логгера с именем и уровнем по умолчанию

logger_manager = LoggerManager('MainLogger', logging.DEBUG)


Включение и отключение логирования

logger_manager.disable_logging() - Отключение логирования

logger_manager.enable_logging() - Включение логирования


Установка уровня логирования

logger_manager.set_level('INFO') - Установка уровня логирования на INFO


Логирование сообщений

logger = logger_manager.logger

logger.debug("debug message")

logger.info("info message")

logger.warning("warning message")

logger.error("error message")

logger.critical("critical message")


Обработка некорректного уровня логирования

logger_manager.set_level('INVALID_LEVEL') - Выдаст сообщение об ошибке


Форматы сообщений

Логгер поддерживает различные цветовые кодировки для разных уровней логирования:

DEBUG: зелёный

INFO: пурпурный

WARNING: жёлтый

ERROR: красный

CRITICAL: голубой


Зависимости

Необходимы модули Python: logging, os, platform.


import logging
import platform
# Определение операционной системы
os_name = platform.system()
# Дополнительная проверка для ОС Windows
if os_name == "Windows":
import os
# Это для включения цвета в терминале Windows
os.system('color')
class CustomFormatter(logging.Formatter):
COLORS = {
"black" : "\x1b[30m",
"red" : "\x1b[31m",
"green" : "\x1b[32m",
"yellow" : "\x1b[33m",
"blue" : "\x1b[34m",
"magenta" : "\x1b[35m",
"cyan" : "\x1b[36m",
"white" : "\x1b[37m",
"reset": "\x1b[0m"
}
FORMATS = {
logging.DEBUG: COLORS["green"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.INFO: COLORS["magenta"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.WARNING: COLORS["yellow"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.ERROR: COLORS["red"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.CRITICAL: COLORS["cyan"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"]
}
def __init__(self):
super().__init__(fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
def format(self, record):
log_fmt = self.FORMATS.get(record.levelno)
if log_fmt:
self._style._fmt = log_fmt
return super().format(record)
class LoggerManager:
def __init__(self, name, level=logging.DEBUG, log_to_file=False, file_name='app.log'):
if not isinstance(name, str) or not name.strip():
print(f"Некорректное имя логгера: '{name}'. Устанавливается имя по умолчанию 'DefaultLogger'.")
name = "DefaultLogger"
self.logger = logging.getLogger(name)
self.logger.setLevel(level)
self.console_handler = None
self.file_handler = None
self.log_filter = None
self.setup_console_handler(level)
if log_to_file:
self.setup_file_handler(level, file_name)
def setup_console_handler(self, level):
"""Настройка консольного обработчика и форматтера"""
self.console_handler = logging.StreamHandler()
self.console_handler.setLevel(level)
self.console_handler.setFormatter(CustomFormatter())
self.logger.addHandler(self.console_handler)
def setup_file_handler(self, level, file_name):
"""Настройка файлового обработчика и форматтера"""
self.file_handler = logging.FileHandler(file_name)
self.file_handler.setLevel(level)
file_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
self.file_handler.setFormatter(file_formatter)
self.logger.addHandler(self.file_handler)
def enable_logging(self):
"""Включение логирования"""
self.logger.disabled = False
print("Логирование включено")
def disable_logging(self):
"""Отключение логирования"""
self.logger.disabled = True
print("Логирование отключено")
def enable_file_logging(self, file_name='app.log'):
"""Включение логирования в файл"""
if not self.file_handler:
self.setup_file_handler(self.logger.level, file_name)
print(f"Логирование в файл '{file_name}' включено")
def disable_file_logging(self):
"""Отключение логирования в файл"""
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.file_handler = None
print("Логирование в файл отключено")
def set_level(self, level):
"""Установка уровня логирования"""
level_mapping = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL
}
if level in level_mapping:
self.logger.setLevel(level_mapping[level])
if self.console_handler:
self.console_handler.setLevel(level_mapping[level])
if self.file_handler:
self.file_handler.setLevel(level_mapping[level])
print(f"Уровень логирования установлен на {level}")
else:
print(f"Некорректный уровень логирования: {level}. Используйте один из: {list(level_mapping.keys())}")
def set_filter(self, level):
"""Установка фильтра для логирования"""
class LevelFilter(logging.Filter):
def __init__(self, level):
self.level = level
def filter(self, record):
return record.levelno == self.level
level_mapping = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL
}
if level in level_mapping:
self.log_filter = LevelFilter(level_mapping[level])
self.logger.addFilter(self.log_filter)
print(f"Фильтр уровня логирования установлен на {level}")
else:
print(f"Некорректный уровень фильтра: {level}. Используйте один из: {list(level_mapping.keys())}")
def clear_filter(self):
"""Очистка установленного фильтра"""
if self.log_filter:
self.logger.removeFilter(self.log_filter)
self.log_filter = None
print("Фильтр логирования очищен")
if __name__ == "__main__":
# Создание менеджера логгера
logger_manager = LoggerManager("TestLogger", logging.INFO, log_to_file=True)
# Пример использования интерфейса для включения и отключения логгирования
logger_manager.disable_logging() # Отключение логирования
logger_manager.enable_logging() # Включение логирования
# Включение и отключение логирования в файл
logger_manager.enable_file_logging("app.log")
logger_manager.disable_file_logging()
# Установка уровня логирования
logger_manager.set_level('INFO') # Установка уровня логирования на INFO
# Установка и очистка фильтра
logger_manager.set_filter('INFO') # Фильтрация сообщений только уровня INFO
logger_manager.clear_filter() # Очистка установленного фильтра
# Логирование сообщений
logger = logger_manager.logger
logger.debug("debug message") # Не будет отображено, так как уровень установлен на INFO
logger.info("info message")
logger.warning("warning message")
logger.error("error message")
logger.critical("critical message")
# Пример некорректного уровня логирования
logger_manager.set_level('INVALID_LEVEL') # Выдаст сообщение об ошибке
import platform
import os
import inspect
import logging
import logging.handlers
from datetime import datetime
from typing import List, Optional
# Дополнительная проверка для ОС Windows
if platform.system() == "Windows":
os.system('color')
class CustomFormatter(logging.Formatter):
COLORS = {
"black" : "\x1b[30m",
"red" : "\x1b[31m",
"green" : "\x1b[32m",
"yellow" : "\x1b[33m",
"blue" : "\x1b[34m",
"magenta" : "\x1b[35m",
"cyan" : "\x1b[36m",
"white" : "\x1b[37m",
"reset": "\x1b[0m"
}
FORMATS = {
logging.DEBUG: COLORS["green"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.INFO: COLORS["magenta"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.WARNING: COLORS["yellow"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.ERROR: COLORS["red"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.CRITICAL: COLORS["cyan"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"]
}
def __init__(self):
super().__init__(fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
def format(self, record: logging.LogRecord) -> str:
log_fmt = self.FORMATS.get(record.levelno)
if log_fmt:
self._style._fmt = log_fmt
return super().format(record)
@classmethod
def set_format(cls, level: str, format_string: str):
"""Устанавливает форматирование для заданного уровня логирования."""
log_level = getattr(logging, level.upper(), None)
if log_level is not None:
cls.FORMATS[log_level] = format_string
else:
raise ValueError(f"Некорректный уровень логирования: {level}")
class MultiLevelFilter(logging.Filter):
def __init__(self, levels: List[int]):
self.levels = levels
def filter(self, record: logging.LogRecord) -> bool:
return record.levelno in self.levels
class LevelFilter(logging.Filter):
def __init__(self, level: int):
self.level = level
def filter(self, record: logging.LogRecord) -> bool:
return record.levelno == self.level
class LoggerManager:
LEVEL_MAPPING = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL
}
def __init__(self, name: str, level: int = logging.DEBUG, log_to_file: bool = False, file_name: str = 'app.log'):
if not isinstance(name, str) or not name.strip():
print(f"Некорректное имя логгера: '{name}'. Устанавливается имя по умолчанию 'DefaultLogger'.")
name = "DefaultLogger"
self.logger = logging.getLogger(name)
self.logger.setLevel(level)
self.console_handler: Optional[logging.StreamHandler] = None
self.file_handler: Optional[logging.FileHandler] = None
self.log_filter: Optional[logging.Filter] = None
self.setup_console_handler(level)
if log_to_file:
self.setup_file_handler(level, file_name)
def setup_console_handler(self, level: int):
"""Настройка консольного обработчика и форматтера"""
self.console_handler = logging.StreamHandler()
self.console_handler.setLevel(level)
self.console_handler.setFormatter(CustomFormatter())
self.logger.addHandler(self.console_handler)
def setup_file_handler(self, level: int, file_name: str):
"""Настройка обработчика с ротацией файлов"""
try:
self.file_handler = logging.handlers.RotatingFileHandler(
file_name,
maxBytes = 1024*1024, # Максимальный размер файла (1MB)
#maxBytes = 1024, # Максимальный размер файла (1кб)
backupCount = 5 # Количество ротируемых файлов
)
self.file_handler.setLevel(level)
file_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
self.file_handler.setFormatter(file_formatter)
self.logger.addHandler(self.file_handler)
except Exception as e:
self.logger.error(f"Ошибка при настройке файлового логгера с ротацией: {e}")
raise
def enable_console_logging(self):
"""Включение логирования в консоль"""
if self.console_handler:
self.console_handler.setLevel(self.logger.level)
self.logger.info("Логирование в консоль включено")
def disable_console_logging(self):
"""Отключение логирования в консоль"""
if self.console_handler:
self.console_handler.setLevel(logging.CRITICAL + 1) # Уровень выше CRITICAL, чтобы игнорировать все сообщения
self.logger.info("Логирование в консоль отключено")
else:
self.logger.warning("Обработчик консольного логирования уже отключен или не был инициализирован")
def enable_logging(self):
"""Включение логирования"""
self.logger.disabled = False
self.logger.info("Логирование включено")
def disable_logging(self):
"""Отключение логирования"""
self.logger.disabled = True
self.logger.info("Логирование отключено")
def enable_file_logging(self, file_name: str = 'app.log', log_dir: str = 'logs'):
try:
if not os.path.exists(log_dir):
os.makedirs(log_dir)
except Exception as e:
self.logger.error(f"Ошибка при создании директории для логов: {e}")
raise
log_path = os.path.join(log_dir, file_name)
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
try:
self.file_handler = logging.handlers.RotatingFileHandler(
log_path,
maxBytes=1024*1024, # Максимальный размер файла (1MB)
backupCount=5 # Количество ротируемых файлов
)
self.file_handler.setLevel(self.logger.level)
file_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
self.file_handler.setFormatter(file_formatter)
self.logger.addHandler(self.file_handler)
self.logger.info(f"Логирование в файл '{log_path}' включено")
except Exception as e:
self.logger.error(f"Ошибка при настройке файлового логгера с ротацией: {e}")
raise
def disable_file_logging(self):
"""Отключение логирования в файл"""
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.file_handler = None
self.logger.info("Логирование в файл отключено")
else:
self.logger.warning("Обработчик файла логирования уже отключен или не был инициализирован")
def set_name(self, name: str):
"""Установка нового имени логгера"""
if not isinstance(name, str) or not name.strip():
self.logger.error(f"Некорректное новое имя логгера: '{name}'. Имя остается без изменений.")
return
self.logger.name = name
self.logger.info(f"Имя логгера изменено на '{name}'")
def set_level(self, level: str):
"""Установка уровня логирования"""
log_level = self.LEVEL_MAPPING.get(level)
if log_level is not None:
self.logger.setLevel(log_level)
if self.console_handler:
self.console_handler.setLevel(log_level)
if self.file_handler:
self.file_handler.setLevel(log_level)
self.logger.info(f"Уровень логирования установлен на {level}")
else:
self.logger.error(f"Некорректный уровень логирования: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def set_filter(self, level: str):
"""Установка фильтра для логирования"""
log_level = self.LEVEL_MAPPING.get(level)
if log_level is not None:
self.clear_filter()
self.log_filter = LevelFilter(log_level)
self.logger.addFilter(self.log_filter)
self.logger.info(f"Фильтр уровня логирования установлен на {level}")
else:
self.logger.error(f"Некорректный уровень фильтра: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def set_filter_list(self, levels: List[str]):
"""Установка списка фильтров для логирования"""
if not levels:
self.logger.error("Список уровней фильтра не должен быть пустым.")
return
valid_levels = [self.LEVEL_MAPPING[level] for level in levels if level in self.LEVEL_MAPPING]
if not valid_levels:
self.logger.error(f"Некорректные уровни фильтра: {levels}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
return
self.clear_filter()
self.log_filter = MultiLevelFilter(valid_levels)
self.logger.addFilter(self.log_filter)
self.logger.info(f"Фильтр уровней логирования установлен на {levels}")
def reset_level(self):
"""Сброс уровня логирования до уровня DEBUG"""
self.set_level('DEBUG')
def clear_filter(self):
"""Очистка установленного фильтра"""
if self.log_filter:
self.logger.removeFilter(self.log_filter)
self.log_filter = None
self.logger.info("Фильтр логирования очищен")
def time_execution(self):
"""Контекстный менеджер для логирования времени выполнения блока кода"""
return TimeExecutionLogger(self.logger)
class TimeExecutionLogger:
def __init__(self, logger, level=logging.INFO):
self.logger = logger
self.level = level
self.start_time = datetime.now()
caller_frame = inspect.stack()[2] # Получаем информацию о вызывающем коде (2 - это индекс фрейма с вызывающим кодом)
self.caller_file = caller_frame.filename
self.caller_line = caller_frame.lineno
self.logger.log(self.level, f"Начало выполнения блока кода в {self.start_time.strftime('%Y-%m-%d %H:%M:%S.%f')}. Вызвано из файла '{self.caller_file}', строка {self.caller_line}")
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
end_time = datetime.now()
execution_time = (end_time - self.start_time).total_seconds()
if exc_type is None:
self.logger.log(self.level, f"Завершение выполнения блока кода в {end_time.strftime('%Y-%m-%d %H:%M:%S.%f')}. Время выполнения: {execution_time:.6f} секунд. Вызвано из файла '{self.caller_file}', строка {self.caller_line}")
else:
self.logger.log(self.level, f"Завершение выполнения блока кода с ошибкой {exc_val} в {end_time.strftime('%Y-%m-%d %H:%M:%S.%f')}. Время выполнения: {execution_time:.6f} секунд. Вызвано из файла '{self.caller_file}', строка {self.caller_line}")
return False # Возвращаем False, чтобы исключение продолжило подъём
if __name__ == "__main__":
import time
#CustomFormatter.set_format('INFO', "%(asctime)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)") # Задать свой формат
logger_manager = LoggerManager("TestLogger")
#logger_manager.enable_console_logging() # Включение логирования в консоль
#logger_manager.disable_console_logging() # Отключение логирования в консоль
#logger_manager.disable_logging() # Отключение логирования
#logger_manager.enable_logging() # Включение логирования
#logger_manager.set_level('INFO') # Установка уровня логирования на INFO
#logger_manager.set_filter_list(['DEBUG' ,'WARNING', 'ERROR' ]) # Установка списка фильтров для логирования
#logger_manager.set_filter('INFO') # Фильтрация сообщений только уровня INFO
#logger_manager.clear_filter() # Очистка установленного фильтра
#logger_manager.reset_level() # Сброс уровня логирования до уровня DEBUG
#logger_manager.set_name("NewNameLogger") # Установка нового имени логгера
with logger_manager.time_execution():
for i in range(6):
# Включение и отключение логирования в файл
logger_manager.enable_file_logging(f"{datetime.now().strftime('%Y-%m-%d %H-%M'),i}.log")
#logger_manager.disable_file_logging()
# Логирование сообщений
logger = logger_manager.logger
logger.debug(f"debug message {i}")
logger.info(f"info message {i}")
logger.warning(f"warning message {i}")
logger.error(f"error message {i}")
logger.critical(f"critical message {i}")
time.sleep(1)
import platform
import os
import inspect
import logging
import logging.handlers
from datetime import datetime
from typing import List, Optional
# Дополнительная проверка для ОС Windows
if platform.system() == "Windows":
os.system('color')
class CustomFormatter(logging.Formatter):
DEFAULT_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)"
FILE_FORMAT = DEFAULT_FORMAT
COLORS = {
"black": "\x1b[30m",
"red": "\x1b[31m",
"green": "\x1b[32m",
"yellow": "\x1b[33m",
"blue": "\x1b[34m",
"magenta": "\x1b[35m",
"cyan": "\x1b[36m",
"white": "\x1b[37m",
"reset": "\x1b[0m"
}
LEVEL_COLORS = {
logging.DEBUG: COLORS["green"],
logging.INFO: COLORS["magenta"],
logging.WARNING: COLORS["yellow"],
logging.ERROR: COLORS["red"],
logging.CRITICAL: COLORS["cyan"]
}
FORMATS = {
logging.DEBUG: LEVEL_COLORS[logging.DEBUG] + DEFAULT_FORMAT + COLORS["reset"],
logging.INFO: LEVEL_COLORS[logging.INFO] + DEFAULT_FORMAT + COLORS["reset"],
logging.WARNING: LEVEL_COLORS[logging.WARNING] + DEFAULT_FORMAT + COLORS["reset"],
logging.ERROR: LEVEL_COLORS[logging.ERROR] + DEFAULT_FORMAT + COLORS["reset"],
logging.CRITICAL: LEVEL_COLORS[logging.CRITICAL] + DEFAULT_FORMAT + COLORS["reset"]
}
def __init__(self):
super().__init__(fmt=CustomFormatter.DEFAULT_FORMAT)
def format(self, record: logging.LogRecord) -> str:
log_fmt = self.FORMATS.get(record.levelno)
if log_fmt:
self._style._fmt = log_fmt
return super().format(record)
@classmethod
def set_file_format(cls, format_string: str):
"""Устанавливает форматирование для файлового логирования."""
if not isinstance(format_string, str):
raise TypeError("Формат должен быть строкой")
cls.FILE_FORMAT = format_string
@classmethod
def set_console_format(cls, level: str, format_string: str):
"""Устанавливает форматирование для заданного уровня логирования."""
log_level = getattr(logging, level.upper(), None)
if log_level is not None:
cls.FORMATS[log_level] = format_string
else:
raise ValueError(f"Некорректный уровень логирования: {level}")
@classmethod
def set_color(cls, level: int, color: str):
"""Устанавливает цвет для заданного уровня логирования."""
log_level = getattr(logging, level.upper(), None)
if log_level in cls.LEVEL_COLORS:
cls.LEVEL_COLORS[log_level] = cls.COLORS[color]
cls.FORMATS[log_level] = cls.LEVEL_COLORS[log_level] + cls.DEFAULT_FORMAT + cls.COLORS["reset"]
else:
raise ValueError(f"Некорректный уровень логирования: {level}")
class MultiLevelFilter(logging.Filter):
def __init__(self, levels: List[int]):
self.levels = levels
def filter(self, record: logging.LogRecord) -> bool:
return record.levelno in self.levels
class LevelFilter(logging.Filter):
def __init__(self, level: int):
self.level = level
def filter(self, record: logging.LogRecord) -> bool:
return record.levelno == self.level
class LoggerManager:
LEVEL_MAPPING = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL
}
def __init__(self, *, name: str, level: int = logging.DEBUG, log_to_file: bool = False, file_name: str = 'app.log', log_dir: str = 'logs'):
if not isinstance(name, str) or not name.strip():
print(f"Некорректное имя логгера: '{name}'. Устанавливается имя по умолчанию 'DefaultLogger'.")
name = "DefaultLogger"
self.logger = logging.getLogger(name)
self.logger.setLevel(level)
self.console_handler: Optional[logging.StreamHandler] = None
self.file_handler: Optional[logging.FileHandler] = None
self.log_filter: Optional[logging.Filter] = None
self.setup_console_handler(level)
if log_to_file:
self.enable_file_logging(level, file_name, log_dir)
def setup_console_handler(self, level: int):
"""Настройка консольного обработчика и форматтера"""
self.console_handler = logging.StreamHandler()
self.console_handler.setLevel(level)
self.console_handler.setFormatter(CustomFormatter())
self.logger.addHandler(self.console_handler)
def enable_console_logging(self):
"""Включение логирования в консоль"""
if self.console_handler:
self.console_handler.setLevel(self.logger.level)
self.logger.info("Логирование в консоль включено")
def disable_console_logging(self):
"""Отключение логирования в консоль"""
if self.console_handler:
self.console_handler.setLevel(logging.CRITICAL + 1) # Уровень выше CRITICAL, чтобы игнорировать все сообщения
self.logger.info("Логирование в консоль отключено")
else:
self.logger.warning("Обработчик консольного логирования уже отключен или не был инициализирован")
def enable_logging(self):
"""Включение логирования"""
self.logger.disabled = False
self.logger.info("Логирование включено")
def disable_logging(self):
"""Отключение логирования"""
self.logger.disabled = True
self.logger.info("Логирование отключено")
def enable_file_logging(self, file_name: str = 'app.log', log_dir: str = 'logs'):
try:
if not os.path.exists(log_dir):
os.makedirs(log_dir)
except Exception as e:
self.logger.error(f"Ошибка при создании директории для логов: {e}")
raise
log_path = os.path.join(log_dir, file_name)
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
try:
self.file_handler = logging.handlers.RotatingFileHandler(
log_path,
maxBytes=1024*1024, # Максимальный размер файла (1MB)
backupCount=5 # Количество ротируемых файлов
)
self.file_handler.setLevel(self.logger.level)
file_formatter = logging.Formatter(CustomFormatter.FILE_FORMAT)
self.file_handler.setFormatter(file_formatter)
self.logger.addHandler(self.file_handler)
self.logger.info(f"Логирование в файл '{log_path}' включено")
except Exception as e:
self.logger.error(f"Ошибка при настройке файлового логгера с ротацией: {e}")
raise
def disable_file_logging(self):
"""Отключение логирования в файл"""
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.file_handler = None
self.logger.info("Логирование в файл отключено")
else:
self.logger.warning("Обработчик файла логирования уже отключен или не был инициализирован")
def set_name(self, name: str):
"""Установка нового имени логгера"""
if not isinstance(name, str) or not name.strip():
self.logger.error(f"Некорректное новое имя логгера: '{name}'. Имя остается без изменений.")
return
self.logger.name = name
self.logger.info(f"Имя логгера изменено на '{name}'")
def set_level(self, level: str):
"""Установка уровня логирования"""
log_level = self.LEVEL_MAPPING.get(level)
if log_level is not None:
self.logger.setLevel(log_level)
if self.console_handler:
self.console_handler.setLevel(log_level)
if self.file_handler:
self.file_handler.setLevel(log_level)
self.logger.info(f"Уровень логирования установлен на {level}")
else:
self.logger.error(f"Некорректный уровень логирования: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def set_filter(self, level: str):
"""Установка фильтра для логирования"""
log_level = self.LEVEL_MAPPING.get(level)
if log_level is not None:
self.clear_filter()
self.log_filter = LevelFilter(log_level)
self.logger.addFilter(self.log_filter)
self.logger.info(f"Фильтр уровня логирования установлен на {level}")
else:
self.logger.error(f"Некорректный уровень фильтра: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def set_filter_list(self, levels: List[str]):
"""Установка списка фильтров для логирования"""
if not levels:
self.logger.error("Список уровней фильтра не должен быть пустым.")
return
valid_levels = [self.LEVEL_MAPPING[level] for level in levels if level in self.LEVEL_MAPPING]
if not valid_levels:
self.logger.error(f"Некорректные уровни фильтра: {levels}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
return
self.clear_filter()
self.log_filter = MultiLevelFilter(valid_levels)
self.logger.addFilter(self.log_filter)
self.logger.info(f"Фильтр уровней логирования установлен на {levels}")
def reset_level(self):
"""Сброс уровня логирования до уровня DEBUG"""
self.set_level('DEBUG')
def clear_filter(self):
"""Очистка установленного фильтра"""
if self.log_filter:
self.logger.removeFilter(self.log_filter)
self.log_filter = None
self.logger.info("Фильтр логирования очищен")
def time_execution(self):
"""Контекстный менеджер для логирования времени выполнения блока кода"""
return TimeExecutionLogger(self.logger)
class TimeExecutionLogger:
def __init__(self, logger, level=logging.INFO):
self.logger = logger
self.level = level
self.start_time = datetime.now()
caller_frame = inspect.stack()[2] # Получаем информацию о вызывающем коде (2 - это индекс фрейма с вызывающим кодом)
self.caller_file = caller_frame.filename
self.caller_line = caller_frame.lineno
self.logger.log(self.level, f"Начало выполнения блока кода в {self.start_time.strftime('%Y-%m-%d %H:%M:%S.%f')}. Вызвано из файла '{self.caller_file}', строка {self.caller_line}")
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
end_time = datetime.now()
execution_time = (end_time - self.start_time).total_seconds()
if exc_type is None:
self.logger.log(self.level, f"Завершение выполнения блока кода в {end_time.strftime('%Y-%m-%d %H:%M:%S.%f')}. Время выполнения: {execution_time:.6f} секунд. Вызвано из файла '{self.caller_file}', строка {self.caller_line}")
else:
self.logger.log(self.level, f"Завершение выполнения блока кода с ошибкой {exc_val} в {end_time.strftime('%Y-%m-%d %H:%M:%S.%f')}. Время выполнения: {execution_time:.6f} секунд. Вызвано из файла '{self.caller_file}', строка {self.caller_line}")
return False # Возвращаем False, чтобы исключение продолжило подъём
if __name__ == "__main__":
import time
#CustomFormatter.set_file_format(f"%(asctime)s") # Задать свой формат
#CustomFormatter.set_console_format('INFO', f"%(asctime)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)") # Задать свой формат
#CustomFormatter.set_color('DEBUG', 'blue') # Задать цвет из доступных
logger_manager = LoggerManager(name = "TestLogger")
#logger_manager.enable_console_logging() # Включение логирования в консоль
#logger_manager.disable_console_logging() # Отключение логирования в консоль
#logger_manager.disable_logging() # Отключение логирования
#logger_manager.enable_logging() # Включение логирования
#logger_manager.set_level('INFO') # Установка уровня логирования на INFO
#logger_manager.set_filter_list(['DEBUG' ,'WARNING', 'ERROR' ]) # Установка списка фильтров для логирования
#logger_manager.set_filter('INFO') # Фильтрация сообщений только уровня INFO
#logger_manager.clear_filter() # Очистка установленного фильтра
#logger_manager.reset_level() # Сброс уровня логирования до уровня DEBUG
#logger_manager.set_name("NewNameLogger") # Установка нового имени логгера
with logger_manager.time_execution():
for i in range(6):
# Включение и отключение логирования в файл
logger_manager.enable_file_logging(f"{datetime.now().strftime('%Y-%m-%d %H-%M'),i}.log")
#logger_manager.disable_file_logging()
# Логирование сообщений
logger = logger_manager.logger
logger.debug(f"debug message {i}")
logger.info(f"info message {i}")
logger.warning(f"warning message {i}")
logger.error(f"error message {i}")
logger.critical(f"critical message {i}")
time.sleep(1)
import platform
import os
import inspect
import logging
import logging.handlers
from datetime import datetime
from typing import List, Optional
# Дополнительная проверка для ОС Windows
if platform.system() == "Windows":
os.system('color')
class CustomFormatter(logging.Formatter):
DEFAULT_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)"
FILE_FORMAT = DEFAULT_FORMAT
COLORS = {
"black": "\x1b[30m",
"red": "\x1b[31m",
"green": "\x1b[32m",
"yellow": "\x1b[33m",
"blue": "\x1b[34m",
"magenta": "\x1b[35m",
"cyan": "\x1b[36m",
"white": "\x1b[37m",
"reset": "\x1b[0m"
}
LEVEL_COLORS = {
logging.DEBUG: COLORS["green"],
logging.INFO: COLORS["magenta"],
logging.WARNING: COLORS["yellow"],
logging.ERROR: COLORS["red"],
logging.CRITICAL: COLORS["cyan"]
}
FORMATS = {
logging.DEBUG: LEVEL_COLORS[logging.DEBUG] + DEFAULT_FORMAT + COLORS["reset"],
logging.INFO: LEVEL_COLORS[logging.INFO] + DEFAULT_FORMAT + COLORS["reset"],
logging.WARNING: LEVEL_COLORS[logging.WARNING] + DEFAULT_FORMAT + COLORS["reset"],
logging.ERROR: LEVEL_COLORS[logging.ERROR] + DEFAULT_FORMAT + COLORS["reset"],
logging.CRITICAL: LEVEL_COLORS[logging.CRITICAL] + DEFAULT_FORMAT + COLORS["reset"]
}
def __init__(self):
super().__init__(fmt=CustomFormatter.DEFAULT_FORMAT)
def format(self, record: logging.LogRecord) -> str:
log_fmt = self.FORMATS.get(record.levelno)
if log_fmt:
self._style._fmt = log_fmt
return super().format(record)
@classmethod
def set_file_format(cls, format_string: str):
"""Устанавливает форматирование для файлового логирования."""
if not isinstance(format_string, str):
raise TypeError("Формат должен быть строкой")
cls.FILE_FORMAT = format_string
@classmethod
def set_console_format(cls, level: str, format_string: str):
"""Устанавливает форматирование для заданного уровня логирования."""
log_level = getattr(logging, level.upper(), None)
if log_level is not None:
cls.FORMATS[log_level] = format_string
else:
raise ValueError(f"Некорректный уровень логирования: {level}")
@classmethod
def set_color(cls, level: int, color: str):
"""Устанавливает цвет для заданного уровня логирования."""
log_level = getattr(logging, level.upper(), None)
if log_level in cls.LEVEL_COLORS:
cls.LEVEL_COLORS[log_level] = cls.COLORS[color]
cls.FORMATS[log_level] = cls.LEVEL_COLORS[log_level] + cls.DEFAULT_FORMAT + cls.COLORS["reset"]
else:
raise ValueError(f"Некорректный уровень логирования: {level}")
class MultiLevelFilter(logging.Filter):
def __init__(self, levels: List[int]):
self.levels = levels
def filter(self, record: logging.LogRecord) -> bool:
return record.levelno in self.levels
class LevelFilter(logging.Filter):
def __init__(self, level: int):
self.level = level
def filter(self, record: logging.LogRecord) -> bool:
return record.levelno == self.level
class LoggerManager:
LEVEL_MAPPING = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL
}
def __init__(self, *, name: str, level: int = logging.DEBUG, log_to_file: bool = False, file_name: str = 'app.log', log_dir: str = 'logs', max_bytes: int = 1024*1024, backup_count: int = 5):
if not isinstance(name, str) or not name.strip():
print(f"Некорректное имя логгера: '{name}'. Устанавливается имя по умолчанию 'DefaultLogger'.")
name = "DefaultLogger"
self.max_bytes = max_bytes
self.backup_count = backup_count
self.logger = logging.getLogger(name)
self.logger.setLevel(level)
self.console_handler: Optional[logging.StreamHandler] = None
self.file_handler: Optional[logging.FileHandler] = None
self.log_filter: Optional[logging.Filter] = None
self.setup_console_handler(level)
if log_to_file:
self.enable_file_logging(level, file_name, log_dir)
def setup_console_handler(self, level: int):
"""Настройка консольного обработчика и форматтера"""
self.console_handler = logging.StreamHandler()
self.console_handler.setLevel(level)
self.console_handler.setFormatter(CustomFormatter())
self.logger.addHandler(self.console_handler)
def enable_console_logging(self):
"""Включение логирования в консоль"""
if self.console_handler:
self.console_handler.setLevel(self.logger.level)
self.logger.info("Логирование в консоль включено")
def disable_console_logging(self):
"""Отключение логирования в консоль"""
if self.console_handler:
self.console_handler.setLevel(logging.CRITICAL + 1) # Уровень выше CRITICAL, чтобы игнорировать все сообщения
self.logger.info("Логирование в консоль отключено")
else:
self.logger.warning("Обработчик консольного логирования уже отключен или не был инициализирован")
def enable_logging(self):
"""Включение логирования"""
self.logger.disabled = False
self.logger.info("Логирование включено")
def disable_logging(self):
"""Отключение логирования"""
self.logger.disabled = True
self.logger.info("Логирование отключено")
def enable_file_logging(self, file_name: str = 'app.log', log_dir: str = 'logs'):
try:
if not os.path.exists(log_dir):
os.makedirs(log_dir)
except Exception as e:
self.logger.error(f"Ошибка при создании директории для логов: {e}")
raise
log_path = os.path.join(log_dir, file_name)
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
try:
self.file_handler = logging.handlers.RotatingFileHandler(
log_path,
self.max_bytes, # Максимальный размер файла
self.backup_count # Количество ротируемых файлов
)
self.file_handler.setLevel(self.logger.level)
file_formatter = logging.Formatter(CustomFormatter.FILE_FORMAT)
self.file_handler.setFormatter(file_formatter)
self.logger.addHandler(self.file_handler)
self.logger.info(f"Логирование в файл '{log_path}' включено")
except Exception as e:
self.logger.error(f"Ошибка при настройке файлового логгера с ротацией: {e}")
raise
def disable_file_logging(self):
"""Отключение логирования в файл"""
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.file_handler = None
self.logger.info("Логирование в файл отключено")
else:
self.logger.warning("Обработчик файла логирования уже отключен или не был инициализирован")
def set_file_handler_params(self, max_bytes: int, backup_count: int):
"""Установка параметров для RotatingFileHandler."""
self.max_bytes = max_bytes
self.backup_count = backup_count
if self.file_handler:
self.file_handler.maxBytes = max_bytes
self.file_handler.backupCount = backup_count
self.logger.info(f"Изменены параметры RotatingFileHandler: maxBytes={max_bytes}, backupCount={backup_count}")
else:
self.logger.warning("Файловый обработчик не инициализирован. Новые параметры будут применены при следующем включении логирования в файл.")
def set_name(self, name: str):
"""Установка нового имени логгера"""
if not isinstance(name, str) or not name.strip():
self.logger.error(f"Некорректное новое имя логгера: '{name}'. Имя остается без изменений.")
return
self.logger.name = name
self.logger.info(f"Имя логгера изменено на '{name}'")
def set_level(self, level: str):
"""Установка уровня логирования"""
log_level = self.LEVEL_MAPPING.get(level)
if log_level is not None:
self.logger.setLevel(log_level)
if self.console_handler:
self.console_handler.setLevel(log_level)
if self.file_handler:
self.file_handler.setLevel(log_level)
self.logger.info(f"Уровень логирования установлен на {level}")
else:
self.logger.error(f"Некорректный уровень логирования: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def set_filter(self, level: str):
"""Установка фильтра для логирования"""
log_level = self.LEVEL_MAPPING.get(level)
if log_level is not None:
self.clear_filter()
self.log_filter = LevelFilter(log_level)
self.logger.addFilter(self.log_filter)
self.logger.info(f"Фильтр уровня логирования установлен на {level}")
else:
self.logger.error(f"Некорректный уровень фильтра: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def set_filter_list(self, levels: List[str]):
"""Установка списка фильтров для логирования"""
if not levels:
self.logger.error("Список уровней фильтра не должен быть пустым.")
return
valid_levels = [self.LEVEL_MAPPING[level] for level in levels if level in self.LEVEL_MAPPING]
if not valid_levels:
self.logger.error(f"Некорректные уровни фильтра: {levels}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
return
self.clear_filter()
self.log_filter = MultiLevelFilter(valid_levels)
self.logger.addFilter(self.log_filter)
self.logger.info(f"Фильтр уровней логирования установлен на {levels}")
def reset_level(self):
"""Сброс уровня логирования до уровня DEBUG"""
self.set_level('DEBUG')
def clear_filter(self):
"""Очистка установленного фильтра"""
if self.log_filter:
self.logger.removeFilter(self.log_filter)
self.log_filter = None
self.logger.info("Фильтр логирования очищен")
def time_execution(self):
"""Контекстный менеджер для логирования времени выполнения блока кода"""
return TimeExecutionLogger(self.logger)
class TimeExecutionLogger:
def __init__(self, logger, level=logging.INFO):
self.logger = logger
self.level = level
self.start_time = datetime.now()
caller_frame = inspect.stack()[2] # Получаем информацию о вызывающем коде (2 - это индекс фрейма с вызывающим кодом)
self.caller_file = caller_frame.filename
self.caller_line = caller_frame.lineno
self.logger.log(self.level, f"Начало выполнения блока кода в {self.start_time.strftime('%Y-%m-%d %H:%M:%S.%f')}. Вызвано из файла '{self.caller_file}', строка {self.caller_line}")
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
end_time = datetime.now()
execution_time = (end_time - self.start_time).total_seconds()
if exc_type is None:
self.logger.log(self.level, f"Завершение выполнения блока кода в {end_time.strftime('%Y-%m-%d %H:%M:%S.%f')}. Время выполнения: {execution_time:.6f} секунд. Вызвано из файла '{self.caller_file}', строка {self.caller_line}")
else:
self.logger.log(self.level, f"Завершение выполнения блока кода с ошибкой {exc_val} в {end_time.strftime('%Y-%m-%d %H:%M:%S.%f')}. Время выполнения: {execution_time:.6f} секунд. Вызвано из файла '{self.caller_file}', строка {self.caller_line}")
return False # Возвращаем False, чтобы исключение продолжило подъём
if __name__ == "__main__":
import time
#CustomFormatter.set_file_format(f"%(asctime)s") # Задать свой формат
#CustomFormatter.set_console_format('INFO', f"%(asctime)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)") # Задать свой формат
#CustomFormatter.set_color('DEBUG', 'blue') # Задать цвет из доступных
logger_manager = LoggerManager(name = "TestLogger")
#logger_manager.set_file_handler_params(max_bytes = 2048*1024, backup_count = 10) # Максимальный размер файла и количество ротируемых файлов
#logger_manager.enable_console_logging() # Включение логирования в консоль
#logger_manager.disable_console_logging() # Отключение логирования в консоль
#logger_manager.disable_logging() # Отключение логирования
#logger_manager.enable_logging() # Включение логирования
#logger_manager.set_level('INFO') # Установка уровня логирования на INFO
#logger_manager.set_filter_list(['DEBUG' ,'WARNING', 'ERROR' ]) # Установка списка фильтров для логирования
#logger_manager.set_filter('INFO') # Фильтрация сообщений только уровня INFO
#logger_manager.clear_filter() # Очистка установленного фильтра
#logger_manager.reset_level() # Сброс уровня логирования до уровня DEBUG
#logger_manager.set_name("NewNameLogger") # Установка нового имени логгера
with logger_manager.time_execution():
for i in range(6):
# Включение и отключение логирования в файл
logger_manager.enable_file_logging(f"{datetime.now().strftime('%Y-%m-%d %H-%M')}-{i}.log")
#logger_manager.disable_file_logging()
# Логирование сообщений
logger = logger_manager.logger
logger.debug(f"debug message {i}")
logger.info(f"info message {i}")
logger.warning(f"warning message {i}")
logger.error(f"error message {i}")
logger.critical(f"critical message {i}")
time.sleep(1)
import logging
import platform
# Determine the operating system
os_name = platform.system()
# Additional check for Windows OS
if os_name == "Windows":
import os
# This is to enable color in the Windows terminal
os.system('color')
class CustomFormatter(logging.Formatter):
COLORS = {
"black": "\x1b[30m",
"red": "\x1b[31m",
"green": "\x1b[32m",
"yellow": "\x1b[33m",
"blue": "\x1b[34m",
"magenta": "\x1b[35m",
"cyan": "\x1b[36m",
"white": "\x1b[37m",
"reset": "\x1b[0m"
}
FORMATS = {
logging.DEBUG: COLORS["green"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.INFO: COLORS["magenta"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.WARNING: COLORS["yellow"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.ERROR: COLORS["red"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.CRITICAL: COLORS["cyan"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"]
}
def __init__(self):
super().__init__(fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
def format(self, record):
log_fmt = self.FORMATS.get(record.levelno)
if log_fmt:
self._style._fmt = log_fmt
return super().format(record)
class LoggerManager:
def __init__(self, name, level=logging.DEBUG, log_to_file=False, file_name='app.log'):
if not isinstance(name, str) or not name.strip():
print(f"Invalid logger name: '{name}'. Defaulting to 'DefaultLogger'.")
name = "DefaultLogger"
self.logger = logging.getLogger(name)
self.logger.setLevel(level)
self.console_handler = None
self.file_handler = None
self.log_filter = None
self.setup_console_handler(level)
if log_to_file:
self.setup_file_handler(level, file_name)
def setup_console_handler(self, level):
"""Setup console handler and formatter"""
self.console_handler = logging.StreamHandler()
self.console_handler.setLevel(level)
self.console_handler.setFormatter(CustomFormatter())
self.logger.addHandler(self.console_handler)
def setup_file_handler(self, level, file_name):
"""Setup file handler and formatter"""
self.file_handler = logging.FileHandler(file_name)
self.file_handler.setLevel(level)
file_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
self.file_handler.setFormatter(file_formatter)
self.logger.addHandler(self.file_handler)
def enable_logging(self):
"""Enable logging"""
self.logger.disabled = False
print("Logging enabled")
def disable_logging(self):
"""Disable logging"""
self.logger.disabled = True
print("Logging disabled")
def enable_file_logging(self, file_name='app.log'):
"""Enable logging to file"""
if not self.file_handler:
self.setup_file_handler(self.logger.level, file_name)
print(f"File logging enabled to '{file_name}'")
def disable_file_logging(self):
"""Disable logging to file"""
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.file_handler = None
print("File logging disabled")
def set_level(self, level):
"""Set logging level"""
level_mapping = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL
}
if level in level_mapping:
self.logger.setLevel(level_mapping[level])
if self.console_handler:
self.console_handler.setLevel(level_mapping[level])
if self.file_handler:
self.file_handler.setLevel(level_mapping[level])
print(f"Logging level set to {level}")
else:
print(f"Invalid logging level: {level}. Use one of: {list(level_mapping.keys())}")
def set_filter(self, level):
"""Set filter for logging"""
class LevelFilter(logging.Filter):
def __init__(self, level):
self.level = level
def filter(self, record):
return record.levelno == self.level
level_mapping = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL
}
if level in level_mapping:
self.log_filter = LevelFilter(level_mapping[level])
self.logger.addFilter(self.log_filter)
print(f"Logging filter set to {level}")
else:
print(f"Invalid filter level: {level}. Use one of: {list(level_mapping.keys())}")
def clear_filter(self):
"""Clear the set filter"""
if self.log_filter:
self.logger.removeFilter(self.log_filter)
self.log_filter = None
print("Logging filter cleared")
if __name__ == "__main__":
# Create logger manager
logger_manager = LoggerManager("TestLogger", logging.INFO, log_to_file=True)
# Example usage of the interface to enable and disable logging
logger_manager.disable_logging() # Disable logging
logger_manager.enable_logging() # Enable logging
# Enable and disable file logging
logger_manager.enable_file_logging("app.log")
logger_manager.disable_file_logging()
# Set logging level
logger_manager.set_level('INFO') # Set logging level to INFO
# Set filter
logger_manager.set_filter('INFO') # Filter only INFO level messages
logger_manager.clear_filter() # Clear the set filter
# Log messages
logger = logger_manager.logger
logger.debug("debug message") # Will not be displayed because the level is set to INFO
logger.info("info message")
logger.warning("warning message")
logger.error("error message")
logger.critical("critical message")
# Example of invalid logging level
logger_manager.set_level('INVALID_LEVEL') # Will output an error message
import logging
import platform
# Определение операционной системы
os_name = platform.system()
# Дополнительная проверка для ОС Windows
if os_name == "Windows":
import os
# Это для включения цвета в терминале Windows
os.system('color')
class CustomFormatter(logging.Formatter):
COLORS = {
"black" : "\x1b[30m",
"red" : "\x1b[31m",
"green" : "\x1b[32m",
"yellow" : "\x1b[33m",
"blue" : "\x1b[34m",
"magenta" : "\x1b[35m",
"cyan" : "\x1b[36m",
"white" : "\x1b[37m",
"reset": "\x1b[0m"
}
FORMATS = {
logging.DEBUG: COLORS["green"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.INFO: COLORS["magenta"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.WARNING: COLORS["yellow"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.ERROR: COLORS["red"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.CRITICAL: COLORS["cyan"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"]
}
def __init__(self):
super().__init__(fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
def format(self, record):
log_fmt = self.FORMATS.get(record.levelno)
if log_fmt:
self._style._fmt = log_fmt
return super().format(record)
class LoggerManager:
def __init__(self, name, level=logging.DEBUG, log_to_file=False, file_name='app.log'):
if not isinstance(name, str) or not name.strip():
print(f"Некорректное имя логгера: '{name}'. Устанавливается имя по умолчанию 'DefaultLogger'.")
name = "DefaultLogger"
self.logger = logging.getLogger(name)
self.logger.setLevel(level)
self.console_handler = None
self.file_handler = None
self.log_filter = None
self.setup_console_handler(level)
if log_to_file:
self.setup_file_handler(level, file_name)
def setup_console_handler(self, level):
"""Настройка консольного обработчика и форматтера"""
self.console_handler = logging.StreamHandler()
self.console_handler.setLevel(level)
self.console_handler.setFormatter(CustomFormatter())
self.logger.addHandler(self.console_handler)
def setup_file_handler(self, level, file_name):
"""Настройка файлового обработчика и форматтера"""
self.file_handler = logging.FileHandler(file_name)
self.file_handler.setLevel(level)
file_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
self.file_handler.setFormatter(file_formatter)
self.logger.addHandler(self.file_handler)
def enable_logging(self):
"""Включение логирования"""
self.logger.disabled = False
print("Логирование включено")
def disable_logging(self):
"""Отключение логирования"""
self.logger.disabled = True
print("Логирование отключено")
def enable_file_logging(self, file_name='app.log'):
"""Включение логирования в файл"""
# Удаляем предыдущий файловый обработчик, если он существует
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.setup_file_handler(self.logger.level, file_name)
print(f"Логирование в файл '{file_name}' включено")
def disable_file_logging(self):
"""Отключение логирования в файл"""
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.file_handler = None
print("Логирование в файл отключено")
def set_level(self, level):
"""Установка уровня логирования"""
level_mapping = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL
}
if level in level_mapping:
self.logger.setLevel(level_mapping[level])
if self.console_handler:
self.console_handler.setLevel(level_mapping[level])
if self.file_handler:
self.file_handler.setLevel(level_mapping[level])
print(f"Уровень логирования установлен на {level}")
else:
print(f"Некорректный уровень логирования: {level}. Используйте один из: {list(level_mapping.keys())}")
def set_filter(self, level):
"""Установка фильтра для логирования"""
class LevelFilter(logging.Filter):
def __init__(self, level):
self.level = level
def filter(self, record):
return record.levelno == self.level
level_mapping = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL
}
if level in level_mapping:
self.log_filter = LevelFilter(level_mapping[level])
self.logger.addFilter(self.log_filter)
print(f"Фильтр уровня логирования установлен на {level}")
else:
print(f"Некорректный уровень фильтра: {level}. Используйте один из: {list(level_mapping.keys())}")
def clear_filter(self):
"""Очистка установленного фильтра"""
if self.log_filter:
self.logger.removeFilter(self.log_filter)
self.log_filter = None
print("Фильтр логирования очищен")
if __name__ == "__main__":
logger_manager = LoggerManager("TestLogger")
#logger_manager.disable_logging() # Отключение логирования
logger_manager.enable_logging() # Включение логирования
#logger_manager.set_level('INFO') # Установка уровня логирования на INFO
#logger_manager.set_filter('INFO') # Фильтрация сообщений только уровня INFO
#logger_manager.clear_filter() # Очистка установленного фильтра
for i in range(6):
# Включение и отключение логирования в файл
logger_manager.enable_file_logging(f"app{i}.log")
#logger_manager.disable_file_logging()
# Логирование сообщений
logger = logger_manager.logger
logger.debug(f"debug message {i}") # Не будет отображено, так как уровень установлен на INFO
logger.info(f"info message {i}")
logger.warning(f"warning message {i}")
logger.error(f"error message {i}")
logger.critical(f"critical message {i}")
import logging
import platform
import time
import datetime
# Дополнительная проверка для ОС Windows
if platform.system() == "Windows":
import os
# Это для включения цвета в терминале Windows
os.system('color')
class CustomFormatter(logging.Formatter):
COLORS = {
"black" : "\x1b[30m",
"red" : "\x1b[31m",
"green" : "\x1b[32m",
"yellow" : "\x1b[33m",
"blue" : "\x1b[34m",
"magenta" : "\x1b[35m",
"cyan" : "\x1b[36m",
"white" : "\x1b[37m",
"reset": "\x1b[0m"
}
FORMATS = {
logging.DEBUG: COLORS["green"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.INFO: COLORS["magenta"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.WARNING: COLORS["yellow"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.ERROR: COLORS["red"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.CRITICAL: COLORS["cyan"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"]
}
def __init__(self):
super().__init__(fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
def format(self, record):
log_fmt = self.FORMATS.get(record.levelno)
if log_fmt:
self._style._fmt = log_fmt
return super().format(record)
class LoggerManager:
LEVEL_MAPPING = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL
}
def __init__(self, name, level=logging.DEBUG, log_to_file=False, file_name='app.log'):
if not isinstance(name, str) or not name.strip():
print(f"Некорректное имя логгера: '{name}'. Устанавливается имя по умолчанию 'DefaultLogger'.")
name = "DefaultLogger"
self.logger = logging.getLogger(name)
self.logger.setLevel(level)
self.console_handler = None
self.file_handler = None
self.log_filter = None
self.setup_console_handler(level)
if log_to_file:
self.setup_file_handler(level, file_name)
def setup_console_handler(self, level):
"""Настройка консольного обработчика и форматтера"""
self.console_handler = logging.StreamHandler()
self.console_handler.setLevel(level)
self.console_handler.setFormatter(CustomFormatter())
self.logger.addHandler(self.console_handler)
def setup_file_handler(self, level, file_name):
"""Настройка файлового обработчика и форматтера"""
self.file_handler = logging.FileHandler(file_name)
self.file_handler.setLevel(level)
file_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
self.file_handler.setFormatter(file_formatter)
self.logger.addHandler(self.file_handler)
def enable_logging(self):
"""Включение логирования"""
self.logger.disabled = False
print("Логирование включено")
def disable_logging(self):
"""Отключение логирования"""
self.logger.disabled = True
print("Логирование отключено")
def enable_file_logging(self, file_name='app.log'):
"""Включение логирования в файл"""
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.setup_file_handler(self.logger.level, file_name)
print(f"Логирование в файл '{file_name}' включено")
def disable_file_logging(self):
"""Отключение логирования в файл"""
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.file_handler = None
print("Логирование в файл отключено")
def set_level(self, level):
"""Установка уровня логирования"""
if level in self.LEVEL_MAPPING:
self.logger.setLevel(self.LEVEL_MAPPING[level])
if self.console_handler:
self.console_handler.setLevel(self.LEVEL_MAPPING[level])
if self.file_handler:
self.file_handler.setLevel(self.LEVEL_MAPPING[level])
print(f"Уровень логирования установлен на {level}")
else:
print(f"Некорректный уровень логирования: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def set_filter(self, level):
"""Установка фильтра для логирования"""
class LevelFilter(logging.Filter):
def __init__(self, level):
self.level = level
def filter(self, record):
return record.levelno == self.level
if level in self.LEVEL_MAPPING:
self.log_filter = LevelFilter(self.LEVEL_MAPPING[level])
self.logger.addFilter(self.log_filter)
print(f"Фильтр уровня логирования установлен на {level}")
else:
print(f"Некорректный уровень фильтра: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def clear_filter(self):
"""Очистка установленного фильтра"""
if self.log_filter:
self.logger.removeFilter(self.log_filter)
self.log_filter = None
print("Фильтр логирования очищен")
if __name__ == "__main__":
logger_manager = LoggerManager("TestLogger")
#logger_manager.disable_logging() # Отключение логирования
logger_manager.enable_logging() # Включение логирования
#logger_manager.set_level('INFO') # Установка уровня логирования на INFO
#logger_manager.set_filter('INFO') # Фильтрация сообщений только уровня INFO
#logger_manager.clear_filter() # Очистка установленного фильтра
for i in range(6):
# Включение и отключение логирования в файл
logger_manager.enable_file_logging(f"logs/{datetime.datetime.now().strftime('%Y-%m-%d %H-%M'),i}.log")
#logger_manager.disable_file_logging()
# Логирование сообщений
logger = logger_manager.logger
logger.debug(f"debug message {i}")
logger.info(f"info message {i}")
logger.warning(f"warning message {i}")
logger.error(f"error message {i}")
logger.critical(f"critical message {i}")
time.sleep(1)
import logging
import platform
from typing import Optional
# Дополнительная проверка для ОС Windows
if platform.system() == "Windows":
import os
os.system('color')
class CustomFormatter(logging.Formatter):
COLORS = {
"black" : "\x1b[30m",
"red" : "\x1b[31m",
"green" : "\x1b[32m",
"yellow" : "\x1b[33m",
"blue" : "\x1b[34m",
"magenta" : "\x1b[35m",
"cyan" : "\x1b[36m",
"white" : "\x1b[37m",
"reset": "\x1b[0m"
}
FORMATS = {
logging.DEBUG: COLORS["green"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.INFO: COLORS["magenta"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.WARNING: COLORS["yellow"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.ERROR: COLORS["red"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.CRITICAL: COLORS["cyan"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"]
}
def __init__(self):
super().__init__(fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
def format(self, record: logging.LogRecord) -> str:
log_fmt = self.FORMATS.get(record.levelno)
if log_fmt:
self._style._fmt = log_fmt
return super().format(record)
class LoggerManager:
LEVEL_MAPPING = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL
}
def __init__(self, name: str, level: int = logging.DEBUG, log_to_file: bool = False, file_name: str = 'app.log'):
if not isinstance(name, str) or not name.strip():
print(f"Некорректное имя логгера: '{name}'. Устанавливается имя по умолчанию 'DefaultLogger'.")
name = "DefaultLogger"
self.logger = logging.getLogger(name)
self.logger.setLevel(level)
self.console_handler: Optional[logging.StreamHandler] = None
self.file_handler: Optional[logging.FileHandler] = None
self.log_filter: Optional[logging.Filter] = None
self.setup_console_handler(level)
if log_to_file:
self.setup_file_handler(level, file_name)
def setup_console_handler(self, level: int):
"""Настройка консольного обработчика и форматтера"""
self.console_handler = logging.StreamHandler()
self.console_handler.setLevel(level)
self.console_handler.setFormatter(CustomFormatter())
self.logger.addHandler(self.console_handler)
def setup_file_handler(self, level: int, file_name: str):
"""Настройка файлового обработчика и форматтера"""
try:
self.file_handler = logging.FileHandler(file_name)
self.file_handler.setLevel(level)
file_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
self.file_handler.setFormatter(file_formatter)
self.logger.addHandler(self.file_handler)
except Exception as e:
self.logger.error(f"Ошибка при настройке файлового логгера: {e}")
def enable_logging(self):
"""Включение логирования"""
self.logger.disabled = False
self.logger.info("Логирование включено")
def disable_logging(self):
"""Отключение логирования"""
self.logger.disabled = True
self.logger.info("Логирование отключено")
def enable_file_logging(self, file_name: str = 'app.log'):
"""Включение логирования в файл"""
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.setup_file_handler(self.logger.level, file_name)
self.logger.info(f"Логирование в файл '{file_name}' включено")
def disable_file_logging(self):
"""Отключение логирования в файл"""
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.file_handler = None
self.logger.info("Логирование в файл отключено")
def set_level(self, level: str):
"""Установка уровня логирования"""
if level in self.LEVEL_MAPPING:
self.logger.setLevel(self.LEVEL_MAPPING[level])
if self.console_handler:
self.console_handler.setLevel(self.LEVEL_MAPPING[level])
if self.file_handler:
self.file_handler.setLevel(self.LEVEL_MAPPING[level])
self.logger.info(f"Уровень логирования установлен на {level}")
else:
self.logger.error(f"Некорректный уровень логирования: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def set_filter(self, level: str):
"""Установка фильтра для логирования"""
class LevelFilter(logging.Filter):
def __init__(self, level: int):
self.level = level
def filter(self, record: logging.LogRecord) -> bool:
return record.levelno == self.level
if level in self.LEVEL_MAPPING:
self.log_filter = LevelFilter(self.LEVEL_MAPPING[level])
self.logger.addFilter(self.log_filter)
self.logger.info(f"Фильтр уровня логирования установлен на {level}")
else:
self.logger.error(f"Некорректный уровень фильтра: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def clear_filter(self):
"""Очистка установленного фильтра"""
if self.log_filter:
self.logger.removeFilter(self.log_filter)
self.log_filter = None
self.logger.info("Фильтр логирования очищен")
if __name__ == "__main__":
import time
import datetime
logger_manager = LoggerManager("TestLogger")
#logger_manager.disable_logging() # Отключение логирования
logger_manager.enable_logging() # Включение логирования
logger_manager.set_level('INFO') # Установка уровня логирования на INFO
#logger_manager.set_filter('INFO') # Фильтрация сообщений только уровня INFO
#logger_manager.clear_filter() # Очистка установленного фильтра
for i in range(6):
# Включение и отключение логирования в файл
logger_manager.enable_file_logging(f"logs/{datetime.datetime.now().strftime('%Y-%m-%d %H-%M'),i}.log")
#logger_manager.disable_file_logging()
# Логирование сообщений
logger = logger_manager.logger
logger.debug(f"debug message {i}")
logger.info(f"info message {i}")
logger.warning(f"warning message {i}")
logger.error(f"error message {i}")
logger.critical(f"critical message {i}")
time.sleep(1)
import logging
import platform
from typing import List, Optional
# Дополнительная проверка для ОС Windows
if platform.system() == "Windows":
import os
os.system('color')
class CustomFormatter(logging.Formatter):
COLORS = {
"black" : "\x1b[30m",
"red" : "\x1b[31m",
"green" : "\x1b[32m",
"yellow" : "\x1b[33m",
"blue" : "\x1b[34m",
"magenta" : "\x1b[35m",
"cyan" : "\x1b[36m",
"white" : "\x1b[37m",
"reset": "\x1b[0m"
}
FORMATS = {
logging.DEBUG: COLORS["green"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.INFO: COLORS["magenta"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.WARNING: COLORS["yellow"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.ERROR: COLORS["red"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.CRITICAL: COLORS["cyan"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"]
}
def __init__(self):
super().__init__(fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
def format(self, record: logging.LogRecord) -> str:
log_fmt = self.FORMATS.get(record.levelno)
if log_fmt:
self._style._fmt = log_fmt
return super().format(record)
class MultiLevelFilter(logging.Filter):
def __init__(self, levels: List[int]):
self.levels = levels
def filter(self, record: logging.LogRecord) -> bool:
return record.levelno in self.levels
class LevelFilter(logging.Filter):
def __init__(self, level: int):
self.level = level
def filter(self, record: logging.LogRecord) -> bool:
return record.levelno == self.level
class LoggerManager:
LEVEL_MAPPING = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL
}
def __init__(self, name: str, level: int = logging.DEBUG, log_to_file: bool = False, file_name: str = 'app.log'):
if not isinstance(name, str) or not name.strip():
print(f"Некорректное имя логгера: '{name}'. Устанавливается имя по умолчанию 'DefaultLogger'.")
name = "DefaultLogger"
self.logger = logging.getLogger(name)
self.logger.setLevel(level)
self.console_handler: Optional[logging.StreamHandler] = None
self.file_handler: Optional[logging.FileHandler] = None
self.log_filter: Optional[logging.Filter] = None
self.setup_console_handler(level)
if log_to_file:
self.setup_file_handler(level, file_name)
def setup_console_handler(self, level: int):
"""Настройка консольного обработчика и форматтера"""
self.console_handler = logging.StreamHandler()
self.console_handler.setLevel(level)
self.console_handler.setFormatter(CustomFormatter())
self.logger.addHandler(self.console_handler)
def setup_file_handler(self, level: int, file_name: str):
"""Настройка файлового обработчика и форматтера"""
try:
self.file_handler = logging.FileHandler(file_name)
self.file_handler.setLevel(level)
file_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
self.file_handler.setFormatter(file_formatter)
self.logger.addHandler(self.file_handler)
except Exception as e:
self.logger.error(f"Ошибка при настройке файлового логгера: {e}")
raise
def enable_logging(self):
"""Включение логирования"""
self.logger.disabled = False
self.logger.info("Логирование включено")
def disable_logging(self):
"""Отключение логирования"""
self.logger.disabled = True
self.logger.info("Логирование отключено")
def enable_file_logging(self, file_name: str = 'app.log'):
"""Включение логирования в файл"""
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.setup_file_handler(self.logger.level, file_name)
self.logger.info(f"Логирование в файл '{file_name}' включено")
def disable_file_logging(self):
"""Отключение логирования в файл"""
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.file_handler = None
self.logger.info("Логирование в файл отключено")
def set_level(self, level: str):
"""Установка уровня логирования"""
if level in self.LEVEL_MAPPING:
self.logger.setLevel(self.LEVEL_MAPPING[level])
if self.console_handler:
self.console_handler.setLevel(self.LEVEL_MAPPING[level])
if self.file_handler:
self.file_handler.setLevel(self.LEVEL_MAPPING[level])
self.logger.info(f"Уровень логирования установлен на {level}")
else:
self.logger.error(f"Некорректный уровень логирования: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def set_filter(self, level: str):
"""Установка фильтра для логирования"""
if level in self.LEVEL_MAPPING:
self.clear_filter()
self.log_filter = LevelFilter(self.LEVEL_MAPPING[level])
self.logger.addFilter(self.log_filter)
self.logger.info(f"Фильтр уровня логирования установлен на {level}")
else:
self.logger.error(f"Некорректный уровень фильтра: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def set_filter_list(self, levels: List[str]):
"""Установка списка фильтров для логирования"""
if not levels:
self.logger.error("Список уровней фильтра не должен быть пустым.")
return
valid_levels = [self.LEVEL_MAPPING[level] for level in levels if level in self.LEVEL_MAPPING]
if not valid_levels:
self.logger.error(f"Некорректные уровни фильтра: {levels}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
return
self.clear_filter()
self.log_filter = MultiLevelFilter(valid_levels)
self.logger.addFilter(self.log_filter)
self.logger.info(f"Фильтр уровней логирования установлен на {levels}")
def reset_level(self):
"""Сброс уровня логирования до уровня DEBUG"""
self.set_level('DEBUG')
def clear_filter(self):
"""Очистка установленного фильтра"""
if self.log_filter:
self.logger.removeFilter(self.log_filter)
self.log_filter = None
self.logger.info("Фильтр логирования очищен")
if __name__ == "__main__":
import time
import datetime
logger_manager = LoggerManager("TestLogger")
#logger_manager.disable_logging() # Отключение логирования
logger_manager.enable_logging() # Включение логирования
#logger_manager.set_level('INFO') # Установка уровня логирования на INFO
#logger_manager.set_filter_list(['DEBUG' ,'WARNING', 'ERROR' ]) # Установка списка фильтров для логирования
#logger_manager.set_filter('INFO') # Фильтрация сообщений только уровня INFO
#logger_manager.clear_filter() # Очистка установленного фильтра
#logger_manager.reset_level() # Сброс уровня логирования до уровня DEBUG
for i in range(6):
# Включение и отключение логирования в файл
logger_manager.enable_file_logging(f"logs/{datetime.datetime.now().strftime('%Y-%m-%d %H-%M'),i}.log")
#logger_manager.disable_file_logging()
# Логирование сообщений
logger = logger_manager.logger
logger.debug(f"debug message {i}")
logger.info(f"info message {i}")
logger.warning(f"warning message {i}")
logger.error(f"error message {i}")
logger.critical(f"critical message {i}")
time.sleep(1)
import logging
import logging.handlers
import platform
import os
from typing import List, Optional
# Дополнительная проверка для ОС Windows
if platform.system() == "Windows":
os.system('color')
class CustomFormatter(logging.Formatter):
COLORS = {
"black" : "\x1b[30m",
"red" : "\x1b[31m",
"green" : "\x1b[32m",
"yellow" : "\x1b[33m",
"blue" : "\x1b[34m",
"magenta" : "\x1b[35m",
"cyan" : "\x1b[36m",
"white" : "\x1b[37m",
"reset": "\x1b[0m"
}
FORMATS = {
logging.DEBUG: COLORS["green"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.INFO: COLORS["magenta"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.WARNING: COLORS["yellow"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.ERROR: COLORS["red"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.CRITICAL: COLORS["cyan"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"]
}
def __init__(self):
super().__init__(fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
def format(self, record: logging.LogRecord) -> str:
log_fmt = self.FORMATS.get(record.levelno)
if log_fmt:
self._style._fmt = log_fmt
return super().format(record)
class MultiLevelFilter(logging.Filter):
def __init__(self, levels: List[int]):
self.levels = levels
def filter(self, record: logging.LogRecord) -> bool:
return record.levelno in self.levels
class LevelFilter(logging.Filter):
def __init__(self, level: int):
self.level = level
def filter(self, record: logging.LogRecord) -> bool:
return record.levelno == self.level
class LoggerManager:
LEVEL_MAPPING = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL
}
def __init__(self, name: str, level: int = logging.DEBUG, log_to_file: bool = False, file_name: str = 'app.log'):
if not isinstance(name, str) or not name.strip():
print(f"Некорректное имя логгера: '{name}'. Устанавливается имя по умолчанию 'DefaultLogger'.")
name = "DefaultLogger"
self.logger = logging.getLogger(name)
self.logger.setLevel(level)
self.console_handler: Optional[logging.StreamHandler] = None
self.file_handler: Optional[logging.FileHandler] = None
self.log_filter: Optional[logging.Filter] = None
self.setup_console_handler(level)
if log_to_file:
self.setup_file_handler(level, file_name)
def setup_console_handler(self, level: int):
"""Настройка консольного обработчика и форматтера"""
self.console_handler = logging.StreamHandler()
self.console_handler.setLevel(level)
self.console_handler.setFormatter(CustomFormatter())
self.logger.addHandler(self.console_handler)
def setup_file_handler(self, level: int, file_name: str):
"""Настройка обработчика с ротацией файлов"""
try:
self.file_handler = logging.handlers.RotatingFileHandler(
file_name,
maxBytes=1024*1024, # Максимальный размер файла (1MB)
#maxBytes=1024, # Максимальный размер файла (1кб)
backupCount=5 # Количество ротируемых файлов
)
self.file_handler.setLevel(level)
file_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
self.file_handler.setFormatter(file_formatter)
self.logger.addHandler(self.file_handler)
except Exception as e:
self.logger.error(f"Ошибка при настройке файлового логгера с ротацией: {e}")
raise
def enable_logging(self):
"""Включение логирования"""
self.logger.disabled = False
self.logger.info("Логирование включено")
def disable_logging(self):
"""Отключение логирования"""
self.logger.disabled = True
self.logger.info("Логирование отключено")
def enable_file_logging(self, file_name: str = 'app.log', log_dir: str = 'logs'):
if not os.path.exists(log_dir):
os.makedirs(log_dir)
log_path = os.path.join(log_dir, file_name)
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.setup_file_handler(self.logger.level, log_path)
self.logger.info(f"Логирование в файл '{log_path}' включено")
def disable_file_logging(self):
"""Отключение логирования в файл"""
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.file_handler = None
self.logger.info("Логирование в файл отключено")
def set_level(self, level: str):
"""Установка уровня логирования"""
if level in self.LEVEL_MAPPING:
self.logger.setLevel(self.LEVEL_MAPPING[level])
if self.console_handler:
self.console_handler.setLevel(self.LEVEL_MAPPING[level])
if self.file_handler:
self.file_handler.setLevel(self.LEVEL_MAPPING[level])
self.logger.info(f"Уровень логирования установлен на {level}")
else:
self.logger.error(f"Некорректный уровень логирования: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def set_filter(self, level: str):
"""Установка фильтра для логирования"""
if level in self.LEVEL_MAPPING:
self.clear_filter()
self.log_filter = LevelFilter(self.LEVEL_MAPPING[level])
self.logger.addFilter(self.log_filter)
self.logger.info(f"Фильтр уровня логирования установлен на {level}")
else:
self.logger.error(f"Некорректный уровень фильтра: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def set_filter_list(self, levels: List[str]):
"""Установка списка фильтров для логирования"""
if not levels:
self.logger.error("Список уровней фильтра не должен быть пустым.")
return
valid_levels = [self.LEVEL_MAPPING[level] for level in levels if level in self.LEVEL_MAPPING]
if not valid_levels:
self.logger.error(f"Некорректные уровни фильтра: {levels}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
return
self.clear_filter()
self.log_filter = MultiLevelFilter(valid_levels)
self.logger.addFilter(self.log_filter)
self.logger.info(f"Фильтр уровней логирования установлен на {levels}")
def reset_level(self):
"""Сброс уровня логирования до уровня DEBUG"""
self.set_level('DEBUG')
def clear_filter(self):
"""Очистка установленного фильтра"""
if self.log_filter:
self.logger.removeFilter(self.log_filter)
self.log_filter = None
self.logger.info("Фильтр логирования очищен")
if __name__ == "__main__":
import time
import datetime
logger_manager = LoggerManager("TestLogger")
#logger_manager.disable_logging() # Отключение логирования
logger_manager.enable_logging() # Включение логирования
#logger_manager.set_level('INFO') # Установка уровня логирования на INFO
#logger_manager.set_filter_list(['DEBUG' ,'WARNING', 'ERROR' ]) # Установка списка фильтров для логирования
#logger_manager.set_filter('INFO') # Фильтрация сообщений только уровня INFO
#logger_manager.clear_filter() # Очистка установленного фильтра
#logger_manager.reset_level() # Сброс уровня логирования до уровня DEBUG
for i in range(6):
# Включение и отключение логирования в файл
logger_manager.enable_file_logging(f"{datetime.datetime.now().strftime('%Y-%m-%d %H-%M'),i}.log")
#logger_manager.disable_file_logging()
# Логирование сообщений
logger = logger_manager.logger
logger.debug(f"debug message {i}")
logger.info(f"info message {i}")
logger.warning(f"warning message {i}")
logger.error(f"error message {i}")
logger.critical(f"critical message {i}")
time.sleep(1)
import logging
import logging.handlers
import platform
import os
from typing import List, Optional
# Дополнительная проверка для ОС Windows
if platform.system() == "Windows":
os.system('color')
class CustomFormatter(logging.Formatter):
COLORS = {
"black" : "\x1b[30m",
"red" : "\x1b[31m",
"green" : "\x1b[32m",
"yellow" : "\x1b[33m",
"blue" : "\x1b[34m",
"magenta" : "\x1b[35m",
"cyan" : "\x1b[36m",
"white" : "\x1b[37m",
"reset": "\x1b[0m"
}
FORMATS = {
logging.DEBUG: COLORS["green"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.INFO: COLORS["magenta"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.WARNING: COLORS["yellow"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.ERROR: COLORS["red"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.CRITICAL: COLORS["cyan"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"]
}
def __init__(self):
super().__init__(fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
def format(self, record: logging.LogRecord) -> str:
log_fmt = self.FORMATS.get(record.levelno)
if log_fmt:
self._style._fmt = log_fmt
return super().format(record)
class MultiLevelFilter(logging.Filter):
def __init__(self, levels: List[int]):
self.levels = levels
def filter(self, record: logging.LogRecord) -> bool:
return record.levelno in self.levels
class LevelFilter(logging.Filter):
def __init__(self, level: int):
self.level = level
def filter(self, record: logging.LogRecord) -> bool:
return record.levelno == self.level
class LoggerManager:
LEVEL_MAPPING = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL
}
def __init__(self, name: str, level: int = logging.DEBUG, log_to_file: bool = False, file_name: str = 'app.log'):
if not isinstance(name, str) or not name.strip():
print(f"Некорректное имя логгера: '{name}'. Устанавливается имя по умолчанию 'DefaultLogger'.")
name = "DefaultLogger"
self.logger = logging.getLogger(name)
self.logger.setLevel(level)
self.console_handler: Optional[logging.StreamHandler] = None
self.file_handler: Optional[logging.FileHandler] = None
self.log_filter: Optional[logging.Filter] = None
self.setup_console_handler(level)
if log_to_file:
self.setup_file_handler(level, file_name)
def setup_console_handler(self, level: int):
"""Настройка консольного обработчика и форматтера"""
self.console_handler = logging.StreamHandler()
self.console_handler.setLevel(level)
self.console_handler.setFormatter(CustomFormatter())
self.logger.addHandler(self.console_handler)
def setup_file_handler(self, level: int, file_name: str):
"""Настройка обработчика с ротацией файлов"""
try:
self.file_handler = logging.handlers.RotatingFileHandler(
file_name,
maxBytes=1024*1024, # Максимальный размер файла (1MB)
#maxBytes=1024, # Максимальный размер файла (1кб)
backupCount=5 # Количество ротируемых файлов
)
self.file_handler.setLevel(level)
file_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
self.file_handler.setFormatter(file_formatter)
self.logger.addHandler(self.file_handler)
except Exception as e:
self.logger.error(f"Ошибка при настройке файлового логгера с ротацией: {e}")
raise
def enable_console_logging(self):
"""Включение логирования в консоль"""
if self.console_handler:
self.console_handler.setLevel(self.logger.level)
self.logger.info("Логирование в консоль включено")
def disable_console_logging(self):
"""Отключение логирования в консоль"""
if self.console_handler:
self.console_handler.setLevel(logging.CRITICAL + 1) # Уровень выше CRITICAL, чтобы игнорировать все сообщения
self.logger.info("Логирование в консоль отключено")
def enable_logging(self):
"""Включение логирования"""
self.logger.disabled = False
self.logger.info("Логирование включено")
def disable_logging(self):
"""Отключение логирования"""
self.logger.disabled = True
self.logger.info("Логирование отключено")
def enable_file_logging(self, file_name: str = 'app.log', log_dir: str = 'logs'):
if not os.path.exists(log_dir):
os.makedirs(log_dir)
log_path = os.path.join(log_dir, file_name)
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.setup_file_handler(self.logger.level, log_path)
self.logger.info(f"Логирование в файл '{log_path}' включено")
def disable_file_logging(self):
"""Отключение логирования в файл"""
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.file_handler = None
self.logger.info("Логирование в файл отключено")
def set_level(self, level: str):
"""Установка уровня логирования"""
if level in self.LEVEL_MAPPING:
self.logger.setLevel(self.LEVEL_MAPPING[level])
if self.console_handler:
self.console_handler.setLevel(self.LEVEL_MAPPING[level])
if self.file_handler:
self.file_handler.setLevel(self.LEVEL_MAPPING[level])
self.logger.info(f"Уровень логирования установлен на {level}")
else:
self.logger.error(f"Некорректный уровень логирования: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def set_filter(self, level: str):
"""Установка фильтра для логирования"""
if level in self.LEVEL_MAPPING:
self.clear_filter()
self.log_filter = LevelFilter(self.LEVEL_MAPPING[level])
self.logger.addFilter(self.log_filter)
self.logger.info(f"Фильтр уровня логирования установлен на {level}")
else:
self.logger.error(f"Некорректный уровень фильтра: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def set_filter_list(self, levels: List[str]):
"""Установка списка фильтров для логирования"""
if not levels:
self.logger.error("Список уровней фильтра не должен быть пустым.")
return
valid_levels = [self.LEVEL_MAPPING[level] for level in levels if level in self.LEVEL_MAPPING]
if not valid_levels:
self.logger.error(f"Некорректные уровни фильтра: {levels}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
return
self.clear_filter()
self.log_filter = MultiLevelFilter(valid_levels)
self.logger.addFilter(self.log_filter)
self.logger.info(f"Фильтр уровней логирования установлен на {levels}")
def reset_level(self):
"""Сброс уровня логирования до уровня DEBUG"""
self.set_level('DEBUG')
def clear_filter(self):
"""Очистка установленного фильтра"""
if self.log_filter:
self.logger.removeFilter(self.log_filter)
self.log_filter = None
self.logger.info("Фильтр логирования очищен")
if __name__ == "__main__":
import time
import datetime
logger_manager = LoggerManager("TestLogger")
#logger_manager.enable_console_logging() # Включение логирования в консоль
#logger_manager.disable_console_logging() # Отключение логирования в консоль
#logger_manager.disable_logging() # Отключение логирования
#logger_manager.enable_logging() # Включение логирования
#logger_manager.set_level('INFO') # Установка уровня логирования на INFO
#logger_manager.set_filter_list(['DEBUG' ,'WARNING', 'ERROR' ]) # Установка списка фильтров для логирования
#logger_manager.set_filter('INFO') # Фильтрация сообщений только уровня INFO
#logger_manager.clear_filter() # Очистка установленного фильтра
#logger_manager.reset_level() # Сброс уровня логирования до уровня DEBUG
for i in range(6):
# Включение и отключение логирования в файл
logger_manager.enable_file_logging(f"{datetime.datetime.now().strftime('%Y-%m-%d %H-%M'),i}.log")
#logger_manager.disable_file_logging()
# Логирование сообщений
logger = logger_manager.logger
logger.debug(f"debug message {i}")
logger.info(f"info message {i}")
logger.warning(f"warning message {i}")
logger.error(f"error message {i}")
logger.critical(f"critical message {i}")
time.sleep(1)
import logging
import logging.handlers
import platform
import os
from datetime import datetime
from typing import List, Optional
# Дополнительная проверка для ОС Windows
if platform.system() == "Windows":
os.system('color')
class CustomFormatter(logging.Formatter):
COLORS = {
"black" : "\x1b[30m",
"red" : "\x1b[31m",
"green" : "\x1b[32m",
"yellow" : "\x1b[33m",
"blue" : "\x1b[34m",
"magenta" : "\x1b[35m",
"cyan" : "\x1b[36m",
"white" : "\x1b[37m",
"reset": "\x1b[0m"
}
FORMATS = {
logging.DEBUG: COLORS["green"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.INFO: COLORS["magenta"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.WARNING: COLORS["yellow"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.ERROR: COLORS["red"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"],
logging.CRITICAL: COLORS["cyan"] + "%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)" + COLORS["reset"]
}
def __init__(self):
super().__init__(fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
def format(self, record: logging.LogRecord) -> str:
log_fmt = self.FORMATS.get(record.levelno)
if log_fmt:
self._style._fmt = log_fmt
return super().format(record)
class MultiLevelFilter(logging.Filter):
def __init__(self, levels: List[int]):
self.levels = levels
def filter(self, record: logging.LogRecord) -> bool:
return record.levelno in self.levels
class LevelFilter(logging.Filter):
def __init__(self, level: int):
self.level = level
def filter(self, record: logging.LogRecord) -> bool:
return record.levelno == self.level
class LoggerManager:
LEVEL_MAPPING = {
'DEBUG': logging.DEBUG,
'INFO': logging.INFO,
'WARNING': logging.WARNING,
'ERROR': logging.ERROR,
'CRITICAL': logging.CRITICAL
}
def __init__(self, name: str, level: int = logging.DEBUG, log_to_file: bool = False, file_name: str = 'app.log'):
if not isinstance(name, str) or not name.strip():
print(f"Некорректное имя логгера: '{name}'. Устанавливается имя по умолчанию 'DefaultLogger'.")
name = "DefaultLogger"
self.logger = logging.getLogger(name)
self.logger.setLevel(level)
self.console_handler: Optional[logging.StreamHandler] = None
self.file_handler: Optional[logging.FileHandler] = None
self.log_filter: Optional[logging.Filter] = None
self.setup_console_handler(level)
if log_to_file:
self.setup_file_handler(level, file_name)
def setup_console_handler(self, level: int):
"""Настройка консольного обработчика и форматтера"""
self.console_handler = logging.StreamHandler()
self.console_handler.setLevel(level)
self.console_handler.setFormatter(CustomFormatter())
self.logger.addHandler(self.console_handler)
def setup_file_handler(self, level: int, file_name: str):
"""Настройка обработчика с ротацией файлов"""
try:
self.file_handler = logging.handlers.RotatingFileHandler(
file_name,
maxBytes=1024*1024, # Максимальный размер файла (1MB)
#maxBytes=1024, # Максимальный размер файла (1кб)
backupCount=5 # Количество ротируемых файлов
)
self.file_handler.setLevel(level)
file_formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s (%(filename)s:%(lineno)d)")
self.file_handler.setFormatter(file_formatter)
self.logger.addHandler(self.file_handler)
except Exception as e:
self.logger.error(f"Ошибка при настройке файлового логгера с ротацией: {e}")
raise
def enable_console_logging(self):
"""Включение логирования в консоль"""
if self.console_handler:
self.console_handler.setLevel(self.logger.level)
self.logger.info("Логирование в консоль включено")
def disable_console_logging(self):
"""Отключение логирования в консоль"""
if self.console_handler:
self.console_handler.setLevel(logging.CRITICAL + 1) # Уровень выше CRITICAL, чтобы игнорировать все сообщения
self.logger.info("Логирование в консоль отключено")
def enable_logging(self):
"""Включение логирования"""
self.logger.disabled = False
self.logger.info("Логирование включено")
def disable_logging(self):
"""Отключение логирования"""
self.logger.disabled = True
self.logger.info("Логирование отключено")
def enable_file_logging(self, file_name: str = 'app.log', log_dir: str = 'logs'):
if not os.path.exists(log_dir):
os.makedirs(log_dir)
log_path = os.path.join(log_dir, file_name)
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.setup_file_handler(self.logger.level, log_path)
self.logger.info(f"Логирование в файл '{log_path}' включено")
def disable_file_logging(self):
"""Отключение логирования в файл"""
if self.file_handler:
self.logger.removeHandler(self.file_handler)
self.file_handler.close()
self.file_handler = None
self.logger.info("Логирование в файл отключено")
def set_level(self, level: str):
"""Установка уровня логирования"""
if level in self.LEVEL_MAPPING:
self.logger.setLevel(self.LEVEL_MAPPING[level])
if self.console_handler:
self.console_handler.setLevel(self.LEVEL_MAPPING[level])
if self.file_handler:
self.file_handler.setLevel(self.LEVEL_MAPPING[level])
self.logger.info(f"Уровень логирования установлен на {level}")
else:
self.logger.error(f"Некорректный уровень логирования: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def set_filter(self, level: str):
"""Установка фильтра для логирования"""
if level in self.LEVEL_MAPPING:
self.clear_filter()
self.log_filter = LevelFilter(self.LEVEL_MAPPING[level])
self.logger.addFilter(self.log_filter)
self.logger.info(f"Фильтр уровня логирования установлен на {level}")
else:
self.logger.error(f"Некорректный уровень фильтра: {level}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
def set_filter_list(self, levels: List[str]):
"""Установка списка фильтров для логирования"""
if not levels:
self.logger.error("Список уровней фильтра не должен быть пустым.")
return
valid_levels = [self.LEVEL_MAPPING[level] for level in levels if level in self.LEVEL_MAPPING]
if not valid_levels:
self.logger.error(f"Некорректные уровни фильтра: {levels}. Используйте один из: {list(self.LEVEL_MAPPING.keys())}")
return
self.clear_filter()
self.log_filter = MultiLevelFilter(valid_levels)
self.logger.addFilter(self.log_filter)
self.logger.info(f"Фильтр уровней логирования установлен на {levels}")
def reset_level(self):
"""Сброс уровня логирования до уровня DEBUG"""
self.set_level('DEBUG')
def clear_filter(self):
"""Очистка установленного фильтра"""
if self.log_filter:
self.logger.removeFilter(self.log_filter)
self.log_filter = None
self.logger.info("Фильтр логирования очищен")
def time_execution(self):
"""Контекстный менеджер для логирования времени выполнения блока кода"""
return TimeExecutionLogger(self.logger)
class TimeExecutionLogger:
def __init__(self, logger, level=logging.INFO):
self.logger = logger
self.level = level
def __enter__(self):
self.start_time = datetime.now()
self.logger.log(self.level, f"Начало выполнения блока кода в {self.start_time.strftime('%Y-%m-%d %H:%M:%S.%f')}")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
end_time = datetime.now()
execution_time = (end_time - self.start_time).total_seconds()
self.logger.log(self.level, f"Завершение выполнения блока кода в {end_time.strftime('%Y-%m-%d %H:%M:%S.%f')}. Время выполнения: {execution_time:.6f} секунд")
if __name__ == "__main__":
import time
logger_manager = LoggerManager("TestLogger")
#logger_manager.enable_console_logging() # Включение логирования в консоль
#logger_manager.disable_console_logging() # Отключение логирования в консоль
#logger_manager.disable_logging() # Отключение логирования
#logger_manager.enable_logging() # Включение логирования
#logger_manager.set_level('INFO') # Установка уровня логирования на INFO
#logger_manager.set_filter_list(['DEBUG' ,'WARNING', 'ERROR' ]) # Установка списка фильтров для логирования
#logger_manager.set_filter('INFO') # Фильтрация сообщений только уровня INFO
#logger_manager.clear_filter() # Очистка установленного фильтра
#logger_manager.reset_level() # Сброс уровня логирования до уровня DEBUG
with logger_manager.time_execution():
for i in range(6):
# Включение и отключение логирования в файл
logger_manager.enable_file_logging(f"{datetime.now().strftime('%Y-%m-%d %H-%M'),i}.log")
#logger_manager.disable_file_logging()
# Логирование сообщений
logger = logger_manager.logger
logger.debug(f"debug message {i}")
logger.info(f"info message {i}")
logger.warning(f"warning message {i}")
logger.error(f"error message {i}")
logger.critical(f"critical message {i}")
time.sleep(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment