Используйте structlog для регистрации изменений атрибутов объекта - PullRequest
0 голосов
/ 29 апреля 2020

Я недавно обнаружил 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)), чтобы обновить контекст? Но это только обновит контекст для регистратора внутри функции. В других функциях позиция будет по-прежнему записываться неправильно.

1 Ответ

0 голосов
/ 02 мая 2020

Лично я склонен к выходу из системы только идентификаторов, но если вам нужны более богатые строки журнала, вы можете привязать весь объект к регистратору и написать простой процессор, который извлекает для вас интересные атрибуты:

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 и запись процессора, который его использует (не должно быть больше нескольких строк). Я думаю, что мы добавим поддержку для этого * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 100 * *1001* *).

...