logback 配置
使用 log 记录必要的信息能帮助我们了解程序的运行和在出错时快速定位问题。在开发的过程中,出错了我们可以在控制台中找到错误提示,而当部署到服务器上之后,只能通过查看 log 文件找出问题所在。spring boot 自带的 log 是 logback。配置方式如下。
在 resource 目录下新建 logback-spring.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/> <!-- logback 提供的基本配置 -->
<!-- 控制台 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<Pattern>[%-5level] %d{HH:mm:ss} %logger{36} %line: %msg %n</Pattern> <!-- 输出格式 -->
<charset>UTF-8</charset> <!-- 解决中文乱码问题 -->
</encoder>
</appender>
<!-- 记录到文件 (每天一个文件) -->
<appender name="dailyRollingFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>log/spring-boot-blog.log</File> <!-- 最新的log文件名 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>log/spring-boot-blog.%d{yyyy-MM-dd}.log</FileNamePattern> <!-- 历史文件名 -->
<maxHistory>30</maxHistory> <!-- 保留 30 天的日志 -->
</rollingPolicy>
<encoder>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{35} : %n %msg %n</Pattern>
<charset>UTF-8</charset> <!--解决中文乱码问题-->
</encoder>
</appender>
<!-- 将上面两个 appender 关联到我们的项目 -->
<logger name="com.hpm.blog" level="DEBUG" additivity="false"> <!-- name 是项目包名,为了方便调试,输出 DEBUG 级别及其以上的log -->
<appender-ref ref="CONSOLE"/>
<appender-ref ref="dailyRollingFileAppender" />
</logger>
<!-- 其他框架的日志输出 -->
<property name="LOG_FILE" value="log/spring-boot-blog-tmp.log" />
<logger name="org.springframework.web" level="INFO"/> <!-- spring web 包下的 logger, 只输出 INFO 级别的 -->
<logger name="org.springframework.boot.web.filter" level="INFO"/>
</configuration>
编辑保存好之后重启项目,刷新目录结构可看到多了一个log的目录,log 信息成功记录到文件了。
@ControllerAdvice 处理全局异常
为了说清楚全局异常处理,先在 userApi.java 里面添加一个临时用的一定会抛出异常的方法
@GetMapping("/test")
public int testError(){
return 9 / 0; // 除 0异常
}
当我们访问一个接口出错时,spring 默认返回的错误如下
在控制台下可以看到错误提示,可以看到 UserApi.java 的 18 行发送了除 0 错误。但打开 log 目录下的 spring-boot-blog.log 文件,并没有看到错误提示。这意味着假如这是服务器上的代码出现了这个问题,你无法知道错在哪里。
那要怎么自定义服务器出错时返回的 json 格式和将错误信息记录到 log 文件呢?
-
添加 commons-lang依赖
借助 commons-lang 包下的 ExceptionUtils 类来获取异常的具体信息<dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency>
-
编写 GloablExceptionHandler.java
@ControllerAdvice
public class GlobalExceptionHandler {
private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ResponseBody
@ExceptionHandler(Exception.class)
public Object handleException(Exception e) {
logger.error(ExceptionUtils.getFullStackTrace(e)); // 记录错误信息
String msg = e.getMessage();
if (msg == null || msg.equals("")) {
msg = "服务器出错";
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("message", msg);
return jsonObject;
}
}
@ResponseBody表示这个方法返回 JSON 格式的数据,这里只简单地返回。具体的格式可以自己定。
{
"message": "错误信息"
}
@ExceptionHandler表示该方法可以处理的异常,可以多个,比如
@ExceptionHandler({ NullPointerException.class, DataAccessException.class})
也可以针对不同的异常写不同的方法。@ExceptionHandler(Exception.class)
可以处理所有的异常类型。
-
测试
重启项目,再次访问。可以看到返回的是我们自定义的 JSON 格式。这时候控制台下有错误输出,log/spring-boot-blog.log 文件里面也记录下了错误信息。测试完毕,把一开始添加的 testError 方法删掉吧。
查看项目完整代码
项目地址: https://github.com/hyrijk/spring-boot-blog
克隆项目到本地
git clone https://github.com/hyrijk/spring-boot-blog.git
checkout 到当前版本
git checkout 8b70983e846fdd56a455634d163ebf25c6bd682f
完。