1.异常捕获 ,记录error日志到数据库
package com.chuangqi.core.exception;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import com.chuangqi.core.Conf;
import com.chuangqi.tool.result.ResultUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.LinkedBlockingDeque;
/**
* 全局异常捕获
*/
@ControllerAdvice(basePackages = {"com.chuangqi.*"},annotations = {Controller.class, RestController.class})
public class Exceptionhandling{
/** 是否将日志持久化到数据库,默认不持久化*/
@Value("${error.log.data.persistence:false}")
private Boolean errorLogDataPersistence;
@Value("${server.port}")
private String serverPort;
/**
* 异常处理
*/
@ExceptionHandler(value=Exception.class)
@ResponseBody
public ResultUtil exceptionForAjax(Exception ex) {
if(errorLogDataPersistence){
// 异步将err日志持久化到数据库
logDataPersistence(ex);
}
Console.log("异常处理.");
ex.printStackTrace();
return ResultUtil.error();
}
public void logDataPersistence(Exception ex){
// 封装error消息
JSONObject jsonObject = new JSONObject();
System.out.println(">>> ERROR LOG >>>");
// 错误uuid标识,防止幂等问题
String objectId = IdUtil.objectId();
jsonObject.put("guid", objectId);
// 当前服务ip
try {
jsonObject.put("ip", InetAddress.getLocalHost() + ":" + serverPort);
} catch (UnknownHostException e) {
e.printStackTrace();
}
// 错误代码行数
StackTraceElement[] stackTrace = ex.getStackTrace();
jsonObject.put("line", stackTrace[0]);
// 获取request对象
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
Enumeration<String> parameterNames = request.getParameterNames();
// 获取所有请求参数
JSONObject jsonKey = new JSONObject();
while (parameterNames.hasMoreElements()){
String paramKey = parameterNames.nextElement();
jsonKey.put(paramKey, request.getParameter(paramKey));
}
jsonObject.put("params", jsonKey.toString());
// 错误主要信息
jsonObject.put("mainMessage", ex.getCause());
// 错误全部信息
jsonObject.put("message", Convert.toStr(ex.getStackTrace()));
Console.log("errorLog:{}", jsonObject);
System.out.println("<<< ERROR LOG <<<");
new Thread(){
@Override
public void run() {
// 调用数据存储服务存储错误日志信息到数据库
Map map = new HashMap();
map.put("object", jsonObject.toString());
String post = HttpUtil.post(Conf.DATA_COMMON_SERVER + "/err-log/add", map);
System.out.println("err-log 数据持久性:" + post);
}
}.start();
}
}
2.在服务需要记录错误日志持久化到数据库的application.properties配置文件中加入:
#error日志是否持久化到数据库
error.log.data.persistence=true
3.表结构
/*
Navicat MySQL Data Transfer
Source Server : 192.168.2.177
Source Server Version : 80018
Source Host : 192.168.2.177:3306
Source Database : chuangqi_cloudemulate
Target Server Type : MYSQL
Target Server Version : 80018
File Encoding : 65001
Date: 2020-07-21 11:38:08
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for error_log
-- ----------------------------
DROP TABLE IF EXISTS `error_log`;
CREATE TABLE `error_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`guid` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '唯一标识',
`ip` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '服务ip',
`line` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '错误代码行数',
`params` varchar(1000) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '方法参数',
`main_message` text CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '主要错误信息',
`message` text CHARACTER SET utf8 COLLATE utf8_general_ci COMMENT '全部错误信息',
`insert_time` datetime DEFAULT NULL COMMENT '记录时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of error_log
-- ----------------------------
INSERT INTO `error_log` VALUES ('19', '5f16628a021b3dbefa97a62d', 'Qi/172.28.160.1:8060', 'com.chuangqi.service.Impl.UserServiceImpl.login(UserServiceImpl.java:54)', '{\"password\":\"admin2\",\"userName\":\"amdin2\"}', null, '[com.chuangqi.service.Impl.UserServiceImpl.login(UserServiceImpl.java:54), com.chuangqi.controller.UserController.login(UserController.java:34), com.chuangqi.controller.UserController$$FastClassBySpringCGLIB$$954841da.invoke(<generated>), org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204), org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:747), org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163), org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52), org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185), org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92), org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185), org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689), com.chuangqi.controller.UserController$$EnhancerBySpringCGLIB$$f7a33392.login(<generated>), sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method), sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62), sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43), java.lang.reflect.Method.invoke(Method.java:498), org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209), org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136), org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102), org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:870), org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:776), org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87), org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991), org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925), org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978), org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:881), javax.servlet.http.HttpServlet.service(HttpServlet.java:661), org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855), javax.servlet.http.HttpServlet.service(HttpServlet.java:742), org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231), org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166), org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52), org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193), org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166), org.springframework.web.servlet.resource.ResourceUrlEncodingFilter.doFilter(ResourceUrlEncodingFilter.java:60), org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193), org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166), org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:158), org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:126), org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:111), org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107), org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193), org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166), org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:84), org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107), org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193), org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166), org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99), org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107), org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193), org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166), org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109), org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107), org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193), org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166), org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81), org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107), org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193), org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166), org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200), org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107), org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193), org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166), org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199), org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96), org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496), org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140), org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81), org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87), org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342), org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803), org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66), org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790), org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459), org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49), java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142), java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617), org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61), java.lang.Thread.run(Thread.java:745)]', '2020-07-21 11:35:35');