У меня есть Акк Актер, который звонит в MyObject.foo(). MyObject не актер. Как настроить регистрацию? С Актером это просто, потому что я могу просто микшировать ActorLogging. В MyObject у меня нет доступа к context.system. Создать akka.event.Logging с помощью AkkaSystem(), а затем, что для неявного LogSource?
Akka Регистрация вне форума
Ответ 1
На самом деле я бы перенаправил Akka в журнал slf4j и использовать этот API непосредственно во всех не связанных между собой классах. Сначала добавьте это в свою конфигурацию:
akka {
event-handlers = ["akka.event.slf4j.Slf4jEventHandler"]
loglevel = "DEBUG"
}
Затем выберите некоторую реализацию SLF4J, я предлагаю logback. В ваших актерах продолжайте использовать черту ActorLogging
. В других классах просто полагайтесь на API SLF4J - или даже лучше - попробуйте slf4s фасад вокруг SLF4J.
Совет. Попробуйте выполнить следующий шаблон ведения журнала в журнале:
<pattern>%d{HH:mm:ss.SSS} | %-5level | %thread | %X{akkaSource} | %logger{1} | %m%n%rEx</pattern>
%X{akkaSource}
будет печатать путь к актеру, если он доступен (как и стандартное ведение журнала).
Ответ 2
Используя Akka 2.2.1, я смог поместить это в свое приложение, чтобы получить регистрацию вне актера:
import akka.event.Logging
val system = ActorSystem("HelloSystem", ConfigFactory.load.getConfig("akka"))
val log = Logging.getLogger(system, this)
log.info("Hi!")
Это похоже на более простое решение для объединения журнала приложений.
Ответ 3
Теперь я решил просто пропустить мою центральную систему ведения журнала через инъекцию конструктора DI (Guice). И в моих классах, которые регулярно регистрируются (где важна асинхронность), я беру введенную ActorSystem и вызываю
this.log = akka.event.Logging.getLogger(actorSystem, this);
в конструкторе классов.
Ответ 4
Как уже упоминалось, вы испорчены для вариантов ведения неактивных записей в системе актеров. Я попытаюсь предоставить набор эвристик, которые помогут вам определить, как вы должны маршрутизировать протоколы для своей работы.
- Вы можете использовать регистратор (log4j 1.x, logback, log4j 2.x) непосредственно как для актера, так и для неактивного кода.
- Это сильно привязывает ваш код к реализации регистратора. Это нормально, если это ваш код, который нельзя использовать в другом месте, но не очень хорошо, если вы создаете библиотеку или собираетесь открыть источник своей работы.
- Если вы сделаете это, вы не получите преимуществ от системы актеров. Журналирование вызовов может стать блокировкой вызовов, в зависимости от того, как вы настроили свой журнал, и, таким образом, это недоверчиво, когда важны проблемы производительности или контроля обратного давления.
- Поскольку код субъекта (вместе с сервисами, который он может потреблять) может работать на многих разных потоках, некоторые традиционные действия в области ведения журналов, такие как использование threadlocal MDC (контекстный диагностический контекст), могут приводить к странным условиям гонки и контекстному swtiching с выходом журналов от сообщений, которые передаются от актера к актеру. Такие действия, как обмен файлами MDC на сообщения перед их отправкой, могут стать необходимыми для сохранения контекста между актером и неактивным кодом.
- Чтобы захватить события ActorSystem, такие как мертвые буквы и надзор, вам может потребоваться написать адаптер регистрации и указать его в вашем приложении application.conf. Это довольно просто.
- Вы можете использовать фасад SLF4J для регистрации как актеров, так и неактивных.
- Вы больше не связаны с логгерским импортом и чем больше ваши услуги не связаны с аккой. Это лучший вариант для переносимости.
- Вы можете наследовать поведение блокировки из своей структуры журнала.
- Возможно, вам придется управлять MDC
- Чтобы захватить события ActorSystem, вам нужно указать "akka.event.slf4j.Slf4jLogger" в вашем приложении application.conf
- Вам нужно будет включить jar-провайдер slf4j в pathpath для маршрутизации событий журнала slf4j в выбранный вами журнал
- Вы можете использовать Akka Logging в качестве своего фасада как в актере, так и в неактивном коде
- Вы не связаны с логгерским импортером ИЛИ с slf4j, но вы связаны с версией akka. Вероятно, это требование вашей системы, но для библиотек это может снизить переносимость.
- Вам нужно пройти актерскую систему, чтобы действовать как "шина" для регистраторов. Тесная связь с действующей системой актеров снижает переносимость. (В приложении я обычно создаю небольшой признак LoggingViaActorSystem с неявной или глобальной ActorSystem, что упрощает работу с этим кодом, но не через зависимости).
- Неблокирующее асинхронное ведение журнала гарантируется, даже если ваш регистратор не поддерживает их. Причинная логичность ведения журнала, вероятно, связана с использованием одного почтового ящика пользователя. Однако безопасность памяти и противодавление не являются (я считаю, что ведение Akka использует неограниченный почтовый ящик) -
- Существуют варианты, такие как использование DiagnosticLoggingAdapter для избежания сложности управления вашими собственными MDC, поскольку работа переходит от актера к актеру. Консистенция должна сохраняться, даже если неактивный код мутирует эти MDC.
- Ведение журнала вряд ли будет доступно во время сбоя вне памяти и будет чувствительным к голоданию потока на диспетчере по умолчанию
- Вам нужно указать свой выбранный регистратор в application.conf, если вы не заинтересованы в регистрации в стандартном формате
Вы можете смешивать и сопоставлять вышеуказанные действия по мере необходимости, чтобы соответствовать вашим требованиям. Например, вы можете привязываться к SLF4J для библиотек и использовать ведение журнала Akka для всего остального. Просто отметьте, что блокирование микширования и неблокирующее протоколирование могут привести к условиям гонки, когда причины (зарегистрированные асинхронные действия через актера) регистрируются после их эффектов (синхронизация с синхронизацией по протоколу напрямую).