You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Python Logger仅记录ERROR级别以下日志?现有实现是否合理?

Is this Python Logger implementation reasonable, and are there better filtering methods?

Great question! Let's start by evaluating your current implementation, then look at a more idiomatic approach using Python's built-in logging tools.

Your Current Implementation: Is It Reasonable?

First off, your code works perfectly for your requirement—it correctly filters out ERROR and higher-level logs, only keeping INFO and WARNING messages. The core logic of overriding StreamHandler.emit() to skip records with level >= logging.ERROR is sound.

That said, there's a minor redundancy worth noting: you've set handl.setLevel(logging.INFO) alongside your custom max_level check. Since your logger is already configured with logger.setLevel(logging.INFO), the handler's level setting ensures it only receives logs at INFO and above. Your emit() method then adds an extra layer to filter out ERROR+ logs. This isn't a bug, but it's a bit unnecessary—you could technically set the handler's level to logging.WARNING (since you want to keep WARNING and below), but again, your current code doesn't break anything.

A More Idiomatic Approach: Using logging.Filter

Python's logging module provides a dedicated Filter class for exactly this kind of log filtering, which aligns better with the module's design principles (separating logging logic into distinct components: loggers, handlers, filters, and formatters). This approach is more flexible, reusable, and readable.

Here's how you can rewrite your code using a custom Filter:

import logging
from logging import StreamHandler, Filter

def get_log_formatter():
    datefmt = '%b %d %y %H:%M:%S'
    formatter = logging.Formatter('%(asctime)s [%(module)s:%(levelname)s] %(message)s', datefmt=datefmt)
    return formatter

# Custom filter to keep logs below a specified max level
class MaxLevelFilter(Filter):
    def __init__(self, max_level):
        self.max_level = max_level

    def filter(self, record):
        # Return True to keep the log, False to discard it
        return record.levelno < self.max_level

# Initialize handler and formatter
handl = StreamHandler()
handl.setLevel(logging.INFO)
handl.setFormatter(get_log_formatter())

# Add the filter to the handler
handl.addFilter(MaxLevelFilter(logging.ERROR))

logger = logging.getLogger("testing_logger")
logger.addHandler(handl)
logger.setLevel(logging.INFO)

Why This Is Better:

  • Separation of concerns: Handlers handle log output, filters handle log filtering. This makes your code more modular—you can reuse the same MaxLevelFilter with any other handler (e.g., a file handler) without rewriting logic.
  • Flexibility: If you ever need to add more filtering rules, you can simply add additional filters to the handler, rather than modifying a custom handler's emit() method.
  • Readability: Other developers familiar with Python's logging module will immediately recognize the filtering logic, instead of having to dig into a custom handler's implementation.

For even simpler cases, you can use a lambda-based filter (no need for a class):

# Lambda filter equivalent to the class above
max_level_filter = Filter(lambda record: record.levelno < logging.ERROR)
handl.addFilter(max_level_filter)

Final Verdict

Your original implementation is valid and achieves your goal. However, using logging.Filter is the more idiomatic, flexible, and maintainable approach for log filtering in Python.

内容的提问来源于stack exchange,提问作者TheDude

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:23:55