Гарантия сброса журнала в Akka при выключении системы?

Я использую Akka FSM со Scala и веду журнал с помощью log член признака FSM, т. е. экземпляр признака akka.event.Logging.

При вызове context.system.shutdown() для завершения работы системы акторов, когда приложение хочет нормально завершить работу, кажется, что последние сообщения журнала иногда теряются (и вообще не распечатываются).

Есть ли способ гарантировать, что все сообщения журнала всегда распечатываются до выключения системы?


person akisaarinen    schedule 19.06.2012    source источник
comment
Откуда вы знаете, что все сообщения напечатаны?   -  person Viktor Klang    schedule 19.06.2012
comment
Я не совсем понимаю, что вы имеете ввиду. С точки зрения моего приложения, ему не нужно никакого уведомления, когда печатаются все сообщения журнала. Другими словами, мне не нужно «знать», что печатаются все сообщения. Я просто хочу, чтобы они были напечатаны. И в моем текущем случае я могу убедиться, что сообщение, которое я зарегистрировал, не распечатывается. Это вообще проясняет ситуацию?   -  person akisaarinen    schedule 20.06.2012
comment
Я хотел сказать, что Akka не может знать, когда все сообщения обработаны.   -  person Viktor Klang    schedule 20.06.2012
comment
Я это понимаю. И поскольку подсистема логирования также реализована с использованием сообщений Akka, нельзя ли гарантировать вывод всех лог-сообщений? Если это правда, есть ли какой-либо способ сделать, по крайней мере, очень вероятным, что все ожидающие сообщения журнала будут сброшены, учитывая, что я использую систему акторов с одним узлом без функций распределения?   -  person akisaarinen    schedule 20.06.2012
comment
Если ты скажешь мне, как это сделать, я могу попробовать. Самое простое решение для вас, вероятно, состоит в том, чтобы ваш регистратор выключил систему, а не ваш актер.   -  person Viktor Klang    schedule 20.06.2012
comment
На данный момент у меня нет предложений, я еще не очень внимательно изучал внутренности регистрации Akka. Я свяжусь с вами, если что-нибудь придумаю. Что касается вашего предложения позволить регистратору выключить систему, не могли бы вы дать какие-либо указания, как это сделать? Прямо сейчас я вызываю context.system.shutdown() в своем актере и использую актеров по умолчанию из Akka для ведения журнала (только вывод на стандартный вывод). Какой самый простой способ внедрить выключение в регистратор?   -  person akisaarinen    schedule 20.06.2012
comment
Прослушать сообщение журнала, которое, как вы знаете, является последним, а затем закрыть?   -  person Viktor Klang    schedule 20.06.2012
comment
Нет, ему придется прослушивать вывод последнего сообщения регистратором (поскольку проблема наверняка заключается в том, что событие журнала находится в почтовом ящике регистратора, когда система выключается). Проще всего было бы реализовать свой собственный регистратор (посмотрите на akka.event.Logging.DefaultLogger, чтобы увидеть, насколько это просто) и заставить его вызывать context.system.shutdown() при получении некоторого сообщения. Затем отправьте это сообщение в ActorSelection(/system/log*), когда захотите завершить работу.   -  person Roland Kuhn    schedule 20.06.2012
comment
Спасибо, Роланд, похоже на план. Я попробую это.   -  person akisaarinen    schedule 20.06.2012


Ответы (1)


По предложению доктора Куна, вот образец TerminatingLogger. Я поместил свой в канал error(), чтобы он не попадал в сравнение строк часто, но вы, очевидно, можете поместить его куда угодно.

class TerminatingLogger extends Actor with StdOutLogger {
    override def receive: Receive = {
      case InitializeLogger(_) ⇒ sender() ! LoggerInitialized
      case error : akka.event.Logging.Error if error.message.toString().equals("TERMINATE_SYSTEM") =>
      {
        context.system.shutdown()
      }
      case event: LogEvent     ⇒ 
      {
       print(event) 
      }
    }
  }

Затем просто настройте его в файле application.conf.

akka {
  loggers = [com.namespace.TerminatingLogger]
}
person fbl    schedule 18.05.2015