后台管理系统之系统操作日志开发(Java实现)

一,功能点

实现管理员操作数据的记录。效果如下

二,代码实现

基于注解的Aop日志记录

1.Log实体类

package com.vulcan.facade.operationlog.entity;

import lombok.Data;
import org.springframework.data.annotation.Id;

import javax.persistence.Column;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Date;


/**
 * @author lzh
 * @version 1.0
 * @describe 操作日志
 * @date 20190413
 * @copyright by lzh
 */
@Data
@Table(name = "*****")
public class OperationLog implements Serializable {

    /**
     * 主键id
     */
    @Id
    private Long id;


    /**
     * 用户id
     */
    @Column(name = "user_id")
    private Long userId;


    /**
     * 用户名称
     */
    @Column(name = "user_name")
    private String userName;


    /**
     * 描述
     */
    @Column(name = "description")
    private String description;
    /**
     * 模块
     */
    @Column(name = "module")
    private String module;

    /**
     * 操作详情
     *a
     */
    @Column(name = "content")
    private String content;

    /**
     * 请求ip
     *
     */
    @Column(name = "ip")
    private String ip;


    /**
     * 创建时间
     */
    @Column(name = "create_time")
    private Date createTime;


}

2.定义注解

package com.vulcan.log.annotation;

import java.lang.annotation.*;


/**
 * @author lzh
 * @date 20190413
 * 定义注解
 */
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {

    /**模块*/
    String module() default "";

    /**描述*/
    String description() default "";
}

3.定义切面

package com.vulcan.log.aop;

import com.vulcan.base.BaseController;
import com.vulcan.facade.permission.vo.SessionUserVO;
import com.vulcan.log.annotation.Log;
import com.vulcan.log.service.LogService;
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 java.lang.reflect.Method;

/**
 * 日志切面
 * @author vlzh
 * @date 20190413
 */

@Aspect
@Component
public class LogAspect extends BaseController {


    @Autowired
    private LogService logService;
    /**
     * 日志切入点
     */
    @Pointcut("@annotation(com.vulcan.log.annotation.Log)")
    public void logPointCut(){}


    @AfterReturning(pointcut = "logPointCut()")
    public void doAfter(JoinPoint joinPoint){
        /**
         * 解析Log注解
         */
        SessionUserVO sessionUserVO = getLoginUser();

        String methodName = joinPoint.getSignature().getName();
        Method method = currentMethod(joinPoint,methodName);
        Log log = method.getAnnotation(Log.class);
        String module = log.module();
        String description = log.description();

        logService.put(joinPoint,methodName,module,description,sessionUserVO.getUserName(),sessionUserVO.getId());
    }

    /**
     * 获取当前执行的方法
     *
     * @param joinPoint  连接点
     * @param methodName 方法名称
     * @return 方法
     */
    private Method currentMethod(JoinPoint joinPoint, String methodName) {
        /**
         * 获取目标类的所有方法,找到当前要执行的方法
         */
        Method[] methods = joinPoint.getTarget().getClass().getMethods();
        Method resultMethod = null;
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                resultMethod = method;
                break;
            }
        }
        return resultMethod;
    }

}

4.业务处理:LogService

package com.vulcan.log.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import com.vulcan.common.util.http.IPUtil;
import com.vulcan.facade.operationlog.entity.OperationLog;
import com.vulcan.facade.operationlog.service.OperationLogService;
import com.vulcan.facade.operationlog.vo.OperationLogVO;
import com.vulcan.log.service.LogService;
import javassist.*;
import javassist.bytecode.CodeAttribute;
import javassist.bytecode.LocalVariableAttribute;
import javassist.bytecode.MethodInfo;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

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

@Component
@Slf4j
public class LogServiceImpl implements LogService {

    private static final String LOG_CONTENT = "[类名]:%s,[方法]:%s,[参数]:%s,[IP]:%s";

    private String username;

    @Reference(version = "1.0.0")
    private OperationLogService operationLogService;




    public String initUsername(String username) {
        if(!StringUtils.isEmpty(username)){
            this.username = username;
        }
        return this.username;
    }


    public void put(JoinPoint joinPoint, String methodName, String module, String description, String userName, Long userId) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            OperationLog log = new OperationLog();
            if (StringUtils.isEmpty(userName)) {
                username =  "未知用户";
            }

            String ip = IPUtil.getIpAddress(request);
            log.setUserId(userId);
            log.setUserName(userName);
            log.setModule(module);
            log.setCreateTime(new Date());
            log.setDescription(description);
            log.setIp(ip);
            log.setContent(operateContent(joinPoint, methodName, ip, request));
            operationLogService.insert(log);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 查询所有日志
     * @param pageNum
     * @param request
     * @return
     */
    public List<OperationLogVO> findAllLog(int pageNum, HttpServletRequest request) {
        return null;
    }


    public String operateContent(JoinPoint joinPoint, String methodName, String ip, HttpServletRequest request) throws ClassNotFoundException, NotFoundException {
        String className = joinPoint.getTarget().getClass().getName();
        Object[] params = joinPoint.getArgs();
        String classType = joinPoint.getTarget().getClass().getName();
        Class<?> clazz = Class.forName(classType);
        String clazzName = clazz.getName();
        Map<String,Object > nameAndArgs = getFieldsName(this.getClass(), clazzName, methodName,params);
        StringBuffer bf = new StringBuffer();
        if (!CollectionUtils.isEmpty(nameAndArgs)){
            Iterator it = nameAndArgs.entrySet().iterator();
            while (it.hasNext()){
                Map.Entry entry = (Map.Entry) it.next();
                String key = (String) entry.getKey();
                String value = JSONObject.toJSONString(entry.getValue());
                bf.append(key).append("=");
                bf.append(value).append("&");
            }
        }
        if (StringUtils.isEmpty(bf.toString())){
            bf.append(request.getQueryString());
        }
        return String.format(LOG_CONTENT, className, methodName, bf.toString(), ip);
    }

    private Map<String,Object> getFieldsName(Class cls, String clazzName, String methodName,Object[] args) throws NotFoundException {
        Map<String,Object > map=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
            return map;
        }
        int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
        for (int i = 0; i < cm.getParameterTypes().length; i++){
            map.put( attr.variableName(i + pos),args[i]);//paramNames即参数名
        }
        return map;
    }
}

5、mapper

package com.vulcan.facade.mapper;

import com.vulcan.common.core.base.BaseMapper;
import com.vulcan.facade.operationlog.entity.OperationLog;
import org.springframework.stereotype.Repository;

@Repository
public interface LogMapper extends BaseMapper<OperationLog> {

}

三,使用注解在需要的地方记录日志

  /**
     * @author: lzh
     * @description:获取订单列表数据
     * @createDate: 14:06 2019/04/04
     * @param orderDTO
     * @param pagebean
     * @return: Result
     * @version: 1.0
     */
    @Log(module = "订单监控",description = "订单列表")
    @RequestMapping(value = "list", method = RequestMethod.POST)
    @ResponseBody
    public Result getOrderListPage(OrderDTO orderDTO, PageBean pagebean){
        log.info("分页查询订单参数queryOrderDTO={},pageBean={}", JSON.toJSONString(orderDTO),JSON.toJSONString(pagebean));
        Result result = this.getListOrder(orderDTO,pagebean);
        log.info("分页查询订单处理结果result={}", JSON.toJSONString(result));
        return result;
    }

 

  • 5
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值