2012-04-14 11 views
42

Possiedo un Akka Actor che effettua una chiamata a MyObject.foo(). MyObject non è un attore. Come posso impostare la registrazione in esso? Con un attore è semplice, perché posso semplicemente mixare ActorLogging. In MyObject, non ho accesso a context.system. Creo un akka.event.Logging con AkkaSystem() e poi cosa è implicito per la LogSource?Akka Registrazione all'esterno dell'attore

+0

Hai letto questo? : http://doc.akka.io/docs/akka/2.0/scala/logging.html –

+6

@ViktorKlang sì. Tuttavia, non sembra rispondere alla mia domanda, né descrive il motivo per cui è necessario il logger degli eventi di Akka (al contrario di usare semplicemente SLF4J direttamente nell'Actor). – Bradford

+1

Poiché è possibile rendere qualsiasi back-end di registrazione asincrono poiché la registrazione viene eseguita tramite un attore. –

risposta

22

realtà avrei reindirizzare registrazione Akka per e utilizzare questa API direttamente in tutte le classi non correlate. In primo luogo aggiungere questo alla propria configurazione:

akka { 
    event-handlers = ["akka.event.slf4j.Slf4jEventHandler"] 
    loglevel = "DEBUG" 
} 

Poi scegliere alcuni implementazione SLF4J, suggerisco . Nei tuoi attori continua ad usare il tratto ActorLogging. In altre classi basterà affidarsi all'API SLF4J - o anche meglio - provare la facciata slf4s attorno a SLF4J.

Suggerimento: provare il seguente schema di registrazione in Logback:

<pattern>%d{HH:mm:ss.SSS} | %-5level | %thread | %X{akkaSource} | %logger{1} | %m%n%rEx</pattern> 

Il %X{akkaSource} stamperà percorso attore quando disponibile (proprio come la registrazione standard).

+0

Grazie.Non sono del tutto sicuro del motivo per cui ActorLogging esista, ma dal momento che è importante, il metodo con cui il mio attore sta chiamando sta utilizzando direttamente l'API SLF4J invece di utilizzare il sistema di eventi di registrazione di Akka? Pericoli? In alternativa, potrei creare un attore di registrazione e inviare solo messaggi di registro. Cosa si preferisce qui? – Bradford

+1

Ma se si utilizza direttamente la fabbrica di SLF4J, non si ottiene la registrazione asincrona, giusto? Sto usando sporcizia statica per accedere al sistema oggetto atm:/ –

+2

@AntonyStubbs: no, se vuoi beneficiare della registrazione asincrona, dovresti inviare un messaggio ad un certo attore - e usare quell'attore per registrare il messaggio .. –

8

ora ho optato per semplicemente passando il mio sistema di registrazione centrale intorno attraverso l'iniezione costruttore DI (Guice). E nella mia classe che accedono regolarmente (dove asincronia è importante), prendo l'ActorSystem iniettata e chiamo la

this.log = akka.event.Logging.getLogger(actorSystem, this); 

nel costruttore classi.

+3

Un'altra opzione, che potrebbe essere migliore per i casi in cui non si desidera far crescere l'oggetto in modo che contenga tale riferimento, è aggiungere un secondo elenco di parametri '(registro implicito: LoggingAdapter)' ai metodi che devono eseguire la registrazione. – AmigoNico

20

Utilizzando Akka 2.2.1, sono stato in grado di mettere questo nel mio App per ottenere la registrazione al di fuori di un attore:

import akka.event.Logging 
val system = ActorSystem("HelloSystem", ConfigFactory.load.getConfig("akka")) 
val log = Logging.getLogger(system, this) 
log.info("Hi!") 

Questa sembra una soluzione più semplice per unificare la registrazione di un'applicazione.

+0

Questo è stato il modo più semplice per farmi andare - grazie! – akauppi

+6

Questa risposta non risolve il problema reale. Si crea un intero ActorSystem solo per fare un po 'di log in un corso. Se ne hai bisogno da qualche altra parte hai intenzione di creare un altro ActorSystem? Potrebbe anche passare il riferimento del tuo primo ActorSystem creato intorno. –

6

Come è stato detto, avrete l'imbarazzo della scelta per la registrazione non-attore all'interno di un sistema di attore. Cercherò di fornire una serie di metodi euristici per aiutarti a determinare come instradare la registrazione per il tuo lavoro.

  1. È possibile utilizzare un logger (log4j 1.x, logback, log4j 2.x) direttamente sia l'attore e il codice non-attore.
    • Questo collega strettamente il codice a un'implementazione di logger. Questo va bene se è il tuo codice, non deve essere usato altrove, ma non va bene se stai costruendo una biblioteca o intendi open source il tuo lavoro.
    • Se si esegue questa operazione, non si ottengono benefici dal sistema degli attori. Le chiamate di log possono diventare chiamate di blocco, a seconda di come è stato configurato il logger, e quindi questo è disapprovato ovunque le prestazioni o il controllo sulla contropressione sono preoccupazioni importanti.
    • Poiché il codice attore (insieme ai servizi che può utilizzare) può operare su molti thread diversi, alcune attività di registrazione tradizionali come l'uso di un MDC threadlocal (contesto diagnostico mappato) possono determinare condizioni di corsa bizzarre e swtiching del contesto con l'output dei registri dai messaggi che passano da attore ad attore. Attività come lo scambio di MDC sui messaggi prima di inviarle possono diventare necessarie per preservare il contesto tra il codice attore e non attore.
    • per acquisire gli eventi ActorSystem come lettere morte e la supervisione, potrebbe essere necessario scrivere un adattatore di registrazione e specificare nel vostro application.conf. Questi sono piuttosto semplici.
  2. È possibile utilizzare la facciata SLF4J per la registrazione di attori e non attori.
    • Non sei più collegato a un programma di registrazione e, inoltre, i tuoi servizi non sono abbinati a akka. Questa è l'opzione migliore per la portabilità.
    • È possibile ereditare il comportamento di blocco dal framework del log.
    • Potrebbe essere necessario gestire MDC
    • Per catturare gli eventi ActorSystem che sarà necessario specificare "akka.event.slf4j.Slf4jLogger" nel tuo application.conf
    • Avrai bisogno di includere un vaso fornitore slf4j su il classpath per eventi di registro di percorso slf4j al tuo logger scelto
  3. È possibile utilizzare la registrazione di Akka come facciata sia in codice di attore e non-attore
    • non sono accoppiati ad un logger impl O a s lf4j, ma tu sei abbinato a una versione di akka. Questo è probabilmente un requisito del tuo sistema in ogni caso, ma per le librerie potrebbe ridurre la portabilità.
    • Devi passare attorno a un sistema di attori per fungere da "bus" per i logger. Un accoppiamento stretto con un sistema di attori funzionanti riduce ulteriormente la portabilità. (All'interno di un'app di solito creo un piccolo tratto di LoggingViaActorSystem con un ActorSystem implicito o globale, il che rende più facile gestirlo nel codice ma non tra le dipendenze).
    • La registrazione sincrona non bloccante è garantita, anche se il registratore non li supporta. La consistenza causale della registrazione è probabilmente dovuta all'uso di un'unica cassetta postale per i consumatori. Tuttavia, la sicurezza della memoria e la contropressione non sono (credo che la registrazione di Akka usi una casella di posta illimitata) -
    • Ci sono opzioni come l'uso di uno DiagnosticLoggingAdapter per evitare la complessità della gestione dei propri MDC mentre il lavoro passa da attore ad attore. La coerenza dovrebbe essere preservata anche se il codice non attore modifica questi MDC.
    • registrazione non è probabile che sia disponibile nel corso di un incidente out-of-memoria, ed è sensibile a filo della fame, il dispatcher di default
    • sarà necessario specificare il logger scelto application.conf meno che non siate interessati in registrazione standard output

Hai la possibilità di combinare i comportamenti di cui sopra come necessario per soddisfare le vostre esigenze. Ad esempio, è possibile scegliere di associare a SLF4J per le librerie e utilizzare la registrazione di Akka per tutto il resto. È sufficiente notare che il mixaggio dei blocchi e la registrazione non bloccante potrebbe causare condizioni di gara in cui le cause (registrate asincrone tramite un attore) vengono registrate dopo i loro effetti (sincronizzazione registrata direttamente).