简体   繁体   English

Log4j 配置过滤日志到多个文件

[英]Log4j config to filter logs to multiple files

I am trying to route specific logs to different files based on a pattern within the log using Log4j 1.2.17 on a JDK1.6 application.我正在尝试在 JDK1.6 应用程序上使用 Log4j 1.2.17 根据日志中的模式将特定日志路由到不同的文件。 I found that the solution mentioned on posts here and here say the below configuration done within the log4j xml should work along with MDC context but for some reason they have no effect on the filter and the logs end up getting routed to both the console and the file.我发现这里这里的帖子中提到的解决方案说在 log4j xml 中完成的以下配置应该与 MDC 上下文一起工作,但由于某种原因,它们对过滤器没有影响,并且日志最终被路由到控制台和文件。

My java code looks like below:我的 java 代码如下所示:

@RequestMapping(value = "/fetchBookById",  method = RequestMethod.GET, produces="application/json")
public @ResponseBody Map<String,? extends Object> bookApi(ParamDTO params) throws InterruptedException {
    
    log.info("SimpleBookController.bookApi: THIS IS A COMMON LOG");
     Map<String,Object> rxdMap = null;
    try{
        //This below will put either ABCD or EFGH etc
        MDC.put("COMPANYNAME", companyMap.get(params.getCompanyOwnerId()));
        
        log.info("SimpleBookController.bookApi: THis is test with routing");
        log.info("SimpleBookController.bookApi: Payload: "+params.toString());
        
        //do something here
        log.info("SimpleBookController.bookApi API completed for :"+params.getCompanyOwnerId());
        
    } finally {
        MDC.clear();
    }
     return rxdMap;
}

Log4j.xml: Log4j.xml:

<appender name="console" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%t] COMPANYNAME:%X{COMPANYNAME} %-5p - %m%n" />
    </layout>
    <filter class="org.apache.log4j.varia.StringMatchFilter">
        <param name="StringToMatch" value="COMPANYNAME:"/>
        <param name="AcceptOnMatch" value="false"/>
    </filter>
</appender>
<appender name="file" class="org.apache.log4j.RollingFileAppender">
    <param name="File" value="./logs/company.log" />
    <param name="Append" value="true" />
    <param name="ImmediateFlush" value="true" />
    <param name="MaxFileSize" value="10MB" />

    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%t] COMPANYNAME:%X{COMPANYNAME} %-5p - %m%n" />
    </layout>
    <filter class="org.apache.log4j.varia.StringMatchFilter">
        <param name="StringToMatch" value="COMPANYNAME:ABCD"/>
        <param name="AcceptOnMatch" value="true"/>
    </filter>
    <filter class="org.apache.log4j.varia.DenyAllFilter"/>
</appender>
 <root>
    <level value="info" />
    <appender-ref ref="file" />
    <appender-ref ref="console" />
</root>

In the above configuration I am trying to route any logs that do not have "COMPANYNAME:" string to console and the logs that have "COMPANYNAME:ABCD" should route to a specific file.在上面的配置中,我试图将任何没有“COMPANYNAME:”字符串的日志路由到控制台,而具有“COMPANYNAME:ABCD”的日志应该路由到特定文件。 But both console and the file Appender end up having all the logs irrespective of the string pattern.但是无论字符串模式如何,控制台和文件 Appender 最终都会拥有所有日志。 Much appreciated if anyone can point me in the right direction.如果有人能指出我正确的方向,将不胜感激。

Sample logs:示例日志:

2022-07-11 21:29:44 [[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'] COMPANYNAME: INFO  - FrameworkServlet 'TestJDK6Logging': initialization completed in 423 ms
2022-07-11 21:29:56 [[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'] COMPANYNAME: INFO  - SimpleBookController.bookApi: THIS IS A COMMON LOG
2022-07-11 21:29:56 [[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'] COMPANYNAME:ABCD INFO  - SimpleBookController.bookApi: THis is test with routing
2022-07-11 21:29:56 [[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'] COMPANYNAME:ABCD INFO  - SimpleBookController.bookApi: Payload: ParamDTO [identifier=sdfdf, bookId=1, companyOwnerId=4]
2022-07-11 21:30:01 [[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'] COMPANYNAME:ABCD INFO  - SimpleBookController.bookApi API completed for :4

I ended up creating custom filter for console and logs to divert the log stream based on MDC map value, and this solved the filtering problem.我最终为控制台和日志创建了自定义过滤器,以根据 MDC 映射值转移日志流,这解决了过滤问题。 This idea came from @KC Baltz from this post .这个想法来自这篇文章的@KC Baltz。

My log4j.xml looks as below:我的 log4j.xml 如下所示:

<appender name="console" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p - %m%n" />
        </layout>
        
        <!-- This is custom console filter, modify decide() function accordingly -->
        <filter class="com.lumn.logtest.web.common.Log4JConsoleFilter">
            <param name="keyToMatch" value="COMPANYNAME" />
            <param name="valueToMatch" value="" />
            <param name="acceptOnMatch" value="false" />
        </filter>
    </appender>

    <appender name="LUMN" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="./logs/lumen.log" />
        <param name="Append" value="true" />
        <param name="ImmediateFlush" value="true" />
        <param name="MaxFileSize" value="10MB" />

        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p - %m%n" />
        </layout>

        <!-- This is custom company filter, modify decide() function accordingly -->
        <filter class="com.lumn.logtest.web.common.Log4JCompanyFilter">
            <param name="keyToMatch" value="COMPANYNAME" />
            <param name="valueToMatch" value="ABCD" />
            <param name="acceptOnMatch" value="true" />
        </filter>
    </appender>

And my custom Filters Log4JConsoleFilter and Log4JCompanyFilter are as below:我的自定义过滤器 Log4JConsoleFilter 和 Log4JCompanyFilter 如下:

public class Log4JConsoleFilter extends Filter {

private String keyToMatch;
private String valueToMatch;
private boolean acceptOnMatch = true;

@Override
public int decide(LoggingEvent event) {
    
    //Modify this condition based on the need, there is room for improvement to reduce number of conditions.
    if (keyToMatch == null || valueToMatch == null)
        return Filter.NEUTRAL;
    else {
        if(event.getMDC(keyToMatch) == null)
            return Filter.NEUTRAL;
        else{ 
            //MDC has value
            return acceptOnMatch ? Filter.ACCEPT: Filter.DENY;
        }
    }
}
public String getKeyToMatch() {
    return keyToMatch;
}

public void setKeyToMatch(String keyToMatch) {
    this.keyToMatch = keyToMatch;
}

public String getValueToMatch() {
    return valueToMatch;
}

public void setValueToMatch(String valueToMatch) {
    this.valueToMatch = valueToMatch;
}

public boolean isAcceptOnMatch() {
    return acceptOnMatch;
}

public void setAcceptOnMatch(boolean acceptOnMatch) {
    this.acceptOnMatch = acceptOnMatch;
}

} }

public class Log4JCompanyFilter extends Filter {

private String keyToMatch;
private String valueToMatch;
private boolean acceptOnMatch = true;

@Override
public int decide(LoggingEvent event) {  
    if (keyToMatch == null || valueToMatch == null)
        return Filter.DENY;
    else {
        if (valueToMatch.equals(event.getMDC(keyToMatch)))
            return acceptOnMatch ? Filter.ACCEPT: Filter.DENY;
        else
            return Filter.DENY;             
    }
}

public String getKeyToMatch() {
    return keyToMatch;
}

public void setKeyToMatch(String keyToMatch) {
    this.keyToMatch = keyToMatch;
}

public String getValueToMatch() {
    return valueToMatch;
}

public void setValueToMatch(String valueToMatch) {
    this.valueToMatch = valueToMatch;
}

public boolean isAcceptOnMatch() {
    return acceptOnMatch;
}

public void setAcceptOnMatch(boolean acceptOnMatch) {
    this.acceptOnMatch = acceptOnMatch;
}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM