1-Python基础

mac 上iterm终端显示中文为乱码解决方案

  返回  

AOP日志打印

2021/8/20 14:21:28 浏览:

需求:

在服务器运行时,拥有清晰的日志,如下图

2021-08-20 14:17:04.356 [] [http-nio-8080-exec-15] INFO  c.h.c.p.p.a.a.w.c.LogAop - [methodBefore,39] - ===============请求内容===============
2021-08-20 14:17:04.513 [] [http-nio-8080-exec-15] INFO  c.h.c.p.p.a.a.w.c.LogAop - [methodBefore,40] - 请求地址:http://ip:端口/admin/getInfo
2021-08-20 14:17:04.513 [] [http-nio-8080-exec-15] INFO  c.h.c.p.p.a.a.w.c.LogAop - [methodBefore,41] - 请求方式:GET
2021-08-20 14:17:04.514 [] [http-nio-8080-exec-15] INFO  c.h.c.p.p.a.a.w.c.LogAop - [methodBefore,42] - 请求类方法:AjaxAdminResult system.SysLoginController.getInfo()
2021-08-20 14:17:04.514 [] [http-nio-8080-exec-15] INFO  c.h.c.p.p.a.a.w.c.LogAop - [methodBefore,43] - 请求类方法参数:[]
2021-08-20 14:17:04.538 [] [http-nio-8080-exec-15] INFO  c.h.c.p.p.a.a.w.c.LogAop - [methodBefore,52] - 请求类方法参数名称和值:
2021-08-20 14:17:04.539 [] [http-nio-8080-exec-15] INFO  c.h.c.p.p.a.a.w.c.LogAop - [methodBefore,53] - ===============请求内容===============
2021-08-20 14:17:04.546 [] [http-nio-8080-exec-15] INFO  c.h.c.p.p.a.a.w.s.TokenService - [getToken,205] - request:XXXXXXX
2021-08-20 14:17:04.691 [] [http-nio-8080-exec-15] INFO  c.h.c.p.p.a.a.w.c.LogAop - [methodAfterReturing,59] - --------------返回内容----------------
2021-08-20 14:17:04.793 [] [http-nio-8080-exec-15] INFO  c.h.c.p.p.a.a.w.c.LogAop - [methodAfterReturing,60] - Response内容:{"msg":"操作成功","code":200,"permissions":["*:*:*"],"roles":["admin"],"user":{"admin":true,"avatar":"/profile/avatar/2021/08/06/c6ff1671-f0bf-4098-b225-a370c8268c5b.jpeg","createBy":"admin","createTime":1615967290000,"delFlag":"0","dept":{"children":[],"deptId":103,"deptName":"研发部门","leader":"若依","orderNum":"1","params":{},"parentId":101,"status":"0"},"deptId":103,"email":"1806361710@qq.com","loginDate":1615967290000,"loginIp":"127.0.0.1","nickName":"ysy","params":{},"password":"$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2","phonenumber":"13*****888","remark":"管理员","roles":[{"admin":true,"dataScope":"1","deptCheckStrictly":false,"flag":false,"menuCheckStrictly":false,"params":{},"roleId":1,"roleKey":"admin","roleName":"超级管理员","roleSort":"1","status":"0"}],"sex":"1","status":"0","userId":1,"userName":"admin"}}

实现代码如下

package com.huawei.cloud.phone.platform.app.admin.web.utils;

import com.alibaba.fastjson.JSON;
import org.apache.ibatis.javassist.*;
import org.apache.ibatis.javassist.bytecode.CodeAttribute;
import org.apache.ibatis.javassist.bytecode.LocalVariableAttribute;
import org.apache.ibatis.javassist.bytecode.MethodInfo;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.util.HashMap;
import java.util.Map;

public class LogAopUtil {

    public static StringBuffer getNameAndArgs(Class<?> cls, String clazzName, String methodName, Object[] args)
            throws NotFoundException {

        Map<String, Object> nameAndArgs = new HashMap<String, Object>();

        ClassPool pool = ClassPool.getDefault();
        ClassClassPath classPath = new ClassClassPath(cls);
        pool.insertClassPath(classPath);

        CtClass cc = pool.get(clazzName);
        CtMethod cm = cc.getDeclaredMethod(methodName);
        MethodInfo methodInfo = cm.getMethodInfo();
        CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
        LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
        if (attr == null) {
            // exception
        }
        int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
        for (int i = 0; i < cm.getParameterTypes().length; i++) {
            nameAndArgs.put(attr.variableName(i + pos), args[i]);// paramNames即参数名
        }
        // nameAndArgs的两种类型,用实体类接收的类似这样:
        // reqParams=com.whoareyou.fido.rest.User@616b9c0e
        // 用Map<String,Object>接收的是这样:menuNo=56473283,遍历这个map区分两种不同,使用不同的取值方式。
        // 根据获取到的值所属的不同类型通过两种不同的方法获取参数
        boolean flag = false;
        if (nameAndArgs != null && nameAndArgs.size() > 0) {
            for (Map.Entry<String, Object> entry : nameAndArgs.entrySet()) {
                if (entry.getValue() instanceof String) {
                    flag = true;
                    break;
                }
            }
        }
        StringBuffer sb = new StringBuffer();
        if (flag) {
            // 从Map中获取
            sb.append(JSON.toJSONString(nameAndArgs));
        } else {
            if (args != null) {
                for (Object object : args) {
                    if (object != null) {
                        if (object instanceof MultipartFile || object instanceof ServletRequest
                                || object instanceof ServletResponse) {
                            continue;
                        }
                        sb.append(JSON.toJSONString(object));
                    }
                }
            }
        }
        return sb;
    }

}

aop代码如下

package com.huawei.cloud.phone.platform.app.admin.web.config;

import com.alibaba.fastjson.JSON;
import com.huawei.cloud.phone.platform.app.admin.web.utils.LogAopUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

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



@Aspect
@Component
public class LogAop {

    private static final Logger log = LoggerFactory.getLogger(LogAop.class);

    // 声明一个切点 里面是 execution表达式,即访问接口的路径
    @Pointcut("execution(public * com.huawei.cloud.phone.platform.app.admin.web.controller..*.*(..))")
    private void controllerAspect() {
    }

    // 请求method前打印内容
    @Before(value = "controllerAspect()")
    public void methodBefore(JoinPoint joinPoint) throws Exception {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        // 打印请求内容
        log.info("===============请求内容===============");
        log.info("请求地址:" + request.getRequestURL().toString());
        log.info("请求方式:" + request.getMethod());
        log.info("请求类方法:" + joinPoint.getSignature());
        log.info("请求类方法参数:" + Arrays.toString(joinPoint.getArgs()));

        Object[] args = joinPoint.getArgs();
        String classType = joinPoint.getTarget().getClass().getName();
        Class<?> clazz = Class.forName(classType);
        String clazzName = clazz.getName();
        String methodName = joinPoint.getSignature().getName(); // 获取方法名称
        // 获取参数名称和值
        StringBuffer sb = LogAopUtil.getNameAndArgs(this.getClass(), clazzName, methodName, args);
        log.info("请求类方法参数名称和值:" + sb);
        log.info("===============请求内容===============");
    }

    // 在方法执行完结后打印返回内容
    @AfterReturning(returning = "o", pointcut = "controllerAspect()")
    public void methodAfterReturing(Object o) {
        log.info("--------------返回内容----------------");
        log.info("Response内容:" + JSON.toJSONString(o));
        log.info("--------------返回内容----------------");
    }
}

当然,也可以不使用切面,在需要的端口进行调用(不建议使用)

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号