近期需要做一个小的服务,最后决定使用SpringBoot框架做,期间遇到了一些坑,现在总结一下,以防后续踩坑。
- 本人使用的SpringBoot版本是2.5.3,对应的log4j2的版本是2.2.5,MyBatis使用的是SpringBoot自带的依赖:版本2.0.0
- 引入依赖,记得移除SpringBoot自带的logging;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 去掉logback配置 -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- spring-boot-starter-log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
- 首先在SpringBoot中配置log4j2,log4j 2.x版本不再支持像1.x中的.properties后缀的文件配置方式,2.x版本配置文件后缀名只能为".xml",".json"或者".jsn". 此处本人新建的为xml文件,根据个人习惯自行决定,名字可以为log4j2.xml或者像图中也可。文件的存放目录放在resources下。
- 配置文件不需要在yml或yaml文件中配置,直接放入到resources目录下即可,本人测试在yml文件中配置路径与不配置一样生效,不用纠结(我就是纠结很久,最后SpringBoot会自己查找,尴尬)。
log4j2配置文件的内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数, 不设置默认5s
-->
<Configuration status="debug">
<!-- 配置日志信息输出 -->
<Appenders>
<!-- 输出到控制台, target属性一般为SYSTEM_OUT,也可以是 SYSTEM_ERR, -->
<Console name="Console" target="SYSTEM_OUT">
<!--配置日志信息的格式 -->
<PatternLayout pattern="%d{HH:mm:ss} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<!-- 输出到文件,其中有一个append属性,默认为true,即不清空该文件原来的信息,采用添加的方式,若设为false,则会先清空原来的信息,再添加 -->
<!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用 版本上线可以直接将该段删除这一段 <File ></File > -->
<File name="MyFile" fileName="D:/Log4j2.log" append="false">
<PatternLayout>
<!--配置日志信息的格式 -->
<pattern>%d{HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</pattern>
</PatternLayout>
</File>
<!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log"
filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<!-- 此处的level一定要设置为debug,否者mybatis的日志会被拒绝 -->
<ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%t] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="200 MB"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了100 例如文件中会生成如下 info-1.log info-2.log .... info-100.log -->
<DefaultRolloverStrategy max="100"/>
</RollingFile>
</Appenders>
<!-- 定义logger,只有定义了logger并引入了appender,appender才会有效 -->
<Loggers>
<!-- 将业务dao接口所在的包填写进去,并用在控制台和文件中输出 此处配置的是mybatis的输出 level记得设置为debug -->
<logger name="com.****.acquire.dao" level="debug"
additivity="false">
<AppenderRef ref="Console" />
<!-- 将SQL语句输出到name为RollingFileInfo 的文件中 -->
<AppenderRef ref="RollingFileInfo" />
</logger>
<Root level="info">
<AppenderRef ref="Console" />
<AppenderRef ref="RollingFileInfo" />
</Root>
</Loggers>
</Configuration>
配置好log4j2的文件并放到对应位置后即可在代码块中添加日志测试一下了。
- 现在测试一下日志是否打印出来,在自己的controller层或者serviceImp层添加调用,此处本人是在controller层。
@Controller
@RequestMapping("/test")
public class DeptController {
//slf4j 日志 推荐第一条写法
Logger logger = LoggerFactory.getLogger(this.getClass());
//Logger logger = LoggerFactory.getLogger(DeptController .getClass());
@Autowired
private DeptService deptService;
@Autowired
DataSource dataSource;
@RequestMapping("testDb")
@ResponseBody
public String testDb() {
int dept = 10;
String res = deptService.SelDept(dept).toString();
logger.info("===========info=========");
logger.info("===========warn=========");
logger.info("===========error=========");
return res;
}
}
- 启动测试结果,可以正常打印
到此处,log4J2的配置完成,现在配置将MyBatis的sql语句输出到log4j2的日志文件中。
配置MyBatis的SQL日志打印到log4j2的日志文件中
- 首先在resources目录下新建MyBatis.xml文件
- 配置文件内容如下 :由于本人使用的数据源与连接池为dbcp2,MyBatis中的配置都为空,此处MyBatis.xml配置文件中只配置了日志功能。这个不用纠结,如果使用的是Mybatis的数据源与连接池,只需将settings内容加入到配置文件中即可。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 使用log4j2输出日志 -->
<settings>
<setting name="logImpl" value="LOG4J2" />
</settings>
</configuration>
- 经过本人尝试,无需在yml文件中添加config-location: classpath:MyBatis.xml到配置文件中,配置也可生效,此处本人又纠结很久,SpringBoot会自动扫描
- 在log4j2配置文件中添加dao层(mapper)文件的路径配置,就是调用mapper.xml文件中sql语句的文件的目录,例如本人的dao路径就为com.****.acquire.dao, DeptDao文件中调用mapper.xml中的sql。
- 本人测试调用以下sql,id为SelDept
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ynrcc.acquire.dao.DeptDao">
<select id="SelDept" resultType="com.ynrcc.acquire.entity.Dept" parameterType="int">
select deptno,dname,loc from dept where deptno = #{deptno}
</select>
</mapper>
- log4j2的配置文件中有这段,注意!此处是坑! level一定要写为debug,ref="TollingFileInfo"意思是将日志输出到name=“TollingFileInfo”的文件中,level一定为debug,不然sql日志不能打印到文件中,log4j2的配置文件中有下图配置。
<logger name="com.****.acquire.dao" level="debug"
additivity="false">
<AppenderRef ref="Console" />
<!-- 将SQL语句输出到name为RollingFileInfo 的文件中 -->
<AppenderRef ref="RollingFileInfo" />
</logger>
- 测试 ,控制台与日志文件都正常输出了sql
- 就此成功
总结:
-
配置log4j2时可以直接使用springboot的依赖,包含slf4j。
- SpringBoot会自动扫描log4j2与MyBatis的配置文件。
- log4j2的配置文件中的日志等级一定要设置正确,否则mybatis的sql日志打印不能进日志文件中。
- mybatis.configuration.log-impl="org.apache.ibatis.logging.stdout.StdOutImpl" 只能在控制台打印mybatis的sql,不能在日志文件中写入。
- log42中的<loggers>....</loggers>中的name一定是调用mybatis.xml中的语句的那个文件的目录。一般为xxxx.xxx.dao或者xxxx.xxx.mapper,看个人怎么起名字的。