【问题标题】:How to set width of combined fields in Python logging如何在 Python 日志记录中设置组合字段的宽度
【发布时间】:2016-02-08 20:23:12
【问题描述】:

在 Python 日志中,有没有办法设置两个组合字段的宽度?

我希望结合文件名和行号来生成类似于以下内容的输出:

2011-10-14 13:47:51 main.py:12       DEBUG - Initializing cluster
2011-10-14 13:47:51 cluster.py:364   DEBUG - Starting cluster
2011-10-14 13:47:51 cluster.py:98    INFO  - Starting simulation
2011-10-14 13:47:51 simulation.py:79 DEBUG - Computing parameters

我将如何修改下面的格式字符串来实现这一点?

logging.Formatter('%(asctime)s %(filename)s:%(lineno)s %(levelname)5s - %(msg)s 

更新:

正如@jonrsharpe 指出的那样,没有开箱即用的方法可以做到这一点,因此请自定义格式。

解决方案:@alecxe 推荐自定义Filter,这里有一个完整的例子:

import logging
import logging.config

class FilenameLinenoFilter(logging.Filter):
    def filter(self, record):
        record.filename_lineno = '{}:{}'.format(record.filename, record.lineno)
        return True

LOG_SETTINGS = {
    'version': 1,
    'filters': {
        'filename_lineno_filter': {
            '()': FilenameLinenoFilter,
        },
    },
    'formatters': {
        'standard': {
            'format': '%(asctime)s %(filename_lineno)-18s %(levelname)5s - %(msg)s',
        },
    },
    'handlers': {
        'default': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'filters': ['filename_lineno_filter'],
            'formatter': 'standard',
            },
    },
    'loggers': {
        '': { 
            'handlers': ['default'],
            'level': 'DEBUG',
        },
    }
}

logging.config.dictConfig(LOG_SETTINGS)
logger = logging.getLogger()
logger.debug('Debug output goes here.')
logger.info('Informational goes here.')

【问题讨论】:

  • AFAIK 没有办法做到这一点,除非你自己接管所有的格式。

标签: python logging formatting


【解决方案1】:

您可以在custom filter 的帮助下创建一个组合字段

import logging

class MyFilter(logging.Filter):
    def filter(self, record):
        record.filename_lineno = "%s:%d" % (record.filename, record.lineno)
        return True

然后,您可以在格式化字符串中引用%(filename_lineno)s 占位符。

【讨论】:

    【解决方案2】:

    Filter 不是适合这项工作的工具 - 过滤器用于决定哪些日志记录被发出,哪些被静音,而不是为了“猴子补丁”而拦截日志记录。

    相反,从 Python 3.2 开始,您可以使用 logging.setRecordFactory 函数注册自定义 LogRecord 子类或工厂函数,为每个 LogRecord 添加自定义属性:

    import logging
    
    class CustomLogRecord(logging.LogRecord):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.origin = f"{self.filename}:{self.lineno}"
    

    然后您可以在记录器的格式字符串中设置此组合字段的宽度:

    logging.setLogRecordFactory(CustomLogRecord)
    logging.basicConfig(
        style='{',
        format="{asctime} {origin:20} {levelname} - {message}",
        level=logging.INFO
    )
    logging.info("Test")
    
    2020-06-26 16:10:03,193 scratch_2.py:16      INFO - Test
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 2018-11-24
      • 2022-12-15
      • 2012-09-24
      • 1970-01-01
      • 2019-11-25
      • 2010-12-08
      相关资源
      最近更新 更多