2012-01-23 2 views
6

Итак, я использую Slf4jEventHandler и logback-classic. Как настроить уровни журналов для разных участников отдельно? [Я использую Akka 2.0_M2]имена регистраторов для настройки akka logger с помощью обработчика событий

Я пытался делать что-то вроде

<configuration debug="true" scan="true"> 
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
     <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> 
      <pattern>%-5level %logger{36} - %msg%n</pattern> 
     </encoder> 
    </appender> 
    <logger name="akka://TradeService" level="DEBUG" /> 
    <root level="INFO"> 
     <appender-ref ref="STDOUT" /> 
    </root> 
</configuration> 

, но это не помогло вообще:

INFO akka://TradeService/user/realTimeReqListener - Declaring queue 
INFO akka://TradeService/user/restReqListener - Declaring queue 
INFO akka://TradeService/user/restReqListener - Starting listening to queue 

Как вы можете видеть, я только получаю протоколирование уровня INFO для актеров. Что такое иерархия именования для регистраторов?

ответ

6

Я предполагаю, что вы используете 2.0 веху Akka, и я далее предполагаю, что вы получите ваш регистратор так:

val log = Logging(context.system, this) 

Как указано, представление по умолчанию актера с точки зрения журнала категории это его путь. К сожалению, logback не готов к работе с иерархиями акторов, он настроен на обработку имен пакетов (то есть разделенных точками иерархии), поэтому ваш параметр влияет на неправильный регистратор. Недавно произошли некоторые изменения в этой области в мастерской Akka, которые будут частью вехи 3 (скоро будет выпущена в ближайшее время), где категория журнала по умолчанию будет получена из фактического класса реализации (согласно LoggerFactory.getLogger(someClass)). Если вы хотите, чтобы достичь того же на вашей старой версии Акко, используйте

val log = Logging(context.system, getClass.getName) 

Обратите внимание, что это, конечно, не унифицировать иерархии имя актера волшебно с именами пакетов, то есть вам придется настроить на класс актера, как является обычным для традиционных фреймворков регистрации Java. Если вы хотите, чтобы, написать свой собственный переход от пути актера, разделенных точками иерархическое имя и передать полученную строку на заводе:

val log = Logging(context.system.eventStream, mangleMyName(self.path)) 

Изменение к использованию eventStream вместо обычного system будет необходимо, как только вы обновление до более поздняя версия, потому что другое изменение состояло в том, что имя системы теперь будет добавлено к простым категориям ведения журнала при прохождении в системе. Предположим system.name == "Fred":

val log = Logging(context.system, "testa") // will log as "testa(Fred)" 
+0

Я смесительной в ActorLogging черта для входа * log. Но вы привели меня к направлению записи - мне интересно, могу ли я создать часть mangleMyName в расширении SLF4JEventHandler вместо того, чтобы писать ее экспликацию в моем коде. Тогда я просто попрошу его преобразовать имя как akka: // TradeService/AnotherService в TradeService.AnotherService (я думаю, что я бы отказался от части протокола). Каково твое мнение? –

+0

Еще одно небольшое раздражение - потому что ведение журнала основано на событиях, шаблон [% X {sourceThread}] для моего ведения не-Actor будет генерировать пробелы «[]». И если у меня есть% thread, я получу «dispatcher-thread-x» для Actor-loggin ...но я могу жить с этим. –

+0

Я предполагаю, что я могу использовать другой обработчик событий, который сначала преобразует logSource из XXXEvents, а затем передает сообщения в SLF4JEventHandler. –

1

каротажного Akka не очень хорошо интегрируется с Play из коробки. Он также использует другой API для slf4j, например. предупреждение, а не предупреждение, что затрудняет замену, если вам нужно.

Черт ниже заставляет классический SLF4J/log4j структуру пакетов имени делает Лесоруб легче настроить в application.conf

import org.slf4j.LoggerFactory 
import akka.actor.ActorRef 

trait ActorLogger { 
    implicit val self:ActorRef 
    protected val log = LoggerFactory.getLogger(getClass().getName() + "_" + self.path.toString()) 
} 

и использовать его как этот

class Foo extends Actor with ActorLogger { 
    def run = { 
    log.info("hi") 
    log.warn("hi") 
    } 
} 
+0

Мне обычно не нравится этот тип решения, но до сих пор это не вызывало у меня никаких проблем и упрощало настройку. Я использую его вместо ActorLogging с Актерами и получаю стандартные форматированные логические операторы (т. Е. Предупреждение), а также простой конфиг. – jlegler