web-dev-qa-db-fra.com

Akka Logging dehors Acteur

J'ai un acteur Akka qui appelle à MyObject.foo(). MyObject n'est pas un acteur. Comment configurer la connexion? Avec un acteur, c'est simple, parce que je peux mélanger ActorLogging. Dans MyObject, je n'ai pas accès à context.system. Est-ce que je crée un akka.event.Logging avec AkkaSystem (), puis quoi pour l'implicite LogSource?

43
Bradford

En fait, je redirigerais la journalisation Akka vers slf4j et utiliserais cette API directement dans toutes les classes non liées. Ajoutez d'abord ceci à votre configuration:

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

Ensuite, choisissez une implémentation de SLF4J, je suggère logback . Dans vos acteurs, continuez à utiliser le trait ActorLogging. Dans d'autres classes, vous utilisez simplement l'API SLF4J - ou même mieux - essayez slf4s façade autour de SLF4J.

Conseil: essayez le modèle de journalisation suivant dans Logback:

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

Le %X{akkaSource} imprimera le chemin de l'acteur lorsqu'il sera disponible (tout comme la journalisation standard).

25
Tomasz Nurkiewicz

En utilisant Akka 2.2.1, j'ai pu mettre cela dans mon application pour que la journalisation se fasse en dehors d'un acteur:

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

Cela semble être une solution plus simple pour unifier la journalisation d'une application.

21
bnsmith

J'ai maintenant décidé de simplement passer mon système de journalisation central par injection de constructeur de DI (Guice). Et dans mes cours qui se connectent régulièrement (où l'asynchronicité est importante), je prends le système Actor injecté et appelle le 

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

dans le constructeur de classes.

8
Antony Stubbs

Comme cela a été mentionné, vous avez l'embarras du choix pour la journalisation sans acteur dans un système d'acteur. Je vais essayer de vous fournir un ensemble d'heuristiques pour vous aider à déterminer la route à suivre pour la journalisation de votre travail.

  1. Vous pouvez utiliser un enregistreur (log4j 1.x, logback, log4j 2.x) directement dans le code acteur et non acteur.
    • Cela associe étroitement votre code à une implémentation d'enregistreur. C'est bien s'il s'agit de votre code, ne pas l'utiliser ailleurs, mais pas si vous construisez une bibliothèque ou avez l'intention d'ouvrir votre travail en source.
    • Si vous faites cela, vous ne tirerez aucun avantage du système d'acteur. Les appels de journalisation peuvent devenir des appels bloquants, selon la configuration de votre enregistreur. Ce point est donc mal vu lorsque les performances ou le contrôle de la contre-pression sont des préoccupations importantes.
    • Étant donné que le code d'acteur (ainsi que les services qu'il peut consommer) peut fonctionner sur plusieurs threads différents, certaines activités de journalisation traditionnelles telles que l'utilisation d'un MDC local (contexte de diagnostic mappé) peuvent entraîner des conditions de concurrence étranges et un changement de contexte avec des journaux générés à partir de messages passer d'acteur à acteur. Des activités telles que la permutation de MDC sur des messages avant de les envoyer peuvent devenir nécessaires pour préserver le contexte entre le code acteur et le code non acteur.
    • Pour capturer les événements ActorSystem tels que les lettres mortes et la supervision, vous devrez peut-être écrire un adaptateur de journalisation et le spécifier dans votre application.conf. Celles-ci sont assez simples.
  2. Vous pouvez utiliser la façade SLF4J pour la journalisation à la fois acteur et non acteur.
    • Vous n'êtes plus associé à un enregistreur et, en plus, vos services ne sont pas associés à l'akka. C'est la meilleure option pour la portabilité.
    • Vous pouvez hériter du comportement de blocage de votre infrastructure de journal.
    • Vous devrez peut-être gérer les MDC
    • Pour capturer les événements ActorSystem, vous devez spécifier "akka.event.slf4j.Slf4jLogger" dans votre application.conf.
    • Vous aurez besoin d'inclure un fichier jar du fournisseur slf4j sur le chemin d'accès aux classes pour router les événements de journal slf4j vers le journal choisi.
  3. Vous pouvez utiliser la journalisation d’Akka comme façade dans les codes acteur et non acteur
    • Vous n'êtes pas couplé à un enregistreur impl OR à slf4j, mais vous êtes couplé à une version de akka. Ceci est probablement une exigence de votre système, mais cela pourrait réduire la portabilité pour les bibliothèques.
    • Vous devez faire passer un système d'acteur pour agir en tant que "bus" pour les enregistreurs. Un couplage étroit à un système d'acteur en fonctionnement réduit encore la portabilité. (Dans une application, je construis généralement un petit trait LoggingViaActorSystem avec un ActorSystem implicite ou global, ce qui facilite le traitement dans le code mais pas entre les dépendances).
    • La journalisation aynchrone non bloquante est garantie, même si votre consignateur ne les prend pas en charge. La cohérence causale de la journalisation est probablement due à l'utilisation d'une seule boîte aux lettres de consommateur. Cependant, la sécurité de la mémoire et la pression de retour ne sont pas (je pense que la journalisation Akka utilise une boîte aux lettres sans limite) - 
    • Il existe des options telles que l’utilisation de DiagnosticLoggingAdapter pour éviter la complexité de la gestion de vos propres MDC lorsque le travail passe d’un acteur à l’autre. La cohérence doit être préservée même lorsque le code non acteur mute ces MDC.
    • Il est peu probable que la journalisation soit disponible lors d'une panne de mémoire insuffisante et elle est sensible à la privation de threads du répartiteur par défaut.
    • Vous devrez spécifier votre enregistreur choisi dans application.conf, sauf si vous souhaitez vous connecter à la sortie standard.

Nous vous invitons à associer les comportements ci-dessus pour répondre à vos besoins. Par exemple, vous pouvez choisir de vous connecter à SLF4J pour les bibliothèques et d'utiliser la journalisation Akka pour tout le reste. Il suffit de noter que le fait de combiner l'enregistrement avec blocage et l'enregistrement sans blocage peut provoquer des conditions de concurrence fâcheuses où les causes (enregistrées de manière asynchrone via un acteur) sont enregistrées après leurs effets (synchronisées directement avec les utilisateurs enregistrés).

8
Matthew Mark Miller

créez simplement votre propre enregistreur:

private val log = LoggerFactory.getLogger(YourClass.getClass)
0
Mohsen Kashi