首页 > 其他分享 >联调神器,处理你未考虑到的bug。打日志,请求日志

联调神器,处理你未考虑到的bug。打日志,请求日志

时间:2022-11-16 20:44:40浏览次数:54  
标签:ordinal log bug req 联调 import 日志 JSONField public

目录:

1、ErrorAopAdvice

package sj.aopLog;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;

/**
 * 处理全局异常,记日志
 */
@Slf4j
@RestControllerAdvice
public class ErrorAopAdvice {

    /**
     * global 处理异常
     */
    @ExceptionHandler(Throwable.class)
    public Object handleError(HttpServletRequest req, Throwable throwable) {
        log.info("handleError", throwable);

        //记日志,接口返回值,状态码500。发生未捕获异常
        ErrorResult r = ErrorResult.of(throwable, req);
        log.info("ErrorResult: " + JSON.toJSONString(r, SerializerFeature.WriteMapNullValue), throwable);
        return r;
    }

}

2、ErrorResult

package sj.aopLog;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalTime;

/**
 * 发生未捕获异常,接口的返回值。
 * 序列化排序的注解:@JSONType(orders @JSONField(ordinal = 1)
 * 指定JSON.toJSONString,属性的输出顺序
 */
@Slf4j
@Data
//@JSONType(orders = {"t", "code", "msg", "url", "queryString", "urlParam", "methodParam", "body"})
public class ErrorResult {
    @JSONField(ordinal = 1)
    public int t;//time
    @JSONField(ordinal = 2)
    public int code;
    @JSONField(ordinal = 3)
    public String msg;

    @JSONField(ordinal = 4)
    public String url;
    @JSONField(ordinal = 5)
    public String queryString;

    @JSONField(ordinal = 6)
    public Object urlParam; //地址的参数
    @JSONField(ordinal = 7)
    public Object reqBody;  //请求体,request的payload
    @JSONField(ordinal = 8)
    public Object ctrlMethParam; //controller方法的入参,controller,method,parameter

    public static <E extends Throwable> ErrorResult of(E throwable, HttpServletRequest req) {
        ErrorResult r = new ErrorResult();
        r.t = getTime();
        r.code = 500;
        r.msg = throwable.toString();

        r.url = req.getRequestURL().toString();
        r.queryString = req.getQueryString();

        r.urlParam = ReqUtil.getParam(req);
        r.reqBody = ReqUtil.getPayload(req);
        r.ctrlMethParam = req.getAttribute(LogAop.methodParam);
        return r;
    }

    /**
     * 此刻。hmms。时分秒
     *
     * @return 6166:6点16分6秒
     */
    public static int getTime() {
        StringBuilder str = new StringBuilder();
        LocalTime t = LocalTime.now();
        int h = t.getHour() % 12;//对12取模,12小时制
        int m = t.getMinute();
        int s = t.getSecond() / 10;//秒数,取第一位

        return h * 1000 + m * 10 + s;
    }

}

 

3、LogAop

package sj.aopLog;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * 切面日志,记日志
 */
@Slf4j
@Component
@Aspect
public class LogAop {
    public static final String methodParam = "methodParam";

    /**
     * 排除切面日志的切入点
     */
    @Pointcut("@annotation( sj.aopLog.LogAopExclude)")
    public void logAopExclude() {
    }

    /**
     * 切入点
     */
    @Pointcut("execution(public * sj.controller..*.*(..))")
    public void controller() {
    }

    /**
     * 环绕操作
     */
    @Around("controller() && !logAopExclude()")
    public Object doAround(ProceedingJoinPoint point) throws Throwable {
        HttpServletRequest request = ReqUtil.getHttpServletRequest();
        //保存 controller方法的参数值,到req的属性。
        Map<String, Object> methodParam = null;
        try {
            methodParam = ReqUtil.getMethodParam(point);
            request.setAttribute(LogAop.methodParam, methodParam);
        } catch (Exception e) {
            log.info("Before.error", e);
        }

        Object proceedResult = point.proceed();

        //记日志,接口返回值,状态码200。
        try {
            RightResultLog rightResultLog = RightResultLog.of(proceedResult, request, methodParam);
            log.info("RightResult: " + rightResultLog);
        } catch (Exception e) {
            log.info("AfterReturning.error", e);
        }
        return proceedResult;
    }

}

 

4、LogAopExclude

package sj.aopLog;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 切面日志的排除注解。不记日志,则在方法上加此注解
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogAopExclude {
}

 

5、ReqUtil

package sj.aopLog;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.util.StreamUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Slf4j
public class ReqUtil {

    /**
     * 获取当前 request
     */
    public static HttpServletRequest getHttpServletRequest() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            return attributes.getRequest();
        } else {
            log.info("上下文获取不到request");
            throw new RuntimeException("当前线程的上下文,获取不到request");
        }
    }

    /**
     * 简化 ParameterMap。simplify
     */
    public static Map<String, Object> getParam(HttpServletRequest req) {
        Map<String, String[]> mapStrArr = req.getParameterMap();
        Map<String, Object> r = new HashMap<>(mapStrArr.size());
        Set<String> keys = mapStrArr.keySet();
        for (String key : keys) {
            String[] strArr = mapStrArr.get(key);
            if (strArr.length == 1) {
                r.put(key, strArr[0]);
            } else {
                r.put(key, strArr);
            }
        }
        return r;
    }

    /**
     * 获取 payload,req的body
     */
    public static Object getPayload(HttpServletRequest req) {
        String method = req.getMethod();//请求方式
        // POST请求 才有payload
        if ("POST".equals(method)) {
            try {
                String payload = new String(StreamUtils.copyToByteArray(req.getInputStream()));
                return JSON.parse(payload);
            } catch (Exception e) {
                log.info("getPayload", e);
                return "getPayload Excp";
            }
        } else {
            return null;
        }
    }

    /**
     * 获取 controller方法的参数
     */
    public static Map<String, Object> getMethodParam(JoinPoint joinPoint) {
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = methodSignature.getParameterNames();
        Object[] args = joinPoint.getArgs();

        Map<String, Object> map = new HashMap<>();
        for (int i = 0; i < parameterNames.length; i++) {
            map.put(parameterNames[i], args[i]);
        }

        return map;
    }

}

 

6、RightResultLog

package sj.aopLog;

import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;

/**
 * 接口正确返回的日志
 */
@Slf4j
@Data
public class RightResultLog {
    @JSONField(ordinal = 1)
    public Object r; //result,返回值,出参

    @JSONField(ordinal = 2)
    public String url;
    @JSONField(ordinal = 3)
    public String queryString;

    @JSONField(ordinal = 4)
    public Object urlParam; //地址的参数
    @JSONField(ordinal = 5)
    public Object reqBody;  //请求体,request的payload
    @JSONField(ordinal = 6)
    public Object ctrlMethParam; //controller方法的入参,controller,method,parameter

    public static RightResultLog of(Object result, HttpServletRequest req, Object ctrlMethParam) {
        RightResultLog log = new RightResultLog();
        log.r = result;

        log.url = req.getRequestURL().toString();
        log.queryString = req.getQueryString();

        log.urlParam = ReqUtil.getParam(req);
        log.reqBody = ReqUtil.getPayload(req);
        log.ctrlMethParam = ctrlMethParam;
        return log;
    }

}

 

标签:ordinal,log,bug,req,联调,import,日志,JSONField,public
From: https://www.cnblogs.com/xsj891107/p/16897449.html

相关文章

  • 日志获取ip
    packagecom.iflytek.ggaq.jz.fk.util;importorg.springframework.web.context.request.RequestContextHolder;importorg.springframework.web.context.request.Serv......
  • IDEA debug时拷贝数据 Evaluate Expression窗口
    今日份鸡汤:别人再好,也是别人。自己再不堪,也是自己,独一无二的自己。只要努力去做最好的自己,一生足矣。为自己的人生负责,为自己的梦想买单。用IDEA调试时候经常需要拷贝变......
  • Oracle 的 Redo log 日志
    Oracle的数据库日志称为redolog,所有数据改变都记录redolog,可以用于修复受损的数据库,Redo日志是分组的,默认是3组,Redo日志是轮流使用的,一个redolog满了,LGWR会切换到下......
  • 聊聊Hive数据血缘——从Atlas没有列级血缘的Bug讲起
    前几天,Datahub提供了最新的字段级别数据血缘功能,很多朋友迫不及待想对比一下Datahub的字段级血缘与Atlas的区别。这个时候问题来了,在Atlas收集Hive血缘的时候,由于部分版本......
  • 关于pycharm中出现的一个小bug
    在pycharm中启动项目,一般直接点击pycharm右上进行配置下,然后点击右边的小三角。结果一直报错。  这个报错,很明显,可以看出启动的是该文件,所以应该找到启动文件manage.p......
  • pytest文档81 - 如何管理Captured logging日志
    前言pytest自动捕获级别为WARNING或以上的日志消息,并以与捕获的stdout和stderr相同的方式在每个失败测试的各自部分中显示它们。日志显示当输入pytest命令,不带任......
  • Python基础之注释、变量、Debug调试、数据类型
    一、注释注释的作⽤⽤⼈类熟悉的语⾔对代码进⾏解释说明,⽅便后期维护。注释分为两类:单⾏注释和多⾏注释。1、单⾏注释只能注释⼀⾏内容,语法如下:#注释内容2、多⾏注释可以......
  • node.js & npm version not match bug
    node.js&npmversionnotmatchbughttps://github.com/web-full-stack/nextjs-ssr/issues/7refs©xgqfrms2012-2020www.cnblogs.com/anonymous007发布文......
  • Next.js & React component render twice bug All In One
    Next.js&ReactcomponentrendertwicebugAllInOneerror❌solution✅//next.config.jsmodule.exports={-reactStrictMode:true,+reactStrictMode:......
  • 使用Filebeat收集K8S应用日志
    简介: Logstash收集Kubernetes的应用日志,发现logstash十分消耗内存(大约500M),而改用filebeat(大约消耗10多M内存)。在进行日志收集的过程中,我们首先想到的是使用Logstash,因......