2017-08-31 2 views
3

Dans Logback, le niveau de journalisation d'un enregistreur peut être modifié avec la méthode setLevel(). Mais dans Logback, parce que les loggers sont singleton, l'appel de la méthode setLevel() affectera tous les autres threads qui utilisent le même logger.Comment modifier le niveau de journalisation uniquement pour le thread en cours avec Logback

Maintenant, j'ai une classe utilisée dans une application web comme celui-ci:

class FooService { 
    private void insertRecord(Foo foo) { 
     // insert one record to DB 
    } 

    public void insertOne(Foo foo) { 
     insertRecord(foo); 
    } 

    public void insertMany(List<Foo> foos) { 
     // I want to stop logging here 
     for (Foo foo: foos) { 
      insertRecord(foo); 
     } 
     // I want to resume logging here 
    } 
} 

Et au printemps ApplicationConfig.xml:

<bean id="traceAdvice" 
    class="org.springframework.aop.interceptor.CustomizableTraceInterceptor"> 
    <property name="enterMessage" 
    value="Entering $[targetClassShortName].$[methodName]($[argumentTypes])[$[arguments]]" /> 
    <property name="exitMessage" 
    value="Exiting $[targetClassShortName].$[methodName] : return = $[returnValue] : time = $[invocationTime]ms" /> 
    <property name="exceptionMessage" 
    value="Exception thrown in $[targetClassShortName].$[methodName] : $[exception]" /> 
</bean> 

<aop:config> 
    <aop:pointcut id="pointcut-service" 
    expression="execution(* my.app.service..*Service.*(..))" /> 
    <aop:advisor advice-ref="traceAdvice" pointcut-ref="pointcut-service" /> 
</aop:config> 

Je veux connecter appel InsertRecord de méthode insertOne. D'un autre côté, dans la méthode insertMany, je veux arrêter la journalisation juste avant la boucle (car cela pourrait générer énormément de logs), et reprendre la journalisation juste après la boucle. Mais si vous appelez setLevel() juste avant la boucle, la modification du niveau de journalisation affectera l'autre enregistreur utilisé dans d'autres threads. Dans cette situation, je pense que vous obtiendrez des logs décisifs sur les autres threads.

Ma question est: Comment changer le niveau de journal seulement pour l'enregistreur utilisé dans le fil en cours?

+0

Vous pouvez définir un appender spécifique pour votre forfait ou votre classe –

+0

Evidement, vous pouvez définir appender supplémentaire pour FooService de classe, mais s'il y a deux threads ou plus qui exécutent FooService simultanément, tous les threads sont affectés par setLevel(). C'est un résultat indésirable pour moi. – satob

Répondre

2

J'ai trouvé une solution. Vous pouvez utiliser MDC et TurboFilter à cette fin. MDC est thread-local et la modification de MDC n'affecte pas les autres threads.

Par exemple, si vous voulez arrêter toute l'activité de l'exploitation forestière, vous devez ajouter une définition de MDCFilter à logback.xml (Notez que <turboFilter> étiquette ne peut pas être un enfant d'une balise <appender>, et devrait être un enfant de <configuration> tag) :

<configuration> 
    <turboFilter class="ch.qos.logback.classic.turbo.MDCFilter"> 
     <MDCKey>tracing</MDCKey> 
     <Value>off</Value> 
     <OnMatch>DENY</OnMatch> 
    </turboFilter> 
    ...... 
</configuration> 

et vous pouvez/désactiver la journalisation par mettre/retirer une clé et une valeur de MDC comme celui-ci (Notez que vous devriez considérer au sujet exception dans l'utilisation réelle):

class FooService { 
    private void insertRecord(Foo foo) { 
     // insert one record to DB 
    } 

    public void insertOne(Foo foo) { 
     insertRecord(foo); 
    } 

    public void insertMany(List<Foo> foos) { 
     // I want to stop logging here 
     MDC.put("tracing", "off"); 
     for (Foo foo: foos) { 
      insertRecord(foo); 
     } 
     // I want to resume logging here 
     MDC.remove("tracing"); 
    } 
} 

Ou, si tu veux arrêt TRACE/debug/INFO/WARN journal, mais laisser erreur journal actif, vous pouvez utiliser DynamicThresholdFilter:

<configuration> 
    <turboFilter class="ch.qos.logback.classic.turbo.DynamicThresholdFilter"> 
     <Key>tracing</Key> 
     <DefaultThreshold>TRACE</DefaultThreshold> 
     <MDCValueLevelPair> 
     <value>off</value> 
     <level>ERROR</level> 
     </MDCValueLevelPair> 
    </turboFilter> 
    ...... 
</configuration> 
+0

Le DynamicThresholdFilter est exactement ce dont j'avais besoin, merci! – xtian