Python日志记录过滤器级别到流

Python Logging Filter Levels to Streams

我正在为我的包设置一个记录器。

我有一个简单的模块,它只启动某些日志处理程序和格式。

  • 文件处理程序
  • 控制台处理程序(拆分为stderr和stdout)
  • 我还设置了一些格式和过滤器。我的过滤器有问题。
  • 我想要有两个处理程序,一个过滤掉信息和调试消息(对于stderr流),另一个过滤掉警告和以上(留下信息和调试)

我不确定我是否正确设置了筛选类。我得到的这个错误对我来说不是很清楚:

1
TypeError: unbound method filter() must be called with STDErrFilter instance as first argument (got LogRecord instance instead)

这是我的密码,提前谢谢!:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import os
import sys
import logging
import tempfile

class STDOutFilter(logging.Filter):
    def filter(self, record):
        return record.levelno == logging.INFO | record.levelno == logging.DEBUG

class STDErrFilter(logging.Filter):
    def filter(self, record):
        return not record.levelno == logging.INFO | record.levelno == logging.DEBUG


def start_logbook(log_path=None, log_formatting=None, std_formatting=None, debug=False, clear_previous=True, ):

    log_level = logging.INFO if not debug else logging.DEBUG
    stdout_level = logging.INFO if not debug else logging.DEBUG

    logger  = logging.getLogger()
    logger.setLevel(log_level)
    log_path = log_path

    if log_path:

        folder, filename = os.path.split(log_path)

        if folder and not os.path.exists(folder):
            raise IOError("path {0} does not exist!".format(folder))

    else:
        # Setup Temp Log
        log_path = tempfile.NamedTemporaryFile(prefix='tempLog'+'_log_', suffix='.log')

    # Add File Handlers
    file_handler = logging.FileHandler(log_path)
    if clear_previous:
        file_handler = logging.FileHandler(log_path, mode='w')

    file_formatting = logging.Formatter('[%(asctime)s] %(levelname)-8s --- %(filename)s - %(funcName)s [%(lineno)d] - %(message)s',"%Y-%m-%d %H:%M:%S")
    file_handler.setFormatter(file_formatting)

    # Add Console Handler
    error_console_handler = logging.StreamHandler(stream=sys.stderr)
    error_console_handler.setLevel(stdout_level)
    error_console_handler.addFilter(STDErrFilter)

    info_console_handler = logging.StreamHandler(stream=sys.stdout)
    info_console_handler.setLevel(stdout_level)
    info_console_handler.addFilter(STDOutFilter)


    console_formatting = logging.Formatter('%(levelname)-8s --- %(message)s')
    error_console_handler.setFormatter(console_formatting)
    info_console_handler.setFormatter(console_formatting)

    logger.addHandler(error_console_handler)
    logger.addHandler(info_console_handler)
    logger.addHandler(file_handler)

    return {'log_filepath': os.path.abspath(log_path), 'handlers':[error_console_handler, info_console_handler, file_handler]}



if __name__ == '__main__':
    info = start_logbook("test.log", debug=True)

    log = logging.getLogger("Test Run")

    log.debug("Debug Message goes Here")
    log.info("INFO Message goes Here")
    log.warning("WARNING Message goes Here")
    log.error("ERROR Message goes Here")
    log.critical("Critical Message goes Here")
    log.exception(ValueError("Blarg"))


    logging.shutdown(info['handlers'])


我想到了,愚蠢的错误。当我添加过滤器而不是传递实例化的对象时,我需要在代码中实例化类。

1
2
3
4
5
6
7
8
# Add Console Handler
error_console_handler = logging.StreamHandler(stream=sys.stderr)
error_console_handler.setLevel(stdout_level)
error_console_handler.addFilter(STDErrFilter()) # Problem was here I needed ()

info_console_handler = logging.StreamHandler(stream=sys.stdout)
info_console_handler.setLevel(stdout_level)
info_console_handler.addFilter(STDOutFilter()) # Problem was here! Needed ()