多个 WAR 共享相同的登录.xml



以下登录设置是否安全且良好。

我有多个 WAR(已部署 WebSphere 8.5.5),并希望它们共享一个logback.xml

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

logback.xml使用带有JNDIBasedContextDiscriminatorSiftingAppender,因此每个 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>

每个战争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>

我不知道使用 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 映射可用作线程局部变量,因此必须为 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>

注册可以是例如在 spring 安全初始值设定项中:

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

最新更新