Dans notre logiciel, nous utilisons largement MDC pour suivre des éléments tels que les identifiants de session et les noms d'utilisateur pour les demandes Web. Cela fonctionne bien lors de l'exécution dans le thread d'origine. Cependant, il y a beaucoup de choses qui doivent être traitées en arrière-plan. Pour cela , nous utilisons java.concurrent.ThreadPoolExecutor
et les java.util.Timer
classes ainsi que quelques async roulées services d'exécution. Tous ces services gèrent leur propre pool de threads.
Voici ce que le manuel de Logback a à dire sur l'utilisation de MDC dans un tel environnement:
Une copie du contexte de diagnostic mappé ne peut pas toujours être héritée par les threads de travail du thread initiateur. C'est le cas lorsque java.util.concurrent.Executors est utilisé pour la gestion des threads. Par exemple, la méthode newCachedThreadPool crée un ThreadPoolExecutor et, comme tout autre code de regroupement de threads, elle a une logique de création de thread complexe.
Dans de tels cas, il est recommandé que MDC.getCopyOfContextMap () soit appelé sur le thread d'origine (maître) avant de soumettre une tâche à l'exécuteur. Lorsque la tâche s'exécute, en tant que première action, elle doit appeler MDC.setContextMapValues () pour associer la copie stockée des valeurs MDC d'origine au nouveau thread géré par Executor.
Ce serait bien, mais il est très facile d'oublier l'ajout de ces appels, et il n'y a pas de moyen facile de reconnaître le problème avant qu'il ne soit trop tard. Le seul signe avec Log4j est que vous obtenez des informations MDC manquantes dans les journaux, et avec Logback, vous obtenez des informations MDC périmées (puisque le thread dans le pool de bandes de roulement hérite de son MDC de la première tâche qui a été exécutée dessus). Les deux sont de graves problèmes dans un système de production.
Je ne vois aucunement notre situation particulière, mais je n'ai pas pu trouver grand-chose sur ce problème sur le Web. Apparemment, ce n'est pas quelque chose contre quoi beaucoup de gens se heurtent, il doit donc y avoir un moyen de l'éviter. Que faisons-nous de mal ici?