0

我最近发现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))更新上下文?但这只会更新函数内记录器的上下文。在其他功能中,位置仍然会被错误地记录。

4

1 回答 1

0

我个人倾向于只注销 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

于 2020-05-02T08:08:02.377 回答