Spring Boot child()上下文的Logback分离

时间:2016-11-09 11:54:34

标签: spring logging spring-boot spring-integration logback

我正在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

2 个答案:

答案 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)中的logbackSiftingAppender结合使用。

下面我将解释它应该如何运作:

  1. MDC允许您拥有一个可用于根据其值分隔日志文件的鉴别器。在此阶段,您需要在执行子上下文中的任何顶层堆栈方法之前执行MDC.put('child-context-key', 'childContextId'),并在执行后执行MDC.remove('child-context-key')
  2. 之后,您可以配置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>
    
  3. 此外,您可以关注this example表单logback,其中显示了如何基于JNDI鉴别器为Web应用程序模块配置单独的日志文件。