Learn ELK series from scratch (11): SpringBoot project access ELK super version (super detailed graphic tutorial)

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

Architecture diagram & timing diagram

  • Architecture diagram
    Insert picture description here
  • Sequence diagram of program writing log
    Insert picture description here
  • ELK collection log and Kibina query log timing diagram
    Insert picture description here

Code

  • Complete code (GitHub, welcome to Star, Fork, Watch )

    https://github.com/dangnianchuntian/springboot

  • 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
      Insert picture description here

    • Abnormal request
      Insert picture description here

  • View on Kibina

    • A warning was found in the newly added parameter in the log
      Insert picture description here

    • Resolve the warning (re-update the index in the settings)
      Insert picture description here

    • Check the normal log (the new parameter has no abnormality)
      Insert picture description here

    • View exception log
      Insert picture description here

    • View abnormal requests based on conditions
      Insert picture description here

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

Guess you like

Origin blog.csdn.net/u012829124/article/details/108687333