一 概述
1.1 概述
我们在本地开发,在配置文件中配置了Mybatis的相关参数,将sql语句输入到控制台上,但是在生产上我们为了排错或者查看sql的执行过程,就需要查看日志,所以Mybatis执行sql不仅要能在控制台打印输出,还要能写入日志文件待查。之前看过的好多博客只是解决了日志向控制台打印的问题。怎么将日志写到制定的文件,遇到了好了问题,无法将日志写到制定的文件中,
麻蛋,网上一堆资料,都是瞎比咧咧,解决不了问题,自己通过专研,终于实现了将日志输入到制定的文件当中。由于Mybatis执行sql的日志级别为DEBUG,一般生产上需要的日志级别为INFO及以上。如果将DEBUG级别日志全部写入日志文件,会造成日志查问题的速度降低,难度大大提高。
所以建议:将Mybatis执行sql的日志只能向更高日志级别的日志文件追加或单独写入一个文件。
1.2 解决办法
当时配置好springboot和logback,无法将mybaits的sql语句写入到制定文件的原因是,日志的输出方式没有配对
将 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 改为:log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
应该配置成:
1.3 logback中onmatch与onmismatch的区别
二 案例演示
2.1 项目结构
2.2.代码说明
2.2.1pom文件
<!-- springBoot的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<!-- web启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<!-- Mybatis启动器 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<!-- mysql数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.3</version>
</dependency>
<!-- druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
2.2.2 controller层
package com.ljf.spring.boot.demo.persistence.controller;
import com.ljf.spring.boot.demo.persistence.model.Users;
import com.ljf.spring.boot.demo.persistence.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
/**
* @ClassName: UserController
* @Description: TODO
* @Author: liujianfu
* @Date: 2020/07/29 15:45:36
* @Version: V1.0
**/
@Controller
@RequestMapping("/users")
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
@Autowired
private UserService usersService;
/**
* 页面跳转
*/
@RequestMapping("/{page}")
public String showPage(@PathVariable String page){
System.out.println("进来了!!!"+page);
return page;
}
/**
* 添加用户
*/
@RequestMapping("/addUser")
public String addUser(Users users){
System.out.println("users:"+users.getName());
this.usersService.addUser(users);
return "ok";
}
/**
* 查询全部用户
*/
@RequestMapping("/findUserAll")
public String findUserAll(Model model){
logger.info("=========================================查询全部用户信息!!!!!!!!!!!!!!!!!!!!!");
List<Users> list = this.usersService.findUserAll();
model.addAttribute("list", list);
return "showUsers";
}
/**
* 根据用户id查询用户
*/
@RequestMapping("/findUserById")
public String findUserById(Integer id,Model model){
Users user = this.usersService.findUserById(id);
model.addAttribute("user", user);
System.out.println("update:"+user);
return "updateUser";
}
/**
* 更新用户
*/
@RequestMapping("/editUser")
public String editUser(Users users){
this.usersService.updateUser(users);
return "ok";
}
/**
* 删除用户
*/
@RequestMapping("/delUser")
public String delUser(Integer id){
this.usersService.deleteUserById(id);
return "redirect:/users/findUserAll"; //重定向页面
}
}
2.2.3 dao层
package com.ljf.spring.boot.demo.persistence.dao;
import com.ljf.spring.boot.demo.persistence.model.Users;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UsersMapper {
void insertUser(Users users);
List<Users> selectUsersAll();
Users selectUsersById(Integer id);
void updateUser(Users users);
void deleteUserById(Integer id);
}
2.2.4 其他层
其他层不是这篇博客的重点不在贴出,只贴出相应的结构图
2.3. 日志输入到不同文件
2.3.1 .application的配置文件
server:
port: 8081
spring:
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test_db
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.ljf.spring.boot.demo.persistence.model
configuration:
#增加打印sql语句,将日志写入到制定的日志文件当中
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
#增加打印sql语句,一般用于本地开发测试
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
logging:
config: classpath:logback-spring-fen.xml
2.3.2 logback.xml的配置
配置自己项目的dao层路径,日志级别为info
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_PATH" value="../logs"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder charset="UTF-8">
<pattern>%date [%thread] %-5level %logger [%L] - %msg%n</pattern>
</encoder>
</appender>
<!--sql日志-->
<appender name="APP_SQL" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--活动日志输出路径示例-->
<file>${LOG_PATH}/sql.log</file>
<append>true</append>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<!-- onMatch:意思是当前级别以及以上要怎么处理 -->
<onMatch>ACCEPT</onMatch>
<!-- onMismatch:意思是当前级别(不包括当前级别)以下要怎么处理 -->
<onMismatch>DENY</onMismatch>
</filter>
<!--存档日志示例-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/sql.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!--日志大小可自定义-->
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--存档天数可自定义-->
<maxHistory>90</maxHistory>
</rollingPolicy>
<!--统一日志输出格式-->
<encoder charset="UTF-8">
<pattern>%date [%thread] %-5level %logger [%L] - %msg%n</pattern>
</encoder>
</appender>
<!--info日志-->
<appender name="APP_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--活动日志输出路径示例-->
<file>${LOG_PATH}/info.log</file>
<append>true</append>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!--存档日志示例-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/info.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!--日志大小可自定义-->
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--存档天数可自定义-->
<maxHistory>90</maxHistory>
</rollingPolicy>
<!--统一日志输出格式-->
<encoder charset="UTF-8">
<pattern>%date [%thread] %-5level %logger [%L] - %msg%n</pattern>
</encoder>
</appender>
<!--ERROR日志-->
<appender name="APP_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/error.log</file>
<append>true</append>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/error.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>90</maxHistory>
</rollingPolicy>
<encoder charset="UTF-8">
<pattern>%date [%thread] %-5level %logger [%L] - %msg%n</pattern>
</encoder>
</appender>
<!--<appender name="CatAppender" class="com.baojia.bike.config.CatLogbackAppender"></appender>-->
<logger name="com.ljf.spring.boot.demo.persistence.dao" level="DEBUG">
<appender-ref ref="APP_SQL"/>
</logger>
<!--调试模式下可以改为debug-->
<root level="INFO">
<!--<appender-ref ref="CatAppender" />-->
<appender-ref ref="CONSOLE"/>
<appender-ref ref="APP_ERROR"/>
<appender-ref ref="APP_INFO"/>
</root>
</configuration>
2.3.3 执行访问,产生日志
看看日志目录:
logs和工程是平级的,进入logs文件夹后,可以看到产生了error,info,sql三种信息的日志文件
查看sql文件:
2.4 将日志输入到相同文件
2.4.1 application的配置文件
server:
port: 8081
spring:
datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test_db
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.ljf.spring.boot.demo.persistence.model
configuration:
#增加打印sql语句,将日志写入到制定的日志文件当中
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
#增加打印sql语句,一般用于本地开发测试
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
logging:
3config: classpath:logback-spring-fen.xml
config: classpath:logback-spring-he.xml
2.4.2 logback配置文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<property name="LOG_PATH" value="D:/spt-logback-demo-logs"/>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<property name="LOG_STDOUT_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
<property name="LOG_FILE_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
<!-- 输出到控制台 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!-- 输出的格式 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_STDOUT_PATTERN}</pattern>
</encoder>
</appender>
<!-- 生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 日志名称 -->
<file>${LOG_PATH}/spt-logback.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/14-spt.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- 日志最大 50MB -->
<maxFileSize>50MB</maxFileSize>
<!-- 保存 30 天 -->
<maxHistory>30</maxHistory>
<!-- <totalSizeCap>10GB</totalSizeCap> <!– 总日志大小 –>-->
</rollingPolicy>
<encoder>
<pattern>${LOG_FILE_PATTERN}</pattern>
</encoder>
</appender>
<!--
<logger name="org.influxdb" level="INFO"/> -->
<logger name="com.ljf.spring.boot.demo.persistence.dao" level="debug"/>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
2..4.3 页面访问,产生日志
查看日志的目录:
查看日志:
2021-03-24 17:48:10.870 [main] INFO c.l.spring.boot.demo.persistence.App - Starting App on LAPTOP-VC53HCIP with PID 33028 (E:\springboot-project\spring-boot-demo\04-spt-tx-persistence-crud\target\classes started by jurfl in E:\springboot-project\spring-boot-demo)
2021-03-24 17:48:10.873 [main] INFO c.l.spring.boot.demo.persistence.App - No active profile set, falling back to default profiles: default
2021-03-24 17:48:10.933 [main] INFO o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@43bc63a3: startup date [Wed Mar 24 17:48:10 CST 2021]; root of context hierarchy
2021-03-24 17:48:12.146 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8081 (http)
2021-03-24 17:48:12.161 [main] INFO o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8081"]
2021-03-24 17:48:12.169 [main] INFO o.a.catalina.core.StandardService - Starting service [Tomcat]
2021-03-24 17:48:12.170 [main] INFO o.a.catalina.core.StandardEngine - Starting Servlet Engine: Apache Tomcat/8.5.29
2021-03-24 17:48:12.174 [localhost-startStop-1] INFO o.a.c.core.AprLifecycleListener - The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [C:\Program Files\Java\jdk1.8.0_181\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;d:\app\as\product\12.1.0\dbhome_1\bin;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\ProgramData\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Java\jdk1.8.0_181\bin;D:\apache-maven-3.6.0\bin;D:\apache-tomcat-8.5.6\bin;C:\Program Files\TortoiseSVN\bin;D:\mysql-5.7.21-winx64\bin;C:\Program Files\Git\bin;D:\xshell-manager\Xmanager 7\;D:\xshell-manager\Xshell 7\;D:\xshell-manager\Xftp 7\;D:\xshell-manager\Xlpd 7\;C:\Users\jurfl\AppData\Local\Microsoft\WindowsApps;;C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.4\bin;;.]
2021-03-24 17:48:12.325 [localhost-startStop-1] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
2021-03-24 17:48:12.325 [localhost-startStop-1] INFO o.s.web.context.ContextLoader - Root WebApplicationContext: initialization completed in 1392 ms
2021-03-24 17:48:12.502 [localhost-startStop-1] INFO o.s.b.w.s.ServletRegistrationBean - Servlet dispatcherServlet mapped to [/]
2021-03-24 17:48:12.506 [localhost-startStop-1] INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'characterEncodingFilter' to: [/*]
2021-03-24 17:48:12.507 [localhost-startStop-1] INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2021-03-24 17:48:12.507 [localhost-startStop-1] INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'httpPutFormContentFilter' to: [/*]
2021-03-24 17:48:12.507 [localhost-startStop-1] INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'requestContextFilter' to: [/*]
2021-03-24 17:48:12.866 [main] INFO o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2021-03-24 17:48:13.042 [main] INFO o.s.w.s.m.m.a.RequestMappingHandlerAdapter - Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@43bc63a3: startup date [Wed Mar 24 17:48:10 CST 2021]; root of context hierarchy
2021-03-24 17:48:13.146 [main] INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/users/addUser]}" onto public java.lang.String com.ljf.spring.boot.demo.persistence.controller.UserController.addUser(com.ljf.spring.boot.demo.persistence.model.Users)
2021-03-24 17:48:13.147 [main] INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/users/findUserAll]}" onto public java.lang.String com.ljf.spring.boot.demo.persistence.controller.UserController.findUserAll(org.springframework.ui.Model)
2021-03-24 17:48:13.147 [main] INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/users/{page}]}" onto public java.lang.String com.ljf.spring.boot.demo.persistence.controller.UserController.showPage(java.lang.String)
2021-03-24 17:48:13.148 [main] INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/users/findUserById]}" onto public java.lang.String com.ljf.spring.boot.demo.persistence.controller.UserController.findUserById(java.lang.Integer,org.springframework.ui.Model)
2021-03-24 17:48:13.148 [main] INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/users/editUser]}" onto public java.lang.String com.ljf.spring.boot.demo.persistence.controller.UserController.editUser(com.ljf.spring.boot.demo.persistence.model.Users)
2021-03-24 17:48:13.148 [main] INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/users/delUser]}" onto public java.lang.String com.ljf.spring.boot.demo.persistence.controller.UserController.delUser(java.lang.Integer)
2021-03-24 17:48:13.151 [main] INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2021-03-24 17:48:13.152 [main] INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2021-03-24 17:48:13.174 [main] INFO o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2021-03-24 17:48:13.175 [main] INFO o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2021-03-24 17:48:13.453 [main] INFO o.s.j.e.a.AnnotationMBeanExporter - Registering beans for JMX exposure on startup
2021-03-24 17:48:13.454 [main] INFO o.s.j.e.a.AnnotationMBeanExporter - Bean with name 'dataSource' has been autodetected for JMX exposure
2021-03-24 17:48:13.461 [main] INFO o.s.j.e.a.AnnotationMBeanExporter - Located MBean 'dataSource': registering with JMX server as MBean [com.alibaba.druid.pool:name=dataSource,type=DruidDataSource]
2021-03-24 17:48:13.473 [main] INFO o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8081"]
2021-03-24 17:48:13.486 [main] INFO o.a.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
2021-03-24 17:48:13.502 [main] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8081 (http) with context path ''
2021-03-24 17:48:13.506 [main] INFO c.l.spring.boot.demo.persistence.App - Started App in 3.085 seconds (JVM running for 5.95)
2021-03-24 17:48:22.617 [http-nio-8081-exec-1] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring FrameworkServlet 'dispatcherServlet'
2021-03-24 17:48:22.618 [http-nio-8081-exec-1] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization started
2021-03-24 17:48:22.647 [http-nio-8081-exec-1] INFO o.s.web.servlet.DispatcherServlet - FrameworkServlet 'dispatcherServlet': initialization completed in 29 ms
2021-03-24 17:48:22.673 [http-nio-8081-exec-1] INFO c.l.s.b.d.p.c.UserController - =========================================查询全部用户信息!!!!!!!!!!!!!!!!!!!!!
2021-03-24 17:48:22.701 [http-nio-8081-exec-1] INFO c.alibaba.druid.pool.DruidDataSource - {dataSource-1} inited
2021-03-24 17:48:22.837 [http-nio-8081-exec-1] DEBUG c.l.s.b.d.p.d.U.selectUsersAll - ==> Preparing: select id,name,age from tb_users
2021-03-24 17:48:22.849 [http-nio-8081-exec-1] DEBUG c.l.s.b.d.p.d.U.selectUsersAll - ==> Parameters:
2021-03-24 17:48:22.861 [http-nio-8081-exec-1] DEBUG c.l.s.b.d.p.d.U.selectUsersAll - <== Total: 7
2021-03-24 17:48:30.972 [http-nio-8081-exec-3] DEBUG c.l.s.b.d.p.d.U.selectUsersById - ==> Preparing: select id,name,age from tb_users where id = ?
2021-03-24 17:48:30.972 [http-nio-8081-exec-3] DEBUG c.l.s.b.d.p.d.U.selectUsersById - ==> Parameters: 1(Integer)
2021-03-24 17:48:30.973 [http-nio-8081-exec-3] DEBUG c.l.s.b.d.p.d.U.selectUsersById - <== Total: 1