Preface
Previously, in " Learning from Zero ELK Series (10): SpringBoot Project Access ELK Upgraded Version (Super Detailed Graphical Tutorial) ", the SpringBoot project access ELK request recording and optimization was demonstrated. This time, it is recorded through interception for unknown exceptions. ;
Before optimization:
- The system is abnormal and no abnormal information is recorded
Optimized:
- Record the exception information of this request
table of Contents
- Learn the ELK series from zero (1): Why should you learn from me the ELK series from zero
- Learn ELK series from zero (two): VMware install Centos (super detailed graphic tutorial)
- Learn ELK series from zero (3): Centos install Docker (super detailed graphic tutorial)
- Learn ELK series from scratch (four): Docker install Elasticsearch (super detailed graphic tutorial)
- Learn ELK series from scratch (5): Docker install Kibana (super detailed graphic tutorial)
- Learn ELK series from scratch (6): Docker install Logstash (super detailed graphic tutorial)
- Learn from zero ELK series (7): Centos install Filebeat (super detailed graphic tutorial)
- Learn ELK series from scratch (eight): SpringBoot project access ELK (super detailed graphic tutorial)
- Learn ELK series from zero (9): Nginx access ELK (super detailed graphic tutorial)
- Learn ELK series from scratch (ten): SpringBoot project access ELK upgraded version (super detailed graphic tutorial)
- Learn ELK series from scratch (11): SpringBoot project access ELK super version (super detailed graphic tutorial)
Architecture diagram & timing diagram
- Architecture diagram
- Sequence diagram of program writing log
- ELK collection log and Kibina query log timing diagram
Code
-
Complete code (GitHub, welcome to Star, Fork, Watch )
-
Main code display
- ExceptionLogAspect
/* * Copyright (c) 2020. [email protected] All Rights Reserved. * 项目名称:SpringBoot项目接入ELK * 类名称:ExceptionLogAspect.java * 创建人:张晗 * 联系方式:[email protected] * 开源地址: https://github.com/dangnianchuntian/springboot * 博客地址: https://zhanghan.blog.csdn.net */ package com.zhanghan.zhelkboot.aop; import com.zhanghan.zhelkboot.util.FileBeatLogUtil; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.util.Arrays; @Aspect @Order(1) @Component public class ExceptionLogAspect { private final Logger logger = LoggerFactory.getLogger(this.getClass()); /** * 范围切点方法 */ @Pointcut("execution(* com.zhanghan.zhelkboot..*.*(..))") public void methodPointCut() { } @AfterThrowing(throwing = "ex", pointcut = "methodPointCut()") public void throwss(JoinPoint joinPoint, Exception ex) { try { String methodArgs = Arrays.toString(joinPoint.getArgs()); FileBeatLogUtil.writeExceptionLog(joinPoint.getSignature().toString(), methodArgs, ex.getMessage()); } catch (Exception e) { logger.error("ExceptionLogAspect;writeExceptionLog;Exception:{}", e.getMessage()); } } }
- RecordExcepitonLogServiceImpl
/* * Copyright (c) 2020. [email protected] All Rights Reserved. * 项目名称:SpringBoot项目接入ELK * 类名称:RecordExcepitonLogServiceImpl.java * 创建人:张晗 * 联系方式:[email protected] * 开源地址: https://github.com/dangnianchuntian/springboot * 博客地址: https://zhanghan.blog.csdn.net */ package com.zhanghan.zhelkboot.service.impl; import com.zhanghan.zhelkboot.controller.request.RecordExceptionLogRequest; import com.zhanghan.zhelkboot.service.RecordExcepitonLogService; import com.zhanghan.zhelkboot.util.wrapper.WrapMapper; import org.springframework.stereotype.Service; import java.util.HashMap; import java.util.Map; @Service public class RecordExcepitonLogServiceImpl implements RecordExcepitonLogService { /** * 记录异常 */ @Override public Object recordExcepitonLog(RecordExceptionLogRequest recordExceptionLogRequest) { Integer divisor = recordExceptionLogRequest.getDivisor(); int consult = 2 / divisor; Map<String, Object> map = new HashMap(); map.put("consult", consult); return WrapMapper.ok(map); } }
- FileBeatLogUtil
/* * Copyright (c) 2020. [email protected] All Rights Reserved. * 项目名称:SpringBoot项目接入ELK * 类名称:FileBeatLogUtil.java * 创建人:张晗 * 联系方式:[email protected] * 开源地址: https://github.com/dangnianchuntian/springboot * 博客地址: https://zhanghan.blog.csdn.net */ package com.zhanghan.zhelkboot.util; import com.alibaba.fastjson.JSON; import com.zhanghan.zhelkboot.util.wrapper.Wrapper; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.MDC; import org.springframework.util.StringUtils; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.text.SimpleDateFormat; import java.util.*; public class FileBeatLogUtil { public static void writeRequestInfo(HttpServletRequest request, String applicationName, String reqName, String requestParams) { String requestURI = request.getRequestURI(); //获取requestHeader Enumeration<String> requestHeaderNames = request.getHeaderNames(); Map<String, Object> reuestHeaderMap = new HashMap<>(); while (requestHeaderNames.hasMoreElements()) { String name = requestHeaderNames.nextElement(); String value = request.getHeaders(name).nextElement(); reuestHeaderMap.put(name, value); } String requestHeader = ""; if (null != reuestHeaderMap && reuestHeaderMap.size() > 0) { requestHeader = JSON.toJSONString(reuestHeaderMap); } //防止MDC值空指针,所有入参不为null applicationName = StringUtils.isEmpty(applicationName) ? "" : applicationName; requestURI = StringUtils.isEmpty(requestURI) ? "" : requestURI; reqName = StringUtils.isEmpty(reqName) ? "" : reqName; requestParams = "null".equals(requestParams) ? "" : requestParams; //MDC值为ES键值对JSON信息 MDC.put("applicationName", applicationName); MDC.put("requestTime", getStringTodayTime()); MDC.put("requestURI", requestURI); MDC.put("requestHeader", requestHeader); MDC.put("sourceName", reqName); MDC.put("requestParams", requestParams); MDC.put("exceptionCount", "0"); } public static void writeExceptionLog(String exceptionMethodName, String exceptionMethodArgs, String exceptionMessage) { MDC.put("exceptionCount", "1"); exceptionMessage = String.format("MethodName:%s;Args:%s;Exception:%s", exceptionMethodName, exceptionMethodArgs, exceptionMessage); //MDC值为ES键值对JSON信息 MDC.put("exceptionMessage", exceptionMessage); } public static void writeResponseLog(Object o, Logger log, HttpServletResponse response) { //取responseHeader内容 Map<String, Object> responseHeaderMap = new HashMap<>(); Collection<String> headerNames = response.getHeaderNames(); headerNames.forEach(name -> { responseHeaderMap.put(name, response.getHeader(name)); }); String strResponseHeader = ""; if (null != responseHeaderMap && responseHeaderMap.size() > 0) { strResponseHeader = JSON.toJSONString(responseHeaderMap); } //获取response内容 String responseCode = ""; String responseMsg = ""; String responseBody = ""; Wrapper wrapper; if (null != o) { wrapper = (Wrapper) o; if (null != wrapper) { responseCode = String.valueOf(wrapper.getCode()); responseMsg = wrapper.getMessage(); Object result = wrapper.getResult(); if (null != result) { responseBody = result.toString(); } } } //MDC值为ES键值对JSON信息 MDC.put("responseHeader", strResponseHeader); MDC.put("responseCode", responseCode); MDC.put("responseMsg", responseMsg); MDC.put("responseBody", responseBody); MDC.put("responseTime", getStringTodayTime()); Map<String, String> copyOfContextMap = MDC.getCopyOfContextMap(); String reqInfoJsonStr = JSON.toJSONString(copyOfContextMap); log.info(reqInfoJsonStr); } /** * 获取请求参数,处理为json字符串 * * @param joinPoint * @return */ public static String getParams(JoinPoint joinPoint) { Object[] argValues = joinPoint.getArgs(); String[] argNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames(); LinkedHashMap<String, Object> linkedHashMap = new LinkedHashMap<>(); if (argNames != null && argNames.length > 0) { for (int i = 0; i < argNames.length; i++) { String thisArgName = argNames[i]; String thisArgValue = argValues[i].toString(); linkedHashMap.put(thisArgName, thisArgValue); } } return JSON.toJSONString(linkedHashMap); } public static String getStringTodayTime() { Date todat_date = new Date(); //将日期格式化 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); //转换成字符串格式 return simpleDateFormat.format(todat_date); } }
test
-
Making request
-
No exception request
-
Abnormal request
-
-
View on Kibina
-
A warning was found in the newly added parameter in the log
-
Resolve the warning (re-update the index in the settings)
-
Check the normal log (the new parameter has no abnormality)
-
View exception log
-
View abnormal requests based on conditions
-
to sum up
- It can accurately count how many requests in the system have exceptions, as well as exception methods, request parameters, and exception information
- Will continue to synchronize the optimization in the production project to this project and output