SpringBoot实现增删改、登录相关的日志记录

在SpringBoot中实现对项目中的各个操作记录操作日志,此方法是最简单的方法,这样的做法需要对项目中的命名规则进行规范,比如添加用add* 编辑用 update* 删除用delete*

package com.ljq.bookshop.aop;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.ljq.bookshop.pojo.LogInfo;
import com.ljq.bookshop.pojo.UserInfo;
import com.ljq.bookshop.service.LogInfoService;
import com.ljq.bookshop.util.IpUtil;

@Aspect
@Component
public class LogAspect {

	@Autowired
	private LogInfoService logInfoService;
	/** 
     * 添加业务逻辑方法切入点 
     */ 
	@Pointcut("execution(* com.ljq.bookshop.service.*.add*(..))")  
	public void addServiceCall() { 
	}  
	
	/** 
     * 修改业务逻辑方法切入点 
     */  
    @Pointcut("execution(* com.ljq.bookshop.service.*.update*(..))")  
    public void updateServiceCall() {
    }  
    
    
    /** 
     * 删除业务逻辑方法切入点 
     * 此处拦截要拦截到具体的莫一个模块
     * 如deleteUser方法。则删除user的时候会记录日志
     */  
    @Pointcut("execution(* com.ljq.bookshop.service.*.delete*(..))")  
    public void deleteServiceCall() {
    }  
      
	
    /** 
     * 管理员添加操作日志(后置通知) 
     * @param joinPoint 
     * @param rtv 
     * @throws Throwable 
     */  
    @AfterReturning(value="addServiceCall()", argNames="rtv", returning="rtv")  
    public void insertServiceCallCalls(JoinPoint joinPoint, Object rtv) throws Throwable{  
    	HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    	UserInfo currentUser = (UserInfo) request.getSession().getAttribute("user");
    	//判断参数  
        if(joinPoint.getArgs() == null){
            return;  
        }  
        //获取方法名  
        //String methodName = joinPoint.getSignature().getName();  
        String className = joinPoint.getArgs()[0].getClass().getName();
        //获取操作内容  
		className = className.substring(className.lastIndexOf(".") + 1);
        String opContent = adminOptionContent(joinPoint.getArgs(), "添加");  
         
        //创建日志对象  
        LogInfo log = new LogInfo();
        log.setModule(className.toLowerCase());
        if(currentUser==null) {
        	log.setUserName("user");  
        }else {
        	log.setUserName(currentUser.getUsername());  
        }
              
        //操作内容  
        log.setContent(opContent);
        //操作
        log.setOperation("添加");
        log.setIp(IpUtil.getIpAddr(request));
        logInfoService.insertLog(log);
    }  
    
    
    /** 
     * 管理员修改操作日志(后置通知) 
     * @param joinPoint 
     * @param rtv 
     * @throws Throwable 
     */ 
    @AfterReturning(value="updateServiceCall()", argNames="rtv", returning="rtv")  
    public void updateServiceCallCalls(JoinPoint joinPoint, Object rtv) throws Throwable{  
    	HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    	UserInfo currentUser = (UserInfo) request.getSession().getAttribute("user");
       
          
        //判断参数  
        if(joinPoint.getArgs() == null){ 
            return;  
        }  
        //获取方法名  
        String className = joinPoint.getArgs()[0].getClass().getName();
		className = className.substring(className.lastIndexOf(".") + 1);
        //获取操作内容  
        String opContent = adminOptionContent(joinPoint.getArgs(), "修改");  
        LogInfo log = new LogInfo();  
        log.setModule(className.toLowerCase());
        if(currentUser==null) {
        	log.setUserName("user");  
        }else {
        	log.setUserName(currentUser.getUsername());  
        }
        
        //操作
        log.setContent(opContent);
        log.setOperation("修改");
        log.setIp(IpUtil.getIpAddr(request));
        //添加日志  
        logInfoService.insertLog(log);
    }  
    
    /** 
     * 管理员删除操作日志(后置通知) 
     * @param joinPoint 
     * @param rtv 
     * @throws Throwable 
     */ 
    @AfterReturning(value="deleteServiceCall()", argNames="rtv", returning="rtv")  
    public void deleteServiceCallCalls(JoinPoint joinPoint, Object rtv) throws Throwable{  
    	HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    	UserInfo currentUser = (UserInfo) request.getSession().getAttribute("user");
       
          
        //判断参数  
        if(joinPoint.getArgs() == null){ 
            return;  
        }  
        //获取方法名  
        String className = joinPoint.getTarget().getClass().getName().toLowerCase();
        try {
        	className=className.substring(0,className.indexOf("serviceimpl"));
        	className = className.substring(className.lastIndexOf(".") + 1);
        }catch(Exception e) {
        	e.printStackTrace();
        }
        //获取操作内容  
        String opContent = "ID:"+joinPoint.getArgs()[0].toString()+"->删除";  
        LogInfo log = new LogInfo(); 
        log.setModule(className);
        if(currentUser==null) {
        	log.setUserName("user");  
        }else {
        	log.setUserName(currentUser.getUsername());  
        }
          
        //操作
        log.setContent(opContent);
        log.setOperation("删除");
        log.setIp(IpUtil.getIpAddr(request));
        //添加日志  
        logInfoService.insertLog(log);        
        
    } 
    
    
	/**
	 * 使用Java反射来获取被拦截方法(insert、update)的参数值, 将参数值拼接为操作内容
	 */
	private String adminOptionContent(Object[] args, String type) throws Exception {
		if (args == null) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		Object info = args[0];
		String className = info.getClass().getName();
		className = className.substring(className.lastIndexOf(".") + 1);
		sb.append(type+className+" 属性名和值:");
		// 获取对象的所有方法
		Method[] methods = info.getClass().getDeclaredMethods();
		// 遍历方法,判断get方法
		for (Method method : methods) {
			String methodName = method.getName();
			// 判断是不是get方法
			if (methodName.indexOf("get") == -1) {
				continue;// 不处理
			}
			Object rsValue = null;
			try {
				// 调用get方法,获取返回值
				rsValue = method.invoke(info);
				if (rsValue == null) {
					continue;
				}
			} catch (Exception e) {
				continue;
			}
			// 将值加入内容中
			sb.append(" " + methodName.substring(3) + "-->" + rsValue + "  ");
		}
		return sb.toString();
	}
}

 

登录日志需要在登录后添加如下代码:

saveLog(user.getUsername(), request, session);

以下是具体的代码

/**
	 * 保存日志信息
	 * @param userName
	 * @param request
	 * @param session
	 * @throws Exception
	 */
	private void saveLog(String userName, HttpServletRequest request, HttpSession session) throws Exception {
		// 加入登陆日志
		String uri = request.getRequestURI();
		String contextPath=session.getServletContext().getContextPath();
        uri = StringUtils.remove(uri, contextPath+"/");
		LogInfo log = new LogInfo();
		log.setUserName(userName);
		log.setIp(IpUtil.getIpAddr(request));
		log.setOperation("登录");
		log.setContent(uri);
		logInfoService.insertLog(log);
	}

 

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要读取 MySQL 的增删日志文件,可以使用 MySQL 的 binlog,binlog 是 MySQL 的二进制日志记录了 MySQL 的所有更新操作,包括增删等。 下面是使用 Spring Boot 读取 MySQL binlog 的步骤: 1. 在 MySQL 配置文件中开启 binlog,可以在 my.cnf 或 my.ini 文件中添加如下配置: ``` [mysqld] log-bin=mysql-bin binlog-format=ROW ``` 这里将 binlog 日志文件存储在名为 mysql-bin 的文件中,格式为 ROW。 2. 在 Spring Boot 中添加 MySQL 驱动和 binlog 相关的依赖,例如: ``` <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.23</version> </dependency> <dependency> <groupId>com.github.shyiko</groupId> <artifactId>mysql-binlog-connector-java</artifactId> <version>0.17.0</version> </dependency> ``` 这里使用了 mysql-connector-java 和 mysql-binlog-connector-java 两个依赖。 3. 在 Spring Boot 中编写读取 binlog 日志的代码,例如: ``` @Component public class BinlogReader { private final BinaryLogClient client; public BinlogReader() { client = new BinaryLogClient("localhost", 3306, "root", "password"); client.registerEventListener(event -> { EventData data = event.getData(); if (data instanceof WriteRowsEventData) { WriteRowsEventData write = (WriteRowsEventData) data; System.out.println("inserted rows: " + write.getRows()); } else if (data instanceof UpdateRowsEventData) { UpdateRowsEventData update = (UpdateRowsEventData) data; System.out.println("updated rows: " + update.getRows()); } else if (data instanceof DeleteRowsEventData) { DeleteRowsEventData delete = (DeleteRowsEventData) data; System.out.println("deleted rows: " + delete.getRows()); } }); } @PostConstruct public void start() throws IOException { client.connect(); } @PreDestroy public void stop() throws IOException { client.disconnect(); } } ``` 这里使用了 BinaryLogClient 类来连接 MySQL,通过 registerEventListener 方法注册事件监听器来监听 binlog 日志的写入、更新、删除操作。 需要注意的是,直接读取 MySQL 的 binlog 日志文件可能会对性能和稳定性造成影响,建议在使用前先进行充分测试和评估。同时,也建议使用专业的数据库同步工具来进行 MySQL 数据库的同步,如阿里云的 DTS、腾讯云的 CDC 等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值