2010-06-04 3 views
8

D'abord un peu d'arrière-plan. J'ai un processus Java de type batch exécuté à partir d'un script batch DOS. Toute la journalisation java va sur stdout, et le script batch redirige la sortie standard vers un fichier. (Cela est bon pour moi parce que je peux ECHO du script et il entre dans le fichier journal, donc je peux voir tous les arguments de la ligne de commande Java, ce qui est excellent pour le débogage.) API, et pour le backend j'avais l'habitude d'utiliser log4j, mais récemment passé à logback-classic.log-back et thirdparty écrivant sur stdout. Comment les empêcher d'être entrelacés

Bien que tout le code de mon application utilise slf4j, j'ai une bibliothèque tierce qui effectue sa propre journalisation (sans utiliser une API standard) qui est également écrite sur stdout.

Le problème est que parfois les lignes de journal sont mélangées et n'apparaissent pas proprement sur des lignes séparées. Voici un exemple d'une sortie foiré:

2010-05-28 18:00:44.783 [thread-1  ] INFO CreditCorrelationElementBuilderImpl - Bump parameters exist for scenario, now attempting bumping. [indexDisplayName=STANDARD_S1_v300] 
2010-05-28 18:01:43.517 [thread-1  ] INFO CreditCorrelationElementBuilderImpl - Found adjusted point in data, now applying bump. [point=0.144040000000000] 
2010-05-28 18:01:58.642 [thread-1  ] DEBUG com.company.request.Request   - Generated request for [dealName=XXX_20050225_01[5],dealType=GENERIC_XXX,correlationType=2,copulaType=1] in 73.8 s, Simon Stopwatch: [sys1.batchpricer.reqgen.gen INHERIT] total 1049 s, counter 24, max 74.1 s, min 212 ms 
2010-05-28 18:05/28/10 18:02:20.236 INFO: [ServiceEvent] SubmittedTask:BC-STRESS_04_FZBC-2010-05-21-545024448189310126-23 
01:58.658 [req-writer-2b ] INFO .c.g.r.o.OptionalFileDocumentOutput - Writing request XML to \\filserver\dir\file1.xml - write time: 21.4 ms - Simon Stopwatch: [sys1.batchpricer.reqgen.writeinputfile INHERIT] total 905 ms, counter 24, max 109 ms, min 10.8 ms 
2010-05-28 18:02:33.626 [ResponseCallbacks-1: DriverJobSpace$TakeJobRunner$1] ERROR c.c.s.s.D.CalculatorCallback  - Id:23 no deal found !! 
2010-0505/28/10 18:02:50.267 INFO: [ServiceEvent] CompletedTask:BC-STRESS_04_FZBC-2010-05-21-545024448189310126-23:Total:24 

maintenant comparer revenir aux fichiers journaux les plus anciens, il semble que le problème ne se produit lors de l'utilisation log4j comme base de l'exploitation forestière. Donc, le logback doit faire quelque chose de différent.

Le problème semble être que bien que PrintStream.write(byte buf[], int off, int len) est synchronisé, mais je peux voir dans ch.qos.logback.core.joran.spi.ConsoleTarget that System.out.write(int b) est la seule méthode d'écriture appelée.

Donc, entre le logback de sortie de chaque octet, la bibliothèque thirdparty parvient à écrire une chaîne entière dans la sortie standard. (Non seulement cela me cause un problème, mais il doit aussi être un peu inefficace?)

Y at-il une autre solution à ce problème d'entrelacement que de patcher le code à ConsoleTarget afin qu'il implémente les autres méthodes d'écriture? Tout beau travail autour. Ou devrais-je simplement déposer un rapport de bogue?

Voici mon logback.xml:

<configuration> 
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
     <encoder> 
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-16thread] %-5level %-35.35logger{30} - %msg%n</pattern> 
     </encoder> 
    </appender> 
    <root level="DEBUG"> 
     <appender-ref ref="STDOUT" /> 
    </root> 
</configuration> 

J'utilise logback 0.9.20 avec java 1.6.0_07.

+0

Hmm, mes préformatés blocs de code viennent par une seule ligne, mais ils étaient bien dans l'aperçu! Humpf! –

+0

David, vous pouvez éditer cette question encore, employez verbatim si vous devez. –

+0

Vous avez une référence ou un exemple sur verbatim? Voulez-vous dire utiliser un bloc non-code? –

Répondre

0

Il semble que vous ayez deux configurations de journal différentes en écrivant dans STDOUT. Le motif de ces deux semble être très différent en essayant de décoder le désordre:

2010-05-28 18:01:58.658 [req-writer-2b ] INFO .c.g.r.o.OptionalFileDocumentOutput - Writing request XML to \\filserver\dir\file1.xml - write time: 21.4 ms - Simon Stopwatch: [sys1.batchpricer.reqgen.writeinputfile INHERIT] total 905 ms, counter 24, max 109 ms, min 10.8 ms 
05/28/10 18:02:20.236 INFO: [ServiceEvent] SubmittedTask:BC-STRESS_04_FZBC-2010-05-21-545024448189310126-23 

La deuxième ligne semble utiliser le modèle par défaut au lieu de votre définition. Y a-t-il un enregistreur chargé quelque part qui utilise la configuration par défaut au lieu de votre configuration XML?

+0

L'autre motif provient de la partie tierce lib. Mais ce n'est pas le modèle qui me dérange, c'est les lignes foirées. Peu importe, j'ai corrigé le logback pour corriger le problème maintenant. Merci. –

2

Dans ce cas, je passerais par System.setOut (PrintStream out) pour la bibliothèque tierce donné qui ne se comporte pas. Implémentez un thread qui lirait ce flux de journaux en le divisant par une nouvelle ligne et en le crachant à la solution de journalisation que vous utilisez. Faites juste attention à ne pas commencer à lire et à écrire au même fil :-) c'est ce que vous faites:

  • Vous obtenez le flux System.out enregistrez-le de côté
  • Vous configurez votre enregistreur à utiliser stream voir OutputStreamAppender
  • Vous créez un thread qui draine un flux que vous affectez en tant que nouveau système.out (votre 3ème partie lib y écrire) et envoyer ainsi une sortie formatée dans le journal

Vous vous avez un joli journal en synchronisation plus ou moins avec ce qui se passe dans le système

+0

Merci Boris, vous avez eu une bonne idée là-bas, malheureusement, c'était plus de travail que de régler le problème du code. J'ai upvoted, mais pas accepté votre réponse. –

Questions connexes