Spring Boot系列
SpringBoot(一):Quick start
SpringBoot(二):多环境切换
SpringBoot(三):Respond封装
SpringBoot(四):统一异常处理
SpringBoot(五):自定义属性获取
一.简介
二.创建数据库表
三.创建ErrorUtil工具类
四.请求测试
五.建议
项目上线后,对于项目报错后,我们只能通过查看服务器的日志,但是对于日志量大的文件,我们看起来多少会有些乏力,我们有没有一种方式一目了然的就可以知道错误在什么地方,然后直接定位到代码层面上呢?
基于上述的问题,我司弄了一套这样子的方案
1.基于Spring Boot的统一异常处理,抓取全局异常(实现请看SpringBoot(四):统一异常处理)
2.数据库建立错误日志表
3.在捕获到异常后,将错误详细信息写入数据库中
4.每日统计错误日志类型(可以分模块写入,详情看表设计)
2.1 表设计
关注点:模块日志,时间,错误日志信息,所以生成以下该表结构
CREATE TABLE `itc_error_logs` (
`id` varchar(36) NOT NULL COMMENT 'id',
`log_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '日志生成时间',
`log_info` text NOT NULL COMMENT '日志信息',
`type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '类型,默认0 (0:用户管理;1:消费记录;2:运营调度;3:算法;4:测试)',
PRIMARY KEY (`id`),
KEY `log_time` (`log_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='错误日志表'
3.1添加mysql 驱动
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.35version>
dependency>
3.2 获取mysql配置信息
修改配置文件application-dev.properties,详情看 SpringBoot(五):自定义属性获取
server.port=8080
#测试属性值
yjgithub.name=cyj
yjgithub.email=yigithub@163.com
yjgithub.sex=man
#mysql
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://172.16.1.159:3306/bus_cloud?characterEncoding=utf8&useSSL=false
spring.datasource.username=bus
spring.datasource.password=bus123456
MysqlConfig.java
package com.citydata.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @Author chenyj
* @Date 2018/05/29
* @Description MySql配置文件信息
*/
@Component
public class MySqlConfig {
// 驱动类
public static String driver;
@Value("${spring.datasource.driver-class-name}")
public void setDriver(String $driver) {
this.driver = $driver;
}
// url地址
public static String url;
@Value("${spring.datasource.url}")
public void setUrl(String $url) {
this.url = $url;
}
// 用户名
public static String username;
@Value("${spring.datasource.username}")
public void setUsername(String $username) {
this.username = $username;
}
// 密码
public static String password;
@Value("${spring.datasource.password}")
public void setPassword(String $password) {
this.password = $password;
}
}
3.3 编写ErrorLogsUtil.java类
路径
/com/citydata/util/ErrorLogsUtil.java
ErrorLogsUtil.java
package com.citydata.util;
import com.citydata.config.MySqlConfig;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* @Author yjgithub
* @Date 14:29 2018/05/29
* @Description 错误日志工具
*/
public class ErrorLogsUtil {
/**
* @Author yjgithub
* @param: [e]
* @return void
* @Date 10:33 2018/5/29
* @Description 打印错误日志并保存到数据库
*/
public static void error(Exception e) {
StackTraceElement stackTraceElement= e.getStackTrace()[0];
Connection con = null;
try {
Class.forName(MySqlConfig.driver);
con = (Connection) DriverManager.getConnection(MySqlConfig.url, MySqlConfig.username, MySqlConfig.password);
} catch (SQLException e1) {
e1.printStackTrace();
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
PreparedStatement ps = null;
String sql = "INSERT INTO itc_error_logs VALUES (UUID(), NOW(), ?, ?)";
try {
ps = con.prepareStatement(sql);
//打印日志,错在第几行
String errorInfo = e.toString()+",errorMassage:"+stackTraceElement+","+"errorLine:"+stackTraceElement.getLineNumber();
ps.setString(1, errorInfo);
ps.setInt(2, 4); //错误类型为4
ps.execute();
} catch (SQLException e1) {
e1.printStackTrace();
} finally {
try {
if(ps != null) {
ps.close();
}
if(con != null) {
con.close();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
}
}
}
3.4 写入数据库
在统一异常处理中,利用该工具类进行记录错误日志
修改为:
//数组越界异常
@ExceptionHandler(ArrayIndexOutOfBoundsException.class)
public ReturnData ArrayIndexOutOfBoundsException(ArrayIndexOutOfBoundsException ex) {
AppConstant.log.info("数组越界异常",ex);
ErrorLogsUtil.error(ex); //这里注意,这里注意,调用工具类写入数据库
return resultFormat(ERROR_CODE, new Exception(ArrayIndexOutOfBoundsStr));
}
在 SpringBoot(四):统一异常处理 该文章中出现一个数据越界异常,用这个请求来测试
测试数据越界成功
查看数据库变化
利用sql查询
SELECT * FROM itc_error_logs i WHERE i.`type` = 4;
文本内容
java.lang.ArrayIndexOutOfBoundsException: 4,errorMassage:com.citydata.service.impl.TestImpl.exception(TestImpl.java:25),errorLine:25
测试到此结束
1.查询sql根据自行需求编写
SELECT * FROM itc_error_logs i WHERE i.`type` = 4;
SELECT * FROM itc_error_logs i WHERE i.`log_time` > '2018-05-29 00:00:00' AND i.`type` = '4'
2.如果你们公司的前端够闲的话,还可以做个前端页面展示,这样就不用连数据库查看,直接在前端展示,更为直观
PS:需要项目源代码,请邮件[email protected]联系