【发布时间】:2011-07-11 15:40:38
【问题描述】:
我在 Python 中使用 logging 模块来编写调试和错误消息。
我想将logging.DEBUG 或更高版本的所有消息写入文件。
但是,我只想将logging.WARNING 或更高版本的消息打印到屏幕上。
这是否可能只使用一个Logger 和一个FileHandler?
【问题讨论】:
我在 Python 中使用 logging 模块来编写调试和错误消息。
我想将logging.DEBUG 或更高版本的所有消息写入文件。
但是,我只想将logging.WARNING 或更高版本的消息打印到屏幕上。
这是否可能只使用一个Logger 和一个FileHandler?
【问题讨论】:
正如已经提到的,处理程序非常容易创建和添加,您最好只使用两个处理程序。但是,如果由于某种原因你想坚持一个,Python logging cookbook 有一个部分或多或少地描述了你想要做什么:登录到控制台和文件,但在不同的级别(它甚至向你展示了如何做不同的格式)。不过,它使用单个 StreamHandler 而不是 FileHandler 来实现:
import logging
# set up logging to file - see previous section for more details
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
datefmt='%m-%d %H:%M',
filename='/temp/myapp.log',
filemode='w')
# define a Handler which writes INFO messages or higher to the sys.stderr
console = logging.StreamHandler()
console.setLevel(logging.INFO)
# set a format which is simpler for console use
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
# tell the handler to use this format
console.setFormatter(formatter)
# add the handler to the root logger
logging.getLogger('').addHandler(console)
# Now, we can log to the root logger, or any other logger. First the root...
logging.info('Jackdaws love my big sphinx of quartz.')
# Now, define a couple of other loggers which might represent areas in your
# application:
logger1 = logging.getLogger('myapp.area1')
logger2 = logging.getLogger('myapp.area2')
logger1.debug('Quick zephyrs blow, vexing daft Jim.')
logger1.info('How quickly daft jumping zebras vex.')
logger2.warning('Jail zesty vixen who grabbed pay from quack.')
logger2.error('The five boxing wizards jump quickly.')
编辑:正如在 cmets 中所讨论的,此代码仍然生成两个处理程序,但通过使用 basicConfig()“隐藏”了一个构造。我强烈建议您明确地创建两者。
【讨论】:
basicConfig(...)“掩盖”了FileHandler的创建,我宁愿明确地创建它们。
您可以将许多处理程序附加到具有不同日志级别的同一记录器,但根日志级别必须与最详细的处理程序一样详细。此示例使用 log.debug() 和 log.info() 将消息记录到文件到控制台:
log = logging.getLogger("syslog2elastic")
log.setLevel(logging.DEBUG) # this must be DEBUG to allow debug messages through
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s.%(msecs)03d - %(name)s:%(lineno)d - %(levelname)s - %(message)s", "%Y%m%d%H%M%S")
console.setFormatter(formatter)
log.addHandler(console)
fh = RotatingFileHandler(args.logfile, maxBytes=104857600, backupCount=5)
fh.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s.%(msecs)03d - %(message)s", "%Y%m%d%H%M%S")
fh.setFormatter(formatter)
log.addHandler(fh)
【讨论】:
没有。文件和屏幕输出意味着您需要两个处理程序。
【讨论】:
您可以通过以下方式执行此操作,制作两个记录器,一个用于文件记录,另一个用于控制台记录。确保将根记录器设置为两者中最详细的。
import logging
logging.getLogger().setLevel(logging.DEBUG) # This must be as verbose as the most verbose handler
formatter = logging.Formatter(
'%(asctime)s.%(msecs)03d %(levelname)s %(module)s - %(funcName)s [%(lineno)s]: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
)
console_logging = logging.StreamHandler()
console_logging.setLevel(logging.WARNING)
console_logging.setFormatter(formatter)
logging.getLogger().addHandler(console_logging)
file_logging = logging.FileHandler('file.log')
file_logging.setLevel(logging.DEBUG)
file_logging.setFormatter(formatter)
logging.getLogger().addHandler(file_logging)
【讨论】: