python只记录特定级别

use*_*462 25 python

我正在使用python日志记录模块在我的python代码中记录事件.我有2个日志文件,我也希望记录,一个包含用户信息,另一个包含更详细的开发日志文件.我已将两个日志记录文件设置为我想要的级别(usr.log = INFO和dev.log = ERROR),但无法解决如何将日志记录限制为usr.log文件,因此只写入INFO级别日志到日志文件而不是INFO加上其他上面的例如INFO,WARNING,ERROR和CRITICAL.

这基本上是我的代码: -

import logging

logger1 = logging.getLogger('')
logger1.addHandler(logging.FileHandler('/home/tmp/usr.log')
logger1.setLevel(logging.INFO)
logger2 = logging.getLogger('')
logger2.addHandler(logging.FileHandler('/home/tmp/dev.log')
logger2.setLevel(logging.ERROR)

logging.critical('this to be logged in dev.log only')
logging.info('this to be logged to usr.log and dev.log')
logging.warning('this to be logged to dev.log only')
Run Code Online (Sandbox Code Playgroud)

任何帮助都会非常感谢你.

srg*_*erg 51

我与大卫达成了一致意见,但我认为还需要说更多.套用公主新娘 -我不认为这代码的含义,你认为它的意思.你的代码有:

logger1 = logging.getLogger('')
...
logger2 = logging.getLogger('')
Run Code Online (Sandbox Code Playgroud)

这意味着logger1并且logger2相同的记录器,因此当您将级别设置logger2为ERROR时,实际上最终会同时设置级别logger1.为了获得两个不同的记录器,您需要提供两个不同的记录器名称.例如:

logger1 = logging.getLogger('user')
...
logger2 = logging.getLogger('dev')
Run Code Online (Sandbox Code Playgroud)

更糟糕的是,您呼叫的日志模块critical(),info()以及warning()方法和期待,这两个记录仪将获得的消息.这只能是因为你使用了空字符串作为名称都logger1logger2,因此他们不仅同记录仪,他们也是根记录.如果您使用我所建议两个记录仪不同的名字,那么你就需要调用critical(),info()warning()单独对每个记录方法(即你需要两个电话,而不是只有一个).

我认为你真正想要的是在一个记录器上有两个不同的处理程序.例如:

import logging

mylogger = logging.getLogger('mylogger')
handler1 = logging.FileHandler('usr.log')
handler1.setLevel(logging.INFO)
mylogger.addHandler(handler1)
handler2 = logging.FileHandler('dev.log')
handler2.setLevel(logging.ERROR)
mylogger.addHandler(handler2)
mylogger.setLevel(logging.INFO)

mylogger.critical('A critical message')
mylogger.info('An info message')
Run Code Online (Sandbox Code Playgroud)

完成此更改后,您可以使用David已经提到过的过滤器.这是一个快速示例过滤器:

class MyFilter(object):
    def __init__(self, level):
        self.__level = level

    def filter(self, logRecord):
        return logRecord.levelno <= self.__level
Run Code Online (Sandbox Code Playgroud)

您可以将过滤器应用于两个处理程序中的每一个,如下所示:

handler1.addFilter(MyFilter(logging.INFO))
...
handler2.addFilter(MyFilter(logging.ERROR))
Run Code Online (Sandbox Code Playgroud)

这将限制每个处理程序仅在指定的级别写出日志消息.

  • 要仅在指定的级别发出日志,条件是否必须是`logRecord.levelno == self .__ level`而不是`<=`? (2认同)
  • @samstav 确实如此,但为了代码清晰,我认为如果这就是您的意思,使用 `==` 仍然很有用。 (2认同)

Dav*_*d Z 7

第一:这是一件非常奇怪的事情,并且对我来说是对日志记录系统的轻微误用.我无法想象任何情况下,通知用户程序的正常运行,而不是更重要的事情.记录级别应用于表示重要性; 如果您只有开发人员感兴趣的消息,您应该使用其他一些机制来区分它们(例如您将它们发送到哪个记录器).

话虽这么说,您可以通过创建一个Filter子类来实现对日志记录的任意过滤,该子类的filter方法实现了您所需的标准并将其安装在适当的处理程序上.

  • 一个例子是,如果您设置了独立的日志 StreamHandler。您可以设置一个记录任何重要信息并将其发送到 stderr。然后,您可以为警告 * 或更低 * 设置一个完全独立的 StreamHandler 并将其设置为标准输出。您不想双重记录关键事件,并且可能永远不希望它们出现在标准输出中。这就是过滤器的用途,这是一个非常合法的用例。 (2认同)