python - python logging.Logger:覆盖makeRecord
问题描述
我有一个格式化程序,它需要记录中的特殊属性“user_id”,但并不总是存在(有时我使用特殊的 logging.Filter 将它添加到记录中)。我试图像这样覆盖 logging.Logger 的 makeRecord 方法:
import logging
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)-15s user_id=%(user_id)s %(filename)s:%(lineno)-15s: %(message)s')
class OneTestLogger(logging.Logger):
def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
rv = logging.Logger.makeRecord(self, name, level, fn, lno,
msg, args, exc_info,
func, extra)
rv.__dict__.setdefault('user_id', 'master')
return rv
if __name__ == '__main__':
logger = OneTestLogger('main')
print logger
logger.info('Starting test')
但这似乎不起作用,我不断得到:
< 0x7f31a6a5b638 处的主.MyLogger 实例>
找不到记录器“main”的处理程序
我究竟做错了什么?谢谢。
解决方案
遵循Logging Cookbook中提供的指南。只是第一部分,我没有实现过滤器(也没有出现在下面的引用中)。
这通常意味着如果您需要对 LogRecord 执行任何特殊操作,则必须执行以下操作之一。
- 创建您自己的 Logger 子类,它会覆盖 Logger.makeRecord(),并在实例化您关心的任何记录器之前使用 setLoggerClass() 设置它。
我简化了您的示例,只是添加了“主机名”:
import logging
from socket import gethostname
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s - %(hostname)s - %(message)s')
class NewLogger(logging.Logger):
def makeRecord(self, *args, **kwargs):
rv = super(NewLogger, self).makeRecord(*args, **kwargs)
# updating the rv value of the original makeRecord
# my idea is to use the same logic than a decorator by
# intercepting the value return by the original makeRecord
# and expanded with what I need
rv.__dict__['hostname'] = gethostname()
# by curiosity I am checking what is in this dictionary
# print(rv.__dict__)
return rv
logging.setLoggerClass(NewLogger)
logger = logging.getLogger(__name__)
logger.info('Hello World!')
请注意,此代码适用于 python 2.7
推荐阅读
- javascript - Wait for firebase.auth initialization before reading another function
- ruby-on-rails - 将带有 AM/PM 的 12 小时时间字符串转换为 24 小时时间
- javascript - 在 javascript 中创建异步单例
- azure - bcp 使用 ActiveDirectoryPassword 身份验证登录失败
- c# - .NET 如果从 OIDC 提供的用户在数据库中不可用,如何不进行身份验证
- node.js - 在heroku上部署我的应用程序但出现错误:加载资源失败:net::ERR_CONNECTION_REFUSED
- javascript - 正则表达式选择双引号之间的特定字符
- amazon-web-services - HITLayoutParameters怎么填
- reactjs - 如何在 nextjs 的 getinitial 道具中获取 cookie?
- prisma - 一种数据类型中两个字段的相同关系