之所以想要写这一篇分享是因为前一段时间看了另一个分享,使用日志打印出完整的sql语句,而不是像JFinal内置的devMode中带"?"的sql语句.链接如下:
http://www.jfinal.com/share/324
但是遇到了一个问题,该分享中使用的日志框架是logback,但是我的项目中使用的是JFinal自带的日志框架(即配置了log4j.properties),会打印出来很多无用的日志,当时并不知道怎么配置"日志过滤",就放弃了该分享中的功能,现在终于解决了这个问题,现分享如下:
分享从几个问题开始
JFinal中使用的是什么日志框架?如何更改?
应该选用什么框架实现日志过滤的功能?
如何配置日志框架才能实现日志过滤的功能?
回答:
JFinal使用的是什么日志框架?默认实现是什么?如何更改?
JFinal使用的是封装了一层的日志框架,可以兼容其余所有日志框架,为何这么说,看源码,JFinal源码中有一个接口ILogFactory,一个抽象类Log,JFinal源代码中使用的日志工具就是Log的子类.为什么说JFinal可以兼容其余所有日志框架呢?看下JFinal提供的Log实现类,有两个,一个JdkLog,一个Log4jLog,从名字就可以看出,一个是封装Jdk默认log,一个是封装log4j的log,部分代码如下:
public class Log4jLog extends Log { private org.apache.log4j.Logger log; private static final String callerFQCN = Log4jLog.class.getName(); Log4jLog(Class<?> clazz) { log = org.apache.log4j.Logger.getLogger(clazz); } Log4jLog(String name) { log = org.apache.log4j.Logger.getLogger(name); } public static Log4jLog getLog(Class<?> clazz) { return new Log4jLog(clazz); } public static Log4jLog getLog(String name) { return new Log4jLog(name); } public void info(String message) { log.log(callerFQCN, Level.INFO, message, null); } ... }
就是封装了一个org.apache.log4j.Logger,所有的操作调用log4j的log完成
JFinal的默认实现又是什么呢?
初始化的代码在抽象类Log中
public abstract class Log { private static ILogFactory defaultLogFactory = null; static { init(); } static void init() { if (defaultLogFactory == null) { try { Class.forName("org.apache.log4j.Logger"); Class<?> log4jLogFactoryClass = Class.forName("com.jfinal.log.Log4jLogFactory"); defaultLogFactory = (ILogFactory)log4jLogFactoryClass.newInstance(); // return new Log4jLogFactory(); } catch (Exception e) { defaultLogFactory = new JdkLogFactory(); } } } ... }
如果可以加载log4j的jar包,就使用log4j,否则使用JdkLog
如何更改日志框架呢?
在configConstant中配置即可
@Override public void configConstant(Constants me) { ... me.setLogFactory(new Slf4jLogFactory()); ... }
其中Slf4jLogFactory类直接使用了cn.dreampie的代码,表示感谢,maven如下
<dependency> <groupId>cn.dreampie</groupId> <artifactId>jfinal-slf4j</artifactId> <version>0.1</version> </dependency>
2.应该选用什么框架实现日志过滤的功能?
在此之前需要了解以下日志框架体系,链接如下:
http://blog.csdn.net/kxcfzyk/article/details/38613861
从上面已经看到,日志门面使用的是slf4j,便于修改,但是底层的日志使用什么实现呢?log4j最新的一版是2012的,太老了直接淘汰,查了下比较常用的是log4j2和logback,从网上查到的资料个人感觉log4j2好用点,就决定使用log4j2,需要一共四个依赖
<!--slf4j及log4j日志--> <!--门面--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <!--桥接器:告诉slf4j使用Log4j2--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>${log4j2.version}</version> <exclusions> <exclusion> <artifactId>slf4j-api</artifactId> <groupId>org.slf4j</groupId> </exclusion> </exclusions> </dependency> <!--具体实现,log4j2--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>${log4j2.version}</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>${log4j2.version}</version> </dependency>
<log4j2.version>2.9.1</log4j2.version> <!--不能升级为1.8.*,log4j2的2.9.1版本依赖1.7.25,使用1.8提示No SLF4J providers were found--> <slf4j.version>1.7.25</slf4j.version>
注意:slf4j不可使用1.8.*.否则不兼容
3.如何配置日志框架才能实现日志过滤的功能?
由于日志选择使用slf4j+log4j2,其实配置就是配置log4j2,网上关于如何配置log4j2的文章很多,都可以查到.
我配置的时候遇到一个坑,log4j2有两种模式,一种strict,一种非strict,strict模式是严格按照xsd标准的配置文件,当时觉得strict模式符合xsd标准,idea也不会报error,就尽力想使用strict模式配置,后来发现一些功能配置实现不了,而且网上的文章多数都是使用非strict模式配置,最后就放弃了,决定使用非strict模式配置,于是idea一打开log4j2.xml文件,就全是error,真是丑
总结:
1.JFinal抽象了日志实现,可以兼容任何日志框架
2.使用slf4j+log4j2实现日志框架,当时要注意jar包版本,注意兼容问题
3.使用非strict模式配置log4j2,虽然丑,但是能用
当时下定决心修改日志框架是因为要让日志打印sql语句,最后该功能当然是实现了,不过使用的并不是文章开头链接中提到的方法,而是----->druid,下一篇分享写下如何配置druid