gpt4 book ai didi

java - 如何使用 Logback 仅更改当前线程的日志级别

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:34:26 25 4
gpt4 key购买 nike

在 Logback 中,可以使用 setLevel() 方法更改记录器的日志级别。但是在 Logback 中,因为记录器是单例的,调用 setLevel() 方法会影响到所有其他使用相同记录器的线程。

现在我有一个用于 Web 应用程序的类,如下所示:

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
}
}

在 Spring 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] with return value $[returnValue], took $[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>

我想记录 insertOne 方法对 insertRecord 的调用。另一方面,在 insertMany 方法中,我想在循环之前停止记录(因为它可能会输出大量日志),并在循环之后恢复记录。但是如果你在循环之前调用 setLevel() ,日志级别的变化将影响其他线程中使用的其他记录器。在这种情况下,我认为您会在其他线程上获得不足的日志。

我的问题是:如何只更改当前线程中使用的记录器的日志级别?

最佳答案

我找到了一个解决方案。为此,您可以使用 MDC 和 TurboFilter。 MDC 是线程本地的,对 MDC 的更改不会影响其他线程。

例如,如果你想停止所有的日志记录 Activity ,你必须在 logback.xml 中添加 MDCFilter 的定义。 (注意 <turboFilter> 标签不能是 <appender> 标签的子标签,而应该是 <configuration> 标签的子标签):

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

并且你可以像这样通过向 MDC 中放置/删除一个键和一个值来打开/关闭日志记录(注意你应该在实际使用中考虑异常):

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");
}
}

或者,如果你想停止 TRACE/DEBUG/INFO/WARN 日志但让 ERROR 日志保持 Activity 状态,你可以使用 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>

关于java - 如何使用 Logback 仅更改当前线程的日志级别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45986024/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com