python logging 仅特定级别
我在用Python的日志模块记录事件。我有两个日志文件,一个用来记录用户信息,另一个是给开发者看的更详细的日志文件。我已经把这两个日志文件的级别设置好了(usr.log = INFO,dev.log = ERROR),但是我不知道怎么限制usr.log文件,只让它记录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')
如果能帮忙就太好了,谢谢你。
2 个回答
首先,这个想法有点奇怪,我觉得有点不太对劲。正常情况下,程序运行的情况应该告诉用户,但更重要的事情却不告诉用户,这让我很难理解。日志的级别应该用来表示事情的重要性;如果你有一些信息只是开发者关心,那就应该用其他方式来区分这些信息,比如把它们发送到不同的日志记录器。
不过,话说回来,你可以通过创建一个Filter
的子类,来实现对日志记录的任意过滤。在这个子类中,你可以定义一个filter
方法,按照你想要的标准来过滤日志,然后把它安装到合适的处理器上。
我大体上同意David的看法,但我觉得还有更多需要说明的。用《公主新娘》里的话来说——我觉得你的代码并不是你想的那样。你的代码里有:
logger1 = logging.getLogger('')
...
logger2 = logging.getLogger('')
这意味着logger1
和logger2
是同一个日志记录器,所以当你把logger2
的级别设置为ERROR时,其实logger1
的级别也会同时被设置成ERROR。要想得到两个不同的日志记录器,你需要给它们提供两个不同的名字。例如:
logger1 = logging.getLogger('user')
...
logger2 = logging.getLogger('dev')
更糟糕的是,你在调用日志模块的critical()
、info()
和warning()
方法时,期望两个日志记录器都能收到消息。之所以能这样做,是因为你给logger1
和logger2
都用了空字符串作为名字,因此它们不仅是同一个日志记录器,还是根日志记录器。如果你按照我建议的那样给两个日志记录器使用不同的名字,那么你就需要分别对每个日志记录器调用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')
一旦你做了这个更改,你就可以像David提到的那样使用过滤器。这里有一个简单的过滤器示例:
class MyFilter(object):
def __init__(self, level):
self.__level = level
def filter(self, logRecord):
return logRecord.levelno <= self.__level
你可以像这样将过滤器应用到两个处理器上:
handler1.addFilter(MyFilter(logging.INFO))
...
handler2.addFilter(MyFilter(logging.ERROR))
这样就可以限制每个处理器只输出指定级别的日志消息。