aop日志-多服务统一-上传到reids

背景:
系统划分了多个微服务,想记录系统操作记录(增删改数据),但是不想每个服务都写边存储日志代码,kafka和mq等需要外搭服务的,因为某些原因无法使用。
现在想的是上传到reids(es) ,然后再一个服务统一处理,但是reids 一个担心内存爆,一个担心丢数据。后续看看能不能做成jar,在各个服务中,获取到数据库连接,然后自动创表,直接存库。

各位大神有好的想法也可以指导下小弟

LogRecodeAspect.java 具体实现





import cn.hutool.core.util.ArrayUtil;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.Maps;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
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.lang.reflect.Method;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;


/**
 * @Author: zhichong
 * @Date: 2023/7/24 18:24
 * @Description: LogRecodeAspect
 * @Version 1.0.0
 */
@Aspect
@Component
@Slf4j
public class LogRecodeAspect {
    @Value("${configuration.isEnableAopLog:false}")
    private Boolean isEnableAopLog;

    @Value("${spring.application.name:notHave}")
    private String springApplicationName;


    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Pointcut("execution(public * com.controller.*.*(..))")
    public void controllerAspectse() {
    }


    @Around(value = "controllerAspectse()")
    public Object controllerAspectse(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object result = proceedingJoinPoint.proceed();
        if(isEnableAopLog){
            result = recordLog(proceedingJoinPoint);
        }
        return result;
    }
    public Object recordLog(ProceedingJoinPoint point)  throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();
        String methodName = point.getSignature().getName();
        Object result = point.proceed();
        if(methodName.startsWith("update")||methodName.startsWith("save")){
            // 打印请求相关参数
            long startTime = System.currentTimeMillis();
            String traceId = request.getAttribute("trace_id").toString();
            final ControllerAspectseLog l = ControllerAspectseLog.builder()
                    .ip(getIp(request))
                    .url(request.getRequestURL().toString())
                    .httpMethod(request.getMethod())
                    .requestParams(getNameAndValue(point))
                    .result(result)
                    .timeCost(System.currentTimeMillis() - startTime)
                    .traceId(traceId)
                    .springApplicationName(springApplicationName)
                    .build();
            uploadData(l);
        }

        return result;
    }


    /**
     * 数据上传
     * @param l
     */
    private void uploadData(ControllerAspectseLog l) {
        String  uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
        String key = RedisConstant.REDIS_CONFIGURATION_AOP_LOG +uuid;
        redisTemplate.opsForValue().setIfAbsent(key, l, 10, TimeUnit.MINUTES);
    }

    private Map<String, Object> getNameAndValue(ProceedingJoinPoint joinPoint) {
        final Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        final String[] names = methodSignature.getParameterNames();
        final Object[] args = joinPoint.getArgs();

        if (ArrayUtil.isEmpty(names) || ArrayUtil.isEmpty(args)) {
            return Collections.emptyMap();
        }
        if (names.length != args.length) {
            log.warn("{}方法参数名和参数值数量不一致", methodSignature.getName());
            return Collections.emptyMap();
        }
        Map<String, Object> map = Maps.newHashMap();
        for (int i = 0; i < names.length; i++) {
            map.put(names[i], args[i]);
        }
        return map;
    }

    private static final String UNKNOWN = "unknown";

    public static String getIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        String comma = ",";
        String localhost = "127.0.0.1";
        if (ip.contains(comma)) {
            ip = ip.split(",")[0];
        }
        if (localhost.equals(ip)) {
            // 获取本机真正的ip地址
            try {
                ip = InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                log.error(e.getMessage(), e);
            }
        }
        return ip;
    }

}

实体类
ControllerAspectseLog.java




import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

import java.io.Serializable;

/**
 * @author Administrator
 */
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class ControllerAspectseLog extends TradeBasePo2 implements Serializable {

    private static final long serialVersionUID = 473556916427144328L;

    // ip
    private String ip;
    // url
    private String url;
    // http方法 GET POST PUT DELETE PATCH
    private String httpMethod;
    // 请求参数
    private Object requestParams;
    // 返回参数
    private Object result;
    // 接口耗时
    private Long timeCost;
    // traceId
    private String traceId;
    // 服务应用名
    private String springApplicationName;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值