SpringBoot(六):统一异常入库处理

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='错误日志表'

三.创建ErrorLogsUtil工具类

工程目录
这里写图片描述

3.1添加mysql 驱动

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.35</version>
        </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]联系

猜你喜欢

转载自blog.csdn.net/yjgithub/article/details/80493642