2012-01-23 10 views
6

Używam więc Slf4jEventHandler i klasycznego logback. Jak skonfigurować osobne poziomy dzienników dla różnych podmiotów? [Używam Akka 2.0_M2]nazwy rejestratorów do konfigurowania rejestratora akka za pomocą obsługi zdarzeń

Próbowałem robić coś podobnego

<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> 

ale to nie pomaga w ogóle:

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

Jak widać ja dostaję tylko rejestrowanie poziom INFO dla aktorów. Jaka jest hierarchia nazw dla rejestratorów aktorów?

Odpowiedz

6

ja domyślam się, że używasz 2.0 milestone Akka, a ja dalej zgadywać, że można uzyskać rejestratora tak:

val log = Logging(context.system, this) 

Jak udokumentowano, domyślną reprezentacją aktora pod względem kategorii dziennika jest jego ścieżka. Niestety, funkcja logback nie jest przygotowana do radzenia sobie z hierarchiami aktorów, jest skonfigurowana tak, aby zajmować się nazwami pakietów (tj. Hierarchią z punktami), dlatego ustawienia wpływają na zły rejestrator. W ostatnim czasie nastąpiły pewne zmiany w tym obszarze w Akka Master, które będą częścią etapu 3 (który zostanie wkrótce wydany), gdzie domyślna kategoria logów zostanie uzyskana z rzeczywistej klasy implementacji (zgodnie z LoggerFactory.getLogger(someClass)). Jeśli chcesz osiągnąć to samo na swojej starszej wersji Akka, użyj

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

Zauważ, że to oczywiście, że nie ma ujednolicić hierarchię nazw aktor magicznie ze swoimi nazw pakietów, czyli trzeba będzie skonfigurować w klasie aktora jako jest typowe dla tradycyjnych frameworków do logowania Java. Jeśli chcesz, aby napisać własny konwersję z drogi aktora do kropka oddziela nazwa hierarchiczna i przekazać wynikowy ciąg do fabryki:

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

Zmiana użyciem eventStream zamiast zwykłego system będzie konieczne po zaktualizowaniu do nowsza wersja, ponieważ inna zmiana polegała na tym, że nazwa systemu zostanie teraz dołączona do zwykłych kategorii logowania, jeśli przejdzie w systemie. Zakładamy system.name == "Fred":

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

jestem mieszania w ActorLogging cecha wprowadzająca * log. Ale doprowadziłeś mnie do kierunku pisania - zastanawiam się, czy mógłbym ustawić część mangleName w rozszerzeniu SLF4JEventHandler, zamiast pisać to explicity w moim kodzie. Następnie po prostu poinstruuję go, aby przekonwertował nazwę jak akka: // TradeService/AnotherService na TradeService.AnotherService (Myślę, że upuściłbym część protokołu). Jaka jest Twoja opinia? –

+0

Inna mała irytacja - ponieważ rejestracja opiera się na zdarzeniu, wzorzec [% X {sourceThread}] dla mojego rejestrowania w trybie innym niż Actor spowoduje wygenerowanie pustych "[]". A jeśli mam% wątku, otrzymam "dispatcher-thread-x" dla Loga Aktora ...ale mogę z tym żyć. –

+0

Zgaduję, że mogę użyć innej procedury obsługi zdarzeń, która najpierw konwertuje logSource XXXEvents, a następnie przekazuje wiadomości do SLF4JEventHandler –

1

Akka Logging nie dobrze integrować z luzem po wyjęciu z pudełka. Używa również innego API do slf4j np. ostrzeżenie zamiast ostrzeżenia, co utrudnia zastąpienie, jeśli zajdzie taka potrzeba.

Poniższa cecha zmusza klasyczny slf4j/log4j Nazwa pakietu strukturę podejmowania rejestratory łatwiejsza do skonfigurowania w 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()) 
} 

i używać go jak ten

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

Zwykle nie lubię tego typu rozwiązań, ale jak dotąd nie sprawiło mi to żadnych problemów i sprawiło, że konfiguracja stała się nieskończenie łatwiejsza. Używam go zamiast ActorLogging z Actors i uzyskuję standardowe sformatowane instrukcje dziennika (np. Ostrzeżenie) oraz łatwą konfigurację. – jlegler

Powiązane problemy