很早以前弄过将log4j的日志存储到数据库,不过是配置在properties文件,包括数据库配置也是写死的。现在正好有个需求要把日志存储到数据库中,还要进行过滤,只有本项目的才会进行保存,像Spring,mybatis,zookeeper这类的日志不需要进行保存,而且现在配置是动态的,根据不同的环境,有不同的数据库,而使用properties达不到这么灵活的效果,只能把properties改为使用xml来配置,但是好多例子在xml也是写死的数据库配置,如果想达到动态配置,需要依赖一个logback扩展jar。
文档地址:,
先增加maven依赖:
org.logback-extensions logback-ext-spring 0.1.4
logback.xml如下,配置的比较简单,还没配置输出到文件:
下面开始整合,使用的Spring的xml形式:
在web.xml中增加监听器配置,如下:
ch.qos.logback.ext.spring.web.LogbackConfigListener logbackConfigLocation classpath:logback.xml
文档中给出spring的bean配置类为:
ch.qos.logback.core.ConsoleAppender
但是这个类没有支持过滤器配置,所以建一个类,继承ConsoleAppender,如下:
import ch.qos.logback.core.filter.Filter;import java.util.List;public class ConsoleAppender extends ch.qos.logback.core.ConsoleAppender { private Listfilters; public List getFilters() { return filters; } public void setFilters(List filters) { this.filters = filters; if (this.filters != null) { for (Filter filter : filters) { addFilter(filter); } } }}
过滤器支持多个,所以使用List,在setFilters方法中遍历,将过滤器添加上,
下面为spring的xml配置:
LogFilter类代码为:
import ch.qos.logback.classic.spi.LoggerContextVO;import ch.qos.logback.classic.spi.LoggingEvent;import ch.qos.logback.core.filter.Filter;import ch.qos.logback.core.spi.FilterReply;import com.system.dao.log.Log;import com.system.service.log.LogService;import org.slf4j.Marker;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.util.Date;import java.util.Map;public class LogFilter extends Filter{ //日志保存的Service @Autowired private LogService LogService; @Override public FilterReply decide(LoggingEvent event) { String loggerName = event.getLoggerName(); /** * 项目本身的日志才会进行保存 */ if (loggerName.startsWith("com.system")) { Log log = new Log(); log.setClazzName(loggerName); Date date = new Date(event.getTimeStamp()); log.setLogTimestamp(date); log.setCreateTime(date); log.setUpdateTime(date); /** * 使用toString,会带有日志级别 */ log.setMessage(event.toString()); /** * 保存日志,使用Spring的异步执行 */ LogService.asyncSave(log); } return FilterReply.ACCEPT; }}
使用Spring的xml配置到此结束。
异常情况处理:
本地启动项目时是没问题的,日志也能进行保存,但是部署到测试环境出现了如下异常:
java.lang.ClassCastException:org.slf4j.impl.Log4jLoggerFactory
cannot be cast to ch.qos.logback.classic.LoggerContext,
通过使用IDEA查看pom文件的依赖树,发现zookeeper依赖了slf4j-log4j12,也同样实现了ILoggerFactory接口,但是没有实现Context接口,导致类转换失败,将依赖去掉即可,不影响项目的正常运行,如下:
com.101tec zkclient 0.10 org.slf4j slf4j-log4j12