python接口自动化(四十)- logger 日志 - 下(超详解)
发布人:shili8
发布时间:2025-01-07 06:28
阅读次数:0
**Python 接口自动化(四十)- Logger 日志 - 下**
在前面的文章中,我们已经介绍了如何使用 Python 的 `logging` 模块来实现日志功能。然而,实际开发中,我们往往需要更高级的日志管理能力,比如自定义日志格式、多线程安全等。在本文中,我们将继续讨论这些主题。
###1. 自定义日志格式我们可以通过继承 `logging.Formatter` 类来实现自定义日志格式。例如,下面是一个例子:
import loggingclass CustomFormatter(logging.Formatter): def format(self, record): # 日志级别 level = record.levelname # 日志时间 timestamp = record.created # 日志内容 message = record.getMessage() # 自定义日志格式 return f"[{level}] [{timestamp}] {message}" # 创建一个 logger 实例logger = logging.getLogger(__name__) # 设置日志级别logger.setLevel(logging.DEBUG) # 创建一个 handler 实例handler = logging.StreamHandler() # 设置日志格式handler.setFormatter(CustomFormatter()) # 将 handler 添加到 logger 中logger.addHandler(handler) # 测试一下logger.debug("这是一个 debug 日志") logger.info("这是一个 info 日志") logger.warning("这是一个 warning 日志") logger.error("这是一个 error 日志") logger.critical("这是一个 critical 日志")
在这个例子中,我们定义了一个 `CustomFormatter` 类,继承自 `logging.Formatter`。我们重写了 `format` 方法来实现自定义日志格式。在实际开发中,你可以根据自己的需求进行调整。
###2. 多线程安全在多线程环境下,logger 日志可能会出现问题,因为 logger 的 handler 可能会被多个线程同时访问。为了解决这个问题,我们需要使用线程安全的 logger 实现。
Python 中提供了一个 `threading` 模块,可以帮助我们实现线程安全的 logger。例如:
import loggingimport threadingclass ThreadSafeLogger(logging.Logger): def __init__(self, name): super().__init__(name) self._lock = threading.Lock() def debug(self, msg, *args, **kwargs): with self._lock: return super().debug(msg, *args, **kwargs) def info(self, msg, *args, **kwargs): with self._lock: return super().info(msg, *args, **kwargs) def warning(self, msg, *args, **kwargs): with self._lock: return super().warning(msg, *args, **kwargs) def error(self, msg, *args, **kwargs): with self._lock: return super().error(msg, *args, **kwargs) def critical(self, msg, *args, **kwargs): with self._lock: return super().critical(msg, *args, **kwargs) # 创建一个 logger 实例logger = ThreadSafeLogger(__name__) # 设置日志级别logger.setLevel(logging.DEBUG) # 创建一个 handler 实例handler = logging.StreamHandler() # 将 handler 添加到 logger 中logger.addHandler(handler) # 测试一下def test_logger(): logger.debug("这是一个 debug 日志") logger.info("这是一个 info 日志") logger.warning("这是一个 warning 日志") logger.error("这是一个 error 日志") logger.critical("这是一个 critical 日志") # 创建多个线程threads = [] for _ in range(10): thread = threading.Thread(target=test_logger) threads.append(thread) thread.start() # 等待所有线程完成for thread in threads: thread.join()
在这个例子中,我们定义了一个 `ThreadSafeLogger` 类,继承自 `logging.Logger`。我们重写了 logger 的方法来实现线程安全的 logger。在实际开发中,你可以根据自己的需求进行调整。
###3. 日志文件除了使用 `StreamHandler` 之外,我们还可以使用 `FileHandler` 来将日志输出到文件中。例如:
import logging# 创建一个 logger 实例logger = logging.getLogger(__name__) # 设置日志级别logger.setLevel(logging.DEBUG) # 创建一个 file handler 实例file_handler = logging.FileHandler('log.log') # 将 file handler 添加到 logger 中logger.addHandler(file_handler) # 测试一下logger.debug("这是一个 debug 日志") logger.info("这是一个 info 日志") logger.warning("这是一个 warning 日志") logger.error("这是一个 error 日志") logger.critical("这是一个 critical 日志")
在这个例子中,我们使用 `FileHandler` 来将日志输出到 `log.log` 文件中。在实际开发中,你可以根据自己的需求进行调整。
###4. 日志轮转除了使用 `FileHandler` 之外,我们还可以使用 `RotatingFileHandler` 来实现日志轮转。例如:
import logging# 创建一个 logger 实例logger = logging.getLogger(__name__) # 设置日志级别logger.setLevel(logging.DEBUG) # 创建一个 rotating file handler 实例rotating_file_handler = logging.RotatingFileHandler('log.log', maxBytes=1024*1024, backupCount=5) # 将 rotating file handler 添加到 logger 中logger.addHandler(rotating_file_handler) # 测试一下logger.debug("这是一个 debug 日志") logger.info("这是一个 info 日志") logger.warning("这是一个 warning 日志") logger.error("这是一个 error 日志") logger.critical("这是一个 critical 日志")
在这个例子中,我们使用 `RotatingFileHandler` 来实现日志轮转。在实际开发中,你可以根据自己的需求进行调整。
###5. 日志压缩除了使用 `RotatingFileHandler` 之外,我们还可以使用 `TimedRotatingFileHandler` 来实现日志压缩。例如:
import logging# 创建一个 logger 实例logger = logging.getLogger(__name__) # 设置日志级别logger.setLevel(logging.DEBUG) # 创建一个 timed rotating file handler 实例timed_rotating_file_handler = logging.TimedRotatingFileHandler('log.log', when='midnight', interval=1, backupCount=5) # 将 timed rotating file handler 添加到 logger 中logger.addHandler(timed_rotating_file_handler) # 测试一下logger.debug("这是一个 debug 日志") logger.info("这是一个 info 日志") logger.warning("这是一个 warning 日志") logger.error("这是一个 error 日志") logger.critical("这是一个 critical 日志")
在这个例子中,我们使用 `TimedRotatingFileHandler` 来实现日志压缩。在实际开发中,你可以根据自己的需求进行调整。
###6. 日志过滤除了使用 `Filter` 之外,我们还可以使用 `LoggerAdapter` 来实现日志过滤。例如:
import logging# 创建一个 logger 实例logger = logging.getLogger(__name__) # 设置日志级别logger.setLevel(logging.DEBUG) # 创建一个 filter 实例filter_ = logging.Filter() # 将 filter 添加到 logger 中logger.addFilter(filter_) # 测试一下def test_logger(): logger.debug("这是一个 debug 日志") logger.info("这是一个 info 日志") logger.warning("这是一个 warning 日志") logger.error("这是一个 error 日志") logger.critical("这是一个 critical 日志") # 创建一个 logger adapter 实例logger_adapter = logging.LoggerAdapter(logger, {'extra': '日志过滤器'}) # 将 logger adapter 添加到 logger 中logger.addHandler(logger_adapter) # 测试一下test_logger()
在这个例子中,我们使用 `LoggerAdapter` 来实现日志过滤。在实际开发中,你可以根据自己的需求进行调整。
###7. 日志格式化除了使用 `Formatter` 之外,我们还可以使用 `LogRecord` 来实现日志格式化。例如:
import logging# 创建一个 logger 实例logger = logging.getLogger(__name__) # 设置日志级别logger.setLevel(logging.DEBUG) # 创建一个 formatter 实例formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # 将 formatter 添加到 logger 中logger.addHandler(formatter) # 测试一下def test_logger(): logger.debug("这是一个 debug 日志") logger.info("这是一个 info 日志") logger.warning("这是一个 warning 日志") logger.error("这是一个 error 日志") logger.critical("这是一个 critical 日志") # 创建一个 log record 实例log_record = logging.LogRecord(name='logger', level=logging.DEBUG, pathname='/path/to/log', lineno=1, msg='日志内容', args=None, exc_info=None) # 将 log record 添加到 logger 中logger.handle(log_record) # 测试一下test_logger()
在这个例子中,我们使用 `LogRecord` 来实现日志格式化。在实际开发中,你可以根据自己的需求进行调整。
###8. 日志输出除了使用 `Handler` 之外,我们还可以使用 `StreamHandler` 来实现日志输出。例如