前两天系统要求业务逻辑日志和数据库sql日志分开打印。
项目日志用的log4j2,架构为SSM架构,代码结构遵循MVC模式即每个业务模块都有单独的包结构,每个业务包下都有serivce、dao等包结构,要单独打印sql日志就要筛选出每个业务包结构下的dao包里的日志,但糟糕的是log4j2没有通配符,包路径不能com.**.dao.**这样写,所以需要用到自定义过滤器实现日志过滤,下面是我增加的log4j2配置。
话不多说,上代码:
1.log4j2.xml配置
<?xml version="1.0" encoding="UTF-8"?>
注意加上下方包扫描路径为自定义filter所在包路径
<configuration status="WARN" monitorInterval="30" packages ="com.aaa.bbb.core.log4j2.filter">
<Properties>
<!-- 配置日志文件输出目录,此配置将日志输出到tomcat根目录下的指定文件夹 -->
<Property name="LOG_HOME">${sys:catalina.home}/logs</Property>
<property name="pattern">%d{yyyy/MM/dd HH:mm:ss.SSS} [%p] %t %c %m%n</property>
</Properties>
<appenders>
<RollingRandomAccessFile name="sqlLogger"
<!--日志文件名-->
fileName="${LOG_HOME}/mybatis-sql.log"
<!--分割后的日志文件名-->
filePattern="${LOG_HOME}/mybatis-sql-%d{yyyy-MM-dd}.log"
append="true">
<Filters>
<!-- 自定义过滤器,只打印dao包内日志
onMatch="NEUTRAL"代表通过过滤器校验后进入下一个过滤器
onMismatch="DENY"代表未通过的日志直接不打印-->
<ClassPathFilter pathName=".dao." onMatch="NEUTRAL" onMismatch="DENY"/>
</Filters>
<PatternLayout pattern="${pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
日志分割大小设置
<SizeBasedTriggeringPolicy size="100MB"/>
</Policies>
</RollingRandomAccessFile>
</appenders>
<loggers>
<Logger name="com.aaa.bbb.core" level="debug" additivity="false">
<appender-ref ref="sqlLogger"></appender-ref>
</Logger>
</loggers>
</configuration>
2.自定义过滤器ClassPathFilter
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.config.Node;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.filter.AbstractFilter;
import org.apache.logging.log4j.message.Message;
//自定义标签插件注解,分别为标签名,节点类型,元素类型,是否打印
@Plugin(name = "ClassPathFilter", category = Node.CATEGORY,elementType = Filter.ELEMENT_TYPE,printObject = true)
public class ClassPathFilter extends AbstractFilter {
private final String pathName;
private ClassPathFilter(String pathName,Result onMatch, Result onMismatch){
super(onMatch, onMismatch);
this.pathName=pathName;
}
/**重写所有标签级别的过滤器,走自定义过滤规则,获取loggerName就是输出日志的对象的全名*/
public Result filter(Logger logger, Level level, Marker marker, String msg, Object... params) {
return filter(logger.getName());
}
public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) {
return filter(logger.getName());
}
public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) {
return filter(logger.getName());
}
@Override
public Result filter(LogEvent event) {
return filter(event.getLoggerName());
}
//@PluginAttribute注解可以获取到xml中配置的属性值
@PluginFactory
public static ClassPathFilter createFilter(@PluginAttribute("pathName") String pathName,
@PluginAttribute("onMatch") final Result match,
@PluginAttribute("onMismatch") final Result mismatch) {
return new ClassPathFilter(pathName, match, mismatch);
}
//自定义过滤规则
public Result filter(String loggerName) {
if(loggerName!=null&&loggerName.indexOf(this.pathName)==-1){
return onMismatch;
}
return onMatch;
}
}
自此配置完毕,重启项目去tomcat/logs/目录下看生成的日志吧。
本文介绍了如何在使用Log4j2的日志框架中,针对SSM架构的项目,通过自定义过滤器ClassPathFilter,实现业务日志与数据库SQL日志的分离,以便于查看和分析。配置主要涉及修改log4j2.xml,并添加过滤规则,使得只有DAO包下的日志被单独记录。

458

被折叠的 条评论
为什么被折叠?



