日志——log4J浅谈与使用
情形
复习尚学堂mubatis
一、log4J
1.由apache推出的开源免费日志处理的类库
2.为什么需要日志:
2.1 在项目编写中我们会通过sout来输出到控制台debug,但是当项目发布到tomcat上时,由于是linux服务器,即使有控制台,但是查看结果不容易,不容易找出错误和debug
2.2 log4J的作用,不仅仅能把内容输出到控制台,还能把内容输出到文件中,例如我们的tomcat服务器的log文件夹下的日志文件,便于观察结果
3.使用步骤
3.1 导入log4j-xxx.jar
3.2 必须在src目录下新建log4j.properties(路径和名称都不允许改变)
4.log4j输出级别
4.1 fatal(致命错误) > error (错误) > warn (警告) > info(普通信息) > debug(调试信息)
4.2 在 log4j.properties 的第一行中控制输出级别:如下设置为ERROR,同时需要注意如果我们设置输出级别为ERROR,则>=error级别的错误才会输出。<error的错误不会输出。
5. log4j 输出目的地
5.1 在一行控制输出目的地:表示将信息输出到控制台(console)以及输出到日志文件(logfile),并且
6. pattern 中常用几个表达式
详细表达式:https://blog.****.net/hello_word2/article/details/79295344
- %C 包名+类名
- %d {YYYY-MM-dd HH:mm:ss} 时间
- %L 行号
- %m 信息
- %n 换行
7.log4j.properties文件配置总体
# 设置输出级别和将信息输出到哪里
log4j.rootCategory=INFO, CONSOLE, LOGFILE
# 负责向控制台输出所使用的类
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
# 向控制台输出的内容格式,由下列类来控制
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
# 向控制台输出的具体内容,可以用log4j表达式来表示我们要输出的内容是什么,详细可参考文档
log4j.appender.CONSOLE.layout.ConversionPattern=%c %d{YYYY/MM/dd hh:mm:ss} %F %m %n
# 负责向日志文件输出所使用的类
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
# 向具体哪个目录下的日志文件进行输出,如果写相对路径,则在当前项目文件目录下输出,输出位置与src目录同级
# 如果写绝对路径,linux系统则会在根目录下创建文件夹和文件,如果windows系统,则会根据当前项目在哪个磁盘分区
# 并在该磁盘分区下创建文件夹和文件。例如如下/log/axis.log表示在windows系统下创建文件,位置为F:/log/axis.log
log4j.appender.LOGFILE.File=/logs/axis.log
# 向日志文件输出的IO是追加还是非追加,肯定设置为可追加
log4j.appender.LOGFILE.Append=true
# 向日志文件输出的内容格式,由下列类来控制
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
# 向日志文件输出的具体内容,可以用log4j表达式来表示我们要输出的内容是什么,详细可参考文档
log4j.appender.LOGFILE.layout.ConversionPattern=%C %L %m %n
四、mybatis集成log4j
1.步骤
- 导入log4j的jar包:
-
- 将log4j.properties文件放到src目录下:
-
- 在mybatis.xml配置文件中添加settings标签,表示mybatis使用log4j,注意settings标签要放在environment标签之前,具体标签的顺序可查看官方文档:
-
<settings> <!--设置我们输出到日志文件中的信息的前缀字符串,方便在各种程序启动日志中找到相关sql的信息的日志,便于定位 PS:关于settings标签中的logPrefix会和log4j.properties文件中的"log4j.logger.cn.uestc.mapper=DEBUG", 也就是局部日志信息输出级别进行冲突。如果我们配置了logPrefix的同时也设置了局部日志信息的输出级别 控制台和日志文件则不会有任何日志的输入 这是因为logPrefix所控制的日志输出为调用sql程序的相关日志,而"log4j.logger.cn.uestc.mapper=DEBUG" 正好也是控制sql程序的相关日志。两者功能都是筛选,所以两者冲突,导致日志文件和控制台没有信息。 如果我们将log4j.properties中“log4j.logger.cn.uestc.mapper=DEBUG”删除,则日志文件和控制台中会输出所有 debug级别的日志信息。同时关于sql的日志会在前面加上“关于sql的相关日志”,而如果我们在这里将logPrefix 注释掉,则日志文件信息和控制台只会输出关于sql的日志信息,而其他信息可以通过设置全局级别设置成ERROR而过滤 掉其他信息的debug信息--> <!--<setting name="logPrefix" value="关于sql的相关日志:"/>--> <setting name="logImpl" value="LOG4J"/> </settings>
-
log4j.properties文件配置
-
# 设置所有日志信息的输出级别、将信息输出到哪里 log4j.rootCategory=ERROR, CONSOLE, LOGFILE #设置局部或者指定日志信息的输出级别 log4j.logger.cn.uestc.mapper=DEBUG # 负责向控制台输出所使用的类 log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender # 向控制台输出的内容格式,由下列类来控制 log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout # 向控制台输出的具体内容,可以用log4j表达式来表示我们要输出的内容是什么,详细可参考文档 log4j.appender.CONSOLE.layout.ConversionPattern=%c %p %d{YYYY/MM/dd hh:mm:ss} %F %m %n # 负责向日志文件输出所使用的类 log4j.appender.LOGFILE=org.apache.log4j.FileAppender # 向具体哪个目录下的日志文件进行输出,如果写相对路径,则在当前项目文件目录下输出,输出位置与src目录同级 # 如果写绝对路径,linux系统则会在根目录下创建文件夹和文件,如果windows系统,则会根据当前项目在哪个磁盘分区 # 并在该磁盘分区下创建文件夹和文件。例如如下/log/mybatis/sql.log表示在windows系统下创建文件,位置为F:/logs/mybatis/sql.log log4j.appender.LOGFILE.File=/logs/mybatis/sql.log # 向日志文件输出的IO是追加还是非追加,肯定设置为可追加 log4j.appender.LOGFILE.Append=true # 向日志文件输出的内容格式,由下列类来控制 log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout # 向日志文件输出的具体内容,可以用log4j表达式来表示我们要输出的内容是什么,详细可参考文档 log4j.appender.LOGFILE.layout.ConversionPattern=%C %L %m %n
2.测试
(1)测试类:
package cn.uestc.test;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class TestLog4jUse4mybatis {
public static void main(String[] args) throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
List<Object> list = sqlSession.selectList("cn.uestc.mapper.PeopleMapper.selAll");
sqlSession.close();
}
}
(2)结果:
控制台:
日志文件:
(3)debug
情形:
在log4j.properties文件中设置了局部或者指定日志信息的输出级别,并在mybatis.xml文件中配置了logPrefix属性,导致日志文件和控制台没有输出日志结果,这是因为log4j.properties中的“log4j.logger.cn.uestc.mapper=DEBUG”与mybatis.xml中的“<setting name="logPrefix" value="关于sql的相关日志:"/>”冲突,两者的作用都是对日志信息进行过滤和筛选。log4j.properties的筛选范围更大,可以指定方法,类或者包下的所有类都进行日志输出。而logPrefix不会过滤日志信息,但是他会在关于sql调用的日志信息前加上“关于sql的相关日志:”的字符串,方便查找。
复现
bug复现:上述两个过滤条件都不注释,控制台和日志文件没有任何输出信息
去掉任何一个过滤条件:这里我们注释掉log4j.properties的过滤信息,因为在2.测试中将logPrefix注释掉了,同时将log4j.properties中的全局日志输出级别改为debug,否则程序如果正常不会将日志输出到控制台或者日志文件
(4)总结
从精准定位来看,通过log4j.properties文件来配置过滤信息是比较好的,日志文件写入信息少,而且不光可以指定输出sql的日志信息,还可以指定到具体方法,具体类,和具体包,接下来是对log4j.properties对日志级别的控制总结
- 命名级别(包级别): mapper.xml文件中的namespace 属性中除去最后一个类名
- 如何通过log4j.properties文件来配置过滤信息
- 1. 先在总体级别调成 Error 不输出无用信息
- 2. 在设置某个指定位置级别为 DEBUG
- 如图:
- 类级别: namespace 属性值 ,namespace 类名
- 如图:则在log4j.properties中将上图中的log4j.logger.cn.uestc.mapper=DEBUG改为log4j.logger.cn.uestc.mapper.PeopleMapper=DEBUG
- 方法级别:使用 namespace 属性值+标签 id 属性值
- 如图:则在log4j.properties中将上图中的log4j.logger.cn.uestc.mapper=DEBUG改为log4j.logger.cn.uestc.mapper.PeopleMapper.selAll=DEBUG