在同一个JVM中启动两个Spring应用程序会导致日志行数翻倍。

huangapple go评论62阅读模式
英文:

Starting two spring applications in same JVM results in doubled log lines

问题

我尝试在同一JVM中启动两个Spring应用程序,除了现在每个日志行都会写两次,所以对于同时为两个应用程序编写的日志行,实际上会写四次。

我还尝试查看连接到记录器的附加器,我得到了两次STDOUT,这可以解释这种行为。

似乎两次启动Spring会导致Logback初始化两次,而不会重置第一次的初始化。

是否有一种方法可以抑制这种行为?我甚至没有想到Spring会手动初始化它。

我用于启动两个应用程序的代码(MainSecondaryMain位于两个独立的包中,彼此不包含):

public static void main(String[] args) throws Exception
{
    run("App1", Main.class, args);
    run("App2", SecondMain.class, args);
}

private static void run(String name, Class<?> clazz, String[] args)
{
    SpringApplication run = new SpringApplication(clazz);

    ThreadGroup threadGroup = new ThreadGroup(name);
    Thread t = new Thread(threadGroup, () -> {run.run(args);}, name+".Main");
    t.start();
}

我的Logback配置(没有特别的内容):

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

I've tried to start two Spring applications in the same JVM which worked fine except that now every log line is written twice, so in case of log line that are written for both applications are written four times effectivly.

I've also tried to see what appenders are attached to the loggers an I got STDOUT two times in it which would explain the behaviour.

It seems like starting spring twice ends up initializing logback twice without resetting the first initialization.

Is there some way to suppress this behaviour? I didn't even think that spring would manually initialize it.

The code I used to start the two applications (Main and SecondaryMain are in two indepenant packages, neither contained in the other):

    public static void main(String[] args) throws Exception
    {
        run(&quot;App1&quot;, Main.class, args);
        run(&quot;App2&quot;, SecondMain.class, args);
    }

    private static void run(String name, Class&lt;?&gt; clazz, String[] args)
    {
        SpringApplication run = new SpringApplication(clazz);

        ThreadGroup threadGroup = new ThreadGroup(name);
        Thread t = new Thread(threadGroup, () -&gt; {run.run(args);}, name+&quot;.Main&quot;);
        t.start();
    }

My logback configuration (nothing special):

&lt;configuration&gt;
    &lt;appender name=&quot;STDOUT&quot; class=&quot;ch.qos.logback.core.ConsoleAppender&quot;&gt;
        &lt;encoder&gt;
            &lt;pattern&gt;%d{yyyy-MM-dd&#39; &#39;HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n&lt;/pattern&gt;
        &lt;/encoder&gt;
    &lt;/appender&gt;
    &lt;root level=&quot;info&quot;&gt;
        &lt;appender-ref ref=&quot;STDOUT&quot; /&gt;
    &lt;/root&gt;
&lt;/configuration&gt;

答案1

得分: 0

与此同时,我已经找到了两种实现它的方法。

禁用Spring中的日志管理

可以指定Spring应该使用的日志系统,但也有一个选项是 none,这样它就不会设置任何日志系统,也不会重复设置两次。

缺点是它不会集成日志记录,在我的情况下,一些以前记录到logback的组件突然不再记录日志了。

使用父上下文

如果两个应用共享一个父上下文,Spring将只初始化日志记录一次。

这似乎是更清晰的解决方案,我还没有看到任何缺点。

英文:

In the meanwhile I've found two ways to accomplish it

disabling logging management in spring

One can specify the logging system that spring should use but there's also the option none so it won't set up any itself and that way also not twice

The con is that it won't integrate logging, in my case some components that used to log to logback suddenly didn't.

using a parent context

If both applications share a parent contract spring will only initialize logging once

This seems to be the cleaner solution and I haven't seen a con to it yet

huangapple
  • 本文由 发表于 2020年9月19日 20:41:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/63968911.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定