我正在Spring Boot中动态创建 child()上下文,我想将每个上下文记录到一个单独的文件中。这可能吗?
这样做的原因是因为我为不同的适配器提供了动态弹簧集成配置。这对于使用相同适配器配置的不同连接非常有用,但只有一个日志文件有很多信息。
我看到线程分离甚至是JNDI上下文分离,但我不知道最好的方法是什么。这可能只是配置logback.xml文件吗?
更新
也许选项是MDC,我不理解这个概念。例如,您是否可以解释如何为具有多个Spring Integration元素的Spring @MessageEndpoint
元素应用MDC,例如@Transformer
,@ServiceActivator
和@Router
,如下所示:
@MessageEndpoint
public class TestComponents {
private static final Logger LOGGER = LoggerFactory.getLogger(Test.class);
@Router(inputChannel = "inputRouter")
public MessageChannel router(Message<String> demo) {
..
LOGGER.trace(“TEST”);
…
LOGGER.error(“TEST”);
…
}
@ServiceActivator(inputChannel="inputService")
public void service(Message< String > demo) {
..
LOGGER.trace(“TEST”);
..
}
@Transformer(inputChannel="inputTransformer", outputChannel="outputTransformer")
public byte[] transformerToByte(Message<String> demo) {
..
LOGGER.debug(“TEST”);
..
}
}
该示例也适用于具有不同方法的@Component
。
由于文档中描述的paragraph,我担心性能问题:
请注意,由logback-classic实现的MDC假定为 值以中等频率放入MDC
答案 0 :(得分:0)
我认为这不容易做到。我没有很多Logback的经验,但我对Log4J,Spring,Tomcat和类加载非常熟悉。
Logback,就像log4J使用静态工厂方法生成单例记录器一样,这意味着静态状态存储在类加载器中。 在spring中,您可以指定使用哪个类加载来加载上下文,但是类加载器将只加载父类加载器无法加载的类/资源(如果重写URLClassLoader.getResource,您将发现这一点)。这是一个问题,因为当Spring Boot启动时,日志记录由“root”类加载器初始化和加载。
我可以看到你阻止这种情况的唯一方法是从类路径中删除logback jar,并创建一个新的URL类加载器(仅包含logback jar和配置),用于加载根Spring上下文和另一个类加载以进行加载子环境(同一罐子不同的配置)。由于logback jar不是系统类路径的一部分,因此您应该能够有两个单独的logback配置,因为static是由类加载器限定的。
修改强>
潜水更深一点我注意到由于LoggingSystem类的初始化方式(LogSystem line 126,版本1.4.1),有一个加载logback-core和logback-classic jar的类加载器是不够的,整个spring-boot jar(可能还有其他所有东西)都需要由同一个类加载器加载。这意味着您将无法使用通常用于运行spring boot应用程序的jar捆绑包。
答案 1 :(得分:0)
您可以将MDC (Mapped Diagnostic Context)
中的logback
与SiftingAppender
结合使用。
下面我将解释它应该如何运作:
MDC
允许您拥有一个可用于根据其值分隔日志文件的鉴别器。在此阶段,您需要在执行子上下文中的任何顶层堆栈方法之前执行MDC.put('child-context-key', 'childContextId')
,并在执行后执行MDC.remove('child-context-key')
。之后,您可以配置ch.qos.logback.classic.sift.SiftingAppender
,它将使用'child-context-key'
值作为鉴别器来分隔您的日志文件。
例如:
<appender name="CHILD-CONTEXT-SIFT-APPENDER" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator class="ch.qos.logback.classic.sift.MDCBasedDiscriminator">
<key>child-context-key</key>
<defaultValue>defaultChildContextId</defaultValue>
</discriminator>
<sift>
<appender name="CHILD-CONTEXT-SIFT-FILE-APPENDER"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/path/to/your/log/file/${child-context-key}.log
</file>
</sift>
</appender>
此外,您可以关注this example表单logback
,其中显示了如何基于JNDI鉴别器为Web应用程序模块配置单独的日志文件。