Группировка / идентификация журналов актеров для одного и того же "запроса"
Я ищу способ или лучшее / лучшее дизайнерское решение для проблемы регистрации. Я использую акторы Akka в кластерах для своих внутренних сервисов и Play во внешнем интерфейсе для приема HTTP-запросов. Мой вопрос несколько расширен от старого вопроса о том, чтобы весь журнал приложения был идентифицируемым для одних и тех же HTTP-запросов, которые просто используют MDC, который существует в большинстве современных сред ведения журналов, генерируя UUID в начале и помещая в контекст.
Пример нашего потока данных может выглядеть так:
"Http-запрос / система A" -> "Actor1/Cluster B" -> "Actor2/Cluster C" -> "Ответить на систему A и выполнить запрос"
Это означает, что в процессе участвуют как минимум 3 отдельные системы. Весь мой журнал уходит в Logstash. Я могу сгенерировать UUID с самого начала запроса от Системы А. Однако мне бы хотелось, чтобы UUID можно было переносить / переносить во все подсистемы, которые все используют сериализацию Protobuf для связи друг с другом, обрабатывая задания, принадлежащие на тот же http запрос.
Я знаю, что всегда могу добавить поле идентификатора ко всем своим сообщениям, но это очень уродливо.
Мне интересно, есть ли лучший способ или лучший механизм передачи информации ко всем другим вызывающим системам Akka, не создавая слишком много шума для обработки моей бизнес-логики?
1 ответ
Вы можете обернуть ваши оригинальные сообщения в контейнер с UUID
:
case class MessageWithUuid(message: Any, uuid: UUID)
Тогда в вашем receive
Вы должны развернуть его и сохранить uuid
для ведения журнала:
var uuid: Option[UUID] =
def receive: Receive = {
case MessageWithUuid(message, uuid) =>
this.uuid = Some(uuid)
//TODO: put UUID to MDC logging context
receive(message)
//TODO: remove UUID from MDC
this.uuid = None
case ... =>
}
И всякий раз, когда вы отправляете сообщение другому актеру, вам нужно обернуть его UUID:
def send(actor: ActorRef, message: Any) = actor ! MessageWithUuid(message, uuid.get)