springboot中實現rabbitmq異步日志記錄功能


1)定義切面;

Log.java

package com.seecen.redis.aop;

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

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {

    LogType logType() default LogType.QUERY;
    String  content() default "";

}

LogType.java

package com.seecen.redis.aop;

/**
 *
 * 日志類型枚舉類
 */
public enum LogType {
    INSERT("1"),DELETE("2"),UPDATE("3"),LOGIN("4"),QUERY("5"),REGISTER("6");
    private String type;

    LogType(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }
}

LogAspect.java

package com.seecen.redis.aop;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.seecen.redis.entity.TLog;
import com.seecen.redis.mapper.TLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
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.util.Map;

/**
 * @author bigpeng
 * @create 2020-07-22-10:17
 */
@Aspect
@Component
@Slf4j
public class LogAspect {
    @Autowired
    private TLogMapper logMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;


    //定義切入點,使用了該注解的方法將被AOP切入
    @Pointcut("@annotation( com.seecen.redis.aop.Log)")
    public void logPointCut(){}

    /**
     * 使用前置通知來完成日志的記錄
     * @param joinPoint 連接點信息
     */
    @Before("logPointCut()")
    public void logBefore(JoinPoint joinPoint) throws JsonProcessingException {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Log logAnnotation = method.getAnnotation(Log.class);
        String type = logAnnotation.logType().getType();
        String content = logAnnotation.content();
        //獲取request對象
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        //請求的IP地址
        String ip = request.getRemoteAddr();
        //請求數據
        Map<String, String[]> data = request.getParameterMap();
        String dataJsonStr="";
        if(data!=null) {
            ObjectMapper objectMapper = new ObjectMapper();
            dataJsonStr= objectMapper.writeValueAsString(data);
        }
        TLog tLog = new TLog();
        tLog.setContent(content);
        tLog.setData(dataJsonStr);
        tLog.setIp(ip);
        tLog.setType(type);
        // log {}表示占位符
        log.info("請求日志信息:{}",tLog);
        // 插入數據庫
        long start = System.currentTimeMillis();
        logMapper.insertSelective(tLog);
        log.info("直接插入數據庫耗時:{}",System.currentTimeMillis()-start);
        start=System.currentTimeMillis();
        //  發消息隊列
        rabbitTemplate.convertAndSend("log.exchange","aopLog",tLog);
        log.info("發送mq消息耗時:{}",System.currentTimeMillis()-start);
    }

}

2)在RabbitConfig.java文件中配置相關的配置信息;

RabbitConfig.java

 //聲明隊列
    @Bean
    public Queue logQueue(){
        return new Queue("log.queue");
    }
    //聲明交換機
    @Bean
    public DirectExchange logExchange(){
        return new DirectExchange("log.exchange",true,false);
    }
    //綁定交換機和隊列
    @Bean
    public Binding logBinding(){
        return BindingBuilder.bind(logQueue()).to(logExchange()).with("aopLog");
    }

3)寫一個日志的消費者;

LogConsumer.java

package com.seecen.redis.rabbitmq;

import com.seecen.redis.entity.TLog;
import com.seecen.redis.mapper.TLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class LogConsumer {
    @Autowired
    private TLogMapper logMapper;

    @RabbitListener(queues = {"log.queue"},
            containerFactory = "rabbitListenerContainerFactory")
    public void insertLog(TLog tLog){
        if (tLog!=null){
            logMapper.insertSelective(tLog);
            log.info("接收到消息:{}",tLog);
        }
    }
}

4)在需要使用的方法上面加上相關的注解;

@Log(logType = LogType.REGISTER,content = "用戶注冊")

5)測試;查看數據庫,即可看到日志信息;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM