当前位置: 首页 > 知识库问答 >
问题:

多个WAR共享同一个logback.xml

毛越
2023-03-14
<appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
    <discriminator class="ch.qos.logback.classic.sift.JNDIBasedContextDiscriminator">
        <defaultValue>unknown</defaultValue>
    </discriminator>
    <sift>
        <appender name="FILE-${contextName}" class="ch.qos.logback.core.FileAppender">
            <file>/var/log/${contextName}.log</file>
            <encoder>
                <pattern>%-50(%level %logger{35}) cn=%contextName - %msg%n</pattern>
            </encoder>
        </appender>
    </sift>
</appender>
<env-entry>
  <description>JNDI logging context for this app</description>
  <env-entry-name>logback/context-name</env-entry-name>
  <env-entry-type>java.lang.String</env-entry-type>
  <env-entry-value>ContextNameWebAppA</env-entry-value>
</env-entry>

共有1个答案

暴夕
2023-03-14

我不知道使用Jndi鉴别器是安全的还是好的做法,但它似乎是日志返回解决此问题的方法:http://Logback.qos.ch/manual/loggingseparation.html
它们表明将其添加到配置中可以获得更好的性能:

<filter>
  <filter-name>LoggerContextFilter</filter-name>
  <filter-class>ch.qos.logback.classic.selector.servlet.LoggerContextFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>LoggerContextFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

另一方面,我可以分享如何避免设置系统属性logback.contextSelector=jndi

相反,我使用MDCBasedDiscriminator,它将获得用MDC.put(key,value)定义的判别值。
MDC映射作为线程局部变量可用,因此必须为web服务器发起的每个线程设置它。
对于这个初始化,我使用了放在其他筛选器之前的javax.servlet.filter,这个筛选器将正确的值放入MDC。

我不认为这比您所做的更好,但它是JNDI属性的一种替代方法,问题是关闭日志位于unknown.log中。

下面是一些代码:

public class WarLoggingFilter implements Filter {
    private static final String WAR_NAME_ATTRIBUTE = "WAR_NAME";
    private String warName;

    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {
        warName = filterConfig.getInitParameter(WAR_NAME_ATTRIBUTE);
    }

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
            throws IOException, ServletException {
        insertIntoMDC(warName);
        chain.doFilter(request, response);
    }

    private void clearMDC() {
        MDC.remove(WAR_NAME_ATTRIBUTE);
    }

    private static void insertIntoMDC(final String warName) {
        MDC.put(WAR_NAME_ATTRIBUTE, warName);
    }

    @Override
    public void destroy() {
        clearMDC();
    }


    /**
     * Register this filter in the servlet context. Adds the necessary init
     * parameter.
     *
     * @param warName
     * @param servletContext
     */
    public static void registerMe(final String warName, final ServletContext servletContext) {
        // MDC for the startup thread
        insertIntoMDC(warName);
        // MCD for next threads
        final Dynamic addFilter = servletContext.addFilter(warName, WarLoggingFilter.class);
        addFilter.setInitParameter(WarLoggingFilter.WAR_NAME_ATTRIBUTE, warName);
        addFilter.addMappingForUrlPatterns(null, false, "/*");

    }

}

和日志文件:

<appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
        <discriminator class="ch.qos.logback.classic.sift.MDCBasedDiscriminator">
            <key>WAR_NAME</key>
            <defaultValue>unknown</defaultValue>
        </discriminator>
        <sift>
            <appender name="FILE-${WAR_NAME}" class="ch.qos.logback.core.FileAppender">
                <file>/tmp/${WAR_NAME}.log</file>
                <encoder>
                    <pattern>%date{ISO8601} %-5level %logger{30}\(%line\) - %message%n</pattern>
                </encoder>
            </appender>
        </sift>
    </appender>
public class MySecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

    /**
     * Invoked before the springSecurityFilterChain is added.
     *
     * @param servletContext
     *            the {@link ServletContext}
     */
    @Override
    protected void beforeSpringSecurityFilterChain(final ServletContext servletContext) {
        // Tell logback to log this web app events in a separate file
        WarLoggingFilter.registerMe("my_webapp", servletContext);
    }
 类似资料:
  • 我有一个运行在400个TaskManager上的flink应用程序。在1小时的窗口时间内,我会更频繁地获得相同的密钥,比如说,在1500个唯一密钥中,有50个密钥会更频繁地出现。这使得很少有任务管理者单独处理的数量比其他人多。如果390个TaskManager每分钟处理50MB,那么其他10个TaskManager每分钟处理10GB。这使得系统速度非常慢。如果负载很高,我们可以与多个TaskMan

  • 问题内容: 我有多个具有相似构建步骤的项目,并且我正在研究在这些项目中重用Jenkinsfile管道。我很难找到有关如何实现这样的标准(我认为)设置的文档。 这是我的要求: 1)Jenkinsfile存储在回购中,在多个项目之间共享 2)每个项目都有其自己的参数:项目在仓库中的位置。 3)至少从用户角度来看,每个项目在Jenkins中都应独立,这意味着,例如,执行和日志可在Jenkins中的每个项

  • 我知道这是一个非常简单的问题,但由于我是Wildfly的新手,我还没有成功地完成它。 在JBoss 4.2的旧时代,当我想与多个war文件共享一个ejb jar文件时,我只是将ejb jar文件部署到应用服务器上,并在war项目中使用文件“jndi”配置jndi。属性放置在war文件的某个源目录中,如下所示: 现在,在Wildfly 8.1中,这种方法不再有效。我不知道jndi属性文件的内容是否发

  • 我使用jsPlumb允许用户构建图形。我允许用户拖动这些元素,所以我为每个endpoint使用锚集合,让jsPlumb在建立连接时从该集合中为我选择“最佳”锚。我遇到的问题是,我可能有多达十几个连接来自任何给定的endpoint,所以当许多人最终选择相同的“最佳”锚点时,这些连接将在视觉上分散注意力——在图中造成拥塞的外观。为了解决这个问题,我想告诉jsPlumb限制任何两个连接在endpoint

  • 问题内容: 说我有a.so和b.so。我是否可以将c.so生成为具有a和b导出的所有功能的单个共享库,当然可以解决所有内部依赖关系(即a.so调用的b.so的所有功能,反之亦然)? 我试过了 但这不起作用。 如果我在aa和ba中归档ao和bo(也不应修改ao和bo),也是如此 谢谢 问题答案: 除了AIX之外,在所有UNIXen上实际上都不可能将多个共享库合并为一个:链接器将.so视为“最终”产品

  • 可以合并多个共享Jenkins库吗? 例如,我有一个公共共享库:我的共享库(带有maven项目的git存储库)定义在包含一些作业的jenkins文件夹上。在该文件夹中运行的每个作业都可以使用Jenkins文件中的共享库,包括: 现在,我想创建另一个共享库:包含一些专门管道的my-专门化共享库(在另一个git存储库中,也作为maven项目)。我的专用共享库中的管道(groovy类、脚本等)应该能够使