使用structlog记录更改的对象属性



我最近发现了structlog,并想用它来记录一些对象的对象属性。我不确定两件事:

1( 面向对象日志记录的最佳实践是什么?我想绑定一些对象属性,例如ID,它们总是为对象记录。我能找到的对象的唯一例子是这个,其中logger被创建为全局变量,每个对象都创建了一个新的记录器和函数。(如果我理解正确的话。(

2( 如果我的一些属性随着时间的推移而改变,例如用户的位置,该怎么办?如果我只是在构造函数中绑定位置,那么即使用户移动,它也总是记录相同的位置。我必须在每个动作后"重新绑定"吗?怎样

这就是我目前拥有的:

import structlog
logger = structlog.get_logger()
class User:
def __init__(self, id, pos):
self.id = id
self.pos = pos
self._log = logger.bind(id=self.id, pos=str(self.pos))
def move(self, delta):
log = self._log.bind(delta=delta)
self.pos += delta
log.msg("User moved")

在这个面向对象的示例中,我是否正确/良好地使用了structlog?不管怎样,即使用户移动,它也总是打印相同的位置。我想,我必须做log.msg("User moved", pos=str(self.pos))来更新上下文?但这只会更新函数中记录器的上下文。在其他功能中,位置仍然会被错误地记录。

我个人倾向于只注销ID,但如果你想要更丰富的日志行,你可以将整个对象绑定到记录器,并编写一个简单的处理器,为你提取有趣的属性:

def user_extractor(_, __, ed):
user = ed.pop("user", None)
if user is not None:
ed.update(user_id=user.id, user_pos=user.pos)
return ed

一个更通用的选项可以是使用functools.singledispatch定义序列化,并编写一个使用它的处理器(也不应该超过几行(。我认为我们迟早也会在structlog中添加对这一点的支持。


请参阅http://www.structlog.org/en/stable/processors.html有关编写处理器的更多详细信息。

最新更新