log4j根据输入内容自定义输出文件

问题背景

1、现有日志生成规则:debug到error四种级别,按照日期每天生成新的日志文件。
2、项目中日志打印不规范,部分日志没有唯一区分标识(例如流水号),在查找日志时,多个客户端的请求混在一起,难以分析。
3、客户希望能够根据客户端设备号进行分类输出日志。

log4j的执行流程分析

1、初始化配置文件流程

(1)调用:FileAppender类中的setFile(String fileName)方法设置this.fileName文件名(文件名来自配置文件)。
(2)调用:FileAppender类中的activateOptions方法,该方法中调用了setFile(fileName, fileAppend, bufferedIO, bufferSize) 里面包含了创建日志文件的方法。

2、每次调用写日志方法

调用WriterAppender类的subAppend(LoggingEvent event)方法。

解决方法

继承FileAppender,重写subAppend(LoggingEvent event)方法, 在里面调用setFile(fileName, fileAppend, bufferedIO, bufferSize),每次写日志时重新指定输出文件。

1、代码

public class MyFileAppender extends FileAppender {
    private Logger logger = Logger.getLogger(this.getClass());

    private void switchFilename(String datedFilename) throws IOException {
        try {
            setFile(datedFilename, getAppend(), getBufferedIO(), getBufferSize());
        } catch (IOException ex) {
            this.errorHandler.error("setFile(" + datedFilename + ", false) call failed.");
        }
        this.fileName = datedFilename;
    }

    protected void subAppend(LoggingEvent event) {
        String msg = (String) event.getMessage();
        // 如果日志中包含a,则重新指定生成文件;实际改为匹配
        if(msg.indexOf("a") != -1){
            try {
                switchFilename("E:/a.log");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        super.subAppend(event);
    }
}

2、配置文件

<appender name="debugLog" class="test_log4j.MyFileAppender">
	<param name="File" value="E:/debug.log" />
	<param name="Append" value="true" />
	<param name="Encoding" value="UTF-8" />
	<param name="DatePattern" value=".yyyy-MM-dd" />

	<layout class="org.apache.log4j.PatternLayout">
		<param name="ConversionPattern" value="%d [%-5p] %c [%t] - %m%n" />
	</layout>
</appender>

总结

1、最好的方法是规范日志输出,延用平时的方法记录日志,在记录日志的时候加上流水号,后期可利用代码或管理员直接在命令下操作提取分析日志信息。
2、并不是每个请求都会带设备号,如果是新项目的话,直接封装前端请求的公共方法进行统一处理;对于该项目,由于设备都处于内网,且固定IP,可根据IP进行区分。
3、只适用于设备量不是很多的情况下,如果设备量过多,又要考虑日志文件的存放问题,比如根据设备编号每1000个设备一个目录等。

你可能感兴趣的:(Java,java,log4j)