输出结果:
# 使用extra默认值:{"ip": "IP", "username": "USERNAME"} 2017-05-22 17:35:38,499 - myPro - IP - USERNAME - User Login! # info(msg, extra)方法中传递的extra方法已覆盖默认值 2017-05-22 17:35:38,499 - myPro - 113.208.78.29 - Petter - User Login! # extra默认值保持不变 2017-05-22 17:35:38,499 - myPro - IP - USERNAME - User Login! 2017-05-22 17:35:38,499 - myPro - IP - USERNAME - User Login!OK! 问题解决了。
其实,如果我们想不受formatter的限制,在日志输出中实现自由的字段插入,可以通过在自定义LoggerAdapter的子类的process()方法中将字典参数中的关键字信息拼接到日志事件的消息中。很明显,这些上下文中的字段信息在日志输出中的位置是有限制的。而使用'extra'的优势在于,这个类字典对象的值将被合并到这个LogRecord实例的__dict__中,这样就允许我们通过Formatter实例自定义日志输出的格式字符串。这虽然使得上下文信息中的字段信息在日志输出中的位置变得与内置字段一样灵活,但是前提是传递给构造器方法的这个类字典对象中的key必须是确定且明了的。
三、使用Filters引入上下文信息另外,我们还可以使用自定义的Filter.Filter实例的方式,在filter(record)方法中修改传递过来的LogRecord实例,把要加入的上下文信息作为新的属性赋值给该实例,这样就可以通过指定formatter的字符串格式来输出这些上下文信息了。
我们模仿上面的实现,在传递个filter(record)方法的LogRecord实例中添加两个与当前网络请求相关的信息:ip和username。
import logging from random import choice class ContextFilter(logging.Filter): ip = 'IP' username = 'USER' def filter(self, record): record.ip = self.ip record.username = self.username return True if __name__ == '__main__': levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL) users = ['Tom', 'Jerry', 'Peter'] ips = ['113.108.98.34', '219.238.78.91', '43.123.99.68'] logging.basicConfig(level=logging.DEBUG, format='%(asctime)-15s %(name)-5s %(levelname)-8s %(ip)-15s %(username)-8s %(message)s') logger = logging.getLogger('myLogger') f = ContextFilter() logger.addFilter(f) logger.debug('A debug message') logger.info('An info message with %s', 'some parameters') for x in range(5): lvl = choice(levels) lvlname = logging.getLevelName(lvl) filter.ip = choice(ips) filter.username = choice(users) logger.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')输出结果:
2017-05-15 10:21:49,401 myLogger DEBUG IP USER A debug message 2017-05-15 10:21:49,401 myLogger INFO IP USER An info message with some parameters 2017-05-15 10:21:49,401 myLogger INFO 219.238.78.91 Tom A message at INFO level with 2 parameters 2017-05-15 10:21:49,401 myLogger INFO 219.238.78.91 Peter A message at INFO level with 2 parameters 2017-05-15 10:21:49,401 myLogger DEBUG 113.108.98.34 Jerry A message at DEBUG level with 2 parameters 2017-05-15 10:21:49,401 myLogger CRITICAL 43.123.99.68 Tom A message at CRITICAL level with 2 parameters 2017-05-15 10:21:49,401 myLogger INFO 43.123.99.68 Jerry A message at INFO level with 2 parameters