2016-06-16 2 views
0

Является следующей безопасностью и хорошей практикой.Несколько WARs, совместно использующих один и тот же logback.xml

У меня есть несколько WARS (развернуть WebSphere 8.5.5) и хочет, чтобы разделить один logback.xml

-Dlogback.configurationFile=/opt/logback.xml -Dlogback.ContextSelector=JNDI

logback.xml использует SiftingAppender с JNDIBasedContextDiscriminator поэтому каждый WAR получает свой собственный файл журнала.

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

Каждый WAR web.xml будет contextName:

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

ответ

0

Я не знаю, если с помощью JNDI дискриминатора является безопасным или хорошей практикой, но это, кажется, путь Logback решает эту проблему : 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 доступна в виде локальной переменной потока, поэтому ее необходимо установить для каждого потока, инициированного веб-сервером.
Для этой инициализации я использовал 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, "/*"); 

    } 

} 

И файл Logback:

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