LogBack简介
LogBack是Log4j的创始人设计的又一个开源日志组件,在SpringBoot中你不需要去单独的去添加关于日志组件的依赖,在你的pom.xml中有如下依赖就行:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
LogBack的使用
编写Logback的配置文件,配置文件的位置在application.properties(或者.yml)里可以配置。
logging.config=classpath:logback-boot.xml
下面放出详细注释的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- %m输出的信息,%p日志级别,%t线程名,%d日期,%c类的全名,%i索引【从数字0开始递增】,,, -->
<!-- appender是configuration的子节点,是负责写日志的组件。 -->
<!-- ConsoleAppender:把日志输出到控制台 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %p (%file:%line\)- %m%n</pattern>
<!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
<!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是sys.log -->
<!-- 2.如果日期没有发生变化,但是当前日志的文件大小超过1KB时,对当前日志进行分割 重命名-->
<appender name="syslog"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>log/sys.log</File>
<!-- rollingPolicy:当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名。 -->
<!-- TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 活动文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
<!-- 文件名:log/sys.2017-12-05.0.log -->
<fileNamePattern>log/sys.%d.%i.log</fileNamePattern>
<!-- 每产生一个日志文件,该日志文件的保存期限为30天 -->
<maxHistory>30</maxHistory>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- maxFileSize:这是活动文件的大小,默认值是10MB,本篇设置为1KB,只是为了演示 -->
<maxFileSize>1KB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<!-- pattern节点,用来设置日志的输入格式 -->
<pattern>
%d %p (%file:%line\)- %m%n
</pattern>
<!-- 记录日志的编码 -->
<charset>UTF-8</charset> <!-- 此处设置字符集 -->
</encoder>
</appender>
<!-- 控制台输出日志级别 -->
<root level="info">
<appender-ref ref="STDOUT" />
</root>
<!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
<!-- com.appley为根包,也就是只要是发生在这个根包下面的所有日志操作行为的权限都是DEBUG -->
<!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE -->
<logger name="com.springboot" level="ERROR">
<appender-ref ref="syslog" />
</logger>
</configuration>
在配置好了Logback之后我们就可以使用它了,在JAVA代码中:
private static Logger logger=LoggerFactory.getLogger(xxx.class/*当前类*/);
这样就可以获取到日志助手了,在程序运行中可以用它去输出信息:
logger.info("运行MyController!");
这样的话就可以避免过多的使用System.out.println();导致的性能问题了。
将错误堆栈信息打印在日志文件中
把错误的堆栈信息打印在日志文件中,这样更有利于我们进行维护和解决BUG,在SpringBoot中我们可以使用@ControllerAdvice、@ExceptionHandler这两个注解来实现。在那之前先介绍一下@InitBinder,@ModelAttribute,(value = Exception.class)这三个注解的作用。
package com.mkdlp.demo.controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
/**
* controller 增强器
* @author mkdlp
* @since 2018/1/29
*/
@ControllerAdvice
public class MyControllerAdvice {
/**
* 应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器
*
*/
@InitBinder
public void initBinder(WebDataBinder binder) {}
/**
* 把值绑定到Model中,使全局@RequestMapping可以获取到该值
*
*/
@ModelAttribute
public void addAttributes(Model model) {
model.addAttribute("author", "Magical Sam");
}
/**
* 全局异常捕捉处理
*
*
*/
@ResponseBody
@ExceptionHandler(value = Exception.class)
public Map errorHandler(Exception ex) {
Map map = new HashMap();
map.put("code", 100);
map.put("msg", ex.getMessage());
return map;
}
}
下面贴出处理全局异常的方法:
GlobalExceptionHandler.java
package com.springboot.study.ExceptionHandler;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import com.springboot.study.exception.MyRuntimeException;
@ControllerAdvice
public class GlobalExceptionHandler {
private static Logger logger=LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 全局异常捕捉处理
* @param ex
* @return
*/
@ResponseBody
@ExceptionHandler(value = Exception.class)
public Map errorHandler(Exception ex) {
logger.error("11111======="+getMessage(ex)+"=======");
Map map = new HashMap();
map.put("code", 100);
map.put("msg", getMessage(ex));
return map;
}
/**
* 拦截捕捉自定义异常 MyException.class
* @param ex
* @return
*/
@ResponseBody
@ExceptionHandler(value = MyRuntimeException.class)
public Map myErrorHandler(MyRuntimeException ex) {
logger.error("======="+ex.getMsg()+"=======");
Map map = new HashMap();
map.put("code", ex.getCode());
map.put("msg", ex.getMsg());
return map;
}
public static String getMessage(Exception e) {
StringWriter sw = null;
PrintWriter pw = null;
try {
sw = new StringWriter();
pw = new PrintWriter(sw);
// 将出错的栈信息输出到printWriter中
e.printStackTrace(pw);
pw.flush();
sw.flush();
} finally {
if (sw != null) {
try {
sw.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
if (pw != null) {
pw.close();
}
}
return sw.toString();
}
}
这样就可以将错误堆栈信息输出到日志文件中了。