zoukankan      html  css  js  c++  java
  • springboot 切面编程 日志模块

    1 创建一个切面类

     注意: 

    saveLog 这个方法我加了获取request里的缓存seeion的用户信息,可根据自己业务调整

    package com.another.aspect;
    
    import com.alibaba.fastjson.JSON;
    import com.another.aspect.anno.SysLog;
    import com.another.aspect.service.SysLogService;
    import com.another.book.model.User;
    import com.another.common.HttpSessionUtil;
    import org.aspectj.lang.ProceedingJoinPoint;
    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.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.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    
    /**
     * @author kql
     * 日志切面类
     */
    @Aspect
    @Component
    public class LogAspect {
    
    //    private final static Logger logger = LoggerFactory.getLogger(LogAspect.class);
    
    
        @Autowired
        private SysLogService sysLogService;
    
    
        // ..表示包及子包 该方法代表controller层的所有方法
    
        @Pointcut("execution(public * com.another.book.controller..*.*(..))")
        public void controllerMethod() {
        }
    
    /*
        @Before("controllerMethod()")
        public void LogRequestInfo(JoinPoint joinPoint) throws Exception {
    
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            User user = HttpSessionUtil.getUser(request);
    
    
            String name= null==user?" 未登陆 ":user.getName();
    
            StringBuffer requestLog = new StringBuffer();
            requestLog.append("请求信息:")
                    .append("URL = {" + request.getRequestURI() + "},	")
                    .append("HTTP_METHOD = {" + request.getMethod() + "},	")
                    .append("IP = {" + request.getRemoteAddr() + "},	")
    
                    .append("CLASS_METHOD = {" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName() + "},	")
                    .append(" 操作人 ={" + name + "},	")
            ;
    
            if (joinPoint.getArgs().length == 0) {
                requestLog.append("ARGS = {} ");
            } else {
                requestLog.append("ARGS = " + new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL)
                        .writeValueAsString(joinPoint.getArgs()[0]) + "");
            }
    
            logger.info(requestLog.toString());
        }
    
    
        @AfterReturning(returning = "resultVO", pointcut = "controllerMethod()")
        public void logResultVOInfo(ResultVO resultVO) throws Exception {
            logger.info("请求结果:" + resultVO.getCode() + "	" + resultVO.getMsg());
        }
    */
    
    
        /**
         * 环绕通知 @Around  , 当然也可以使用 @Before (前置通知)  @After (后置通知)
         *
         * @param point
         * @return
         * @throws Throwable
         */
        @Around("controllerMethod()")
        public Object around(ProceedingJoinPoint point) throws Throwable {
            long beginTime = System.currentTimeMillis();
            Object result = point.proceed();
            long time = System.currentTimeMillis() - beginTime;
            try {
                saveLog(point, time);
            } catch (Exception e) {
            }
            return result;
        }
    
        /**
         * 保存日志
         *
         * @param joinPoint
         * @param time
         */
        private void saveLog(ProceedingJoinPoint joinPoint, long time) {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            SysLogBO sysLogBO = new SysLogBO();
            sysLogBO.setExecuteTime(time);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            sysLogBO.setCreateDate(dateFormat.format(new Date()));
            SysLog sysLog = method.getAnnotation(SysLog.class);
            if (sysLog != null) {
                //注解上的描述
                sysLogBO.setRemark(sysLog.value());
            }
            //请求的 类名、方法名
    
            //操作人
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            User user = HttpSessionUtil.getUser(request);
    
            if (null!=user){
                sysLogBO.setOperatorName(user.getName());
            }else{
                sysLogBO.setOperatorName("未登陆");
            }
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = signature.getName();
            sysLogBO.setClassName(className);
            sysLogBO.setMethodName(methodName);
            //请求的参数
            Object[] args = joinPoint.getArgs();
            try {
                List<String> list = new ArrayList<String>();
                for (Object o : args) {
                    list.add(JSON.toJSONString(o));
                }
                sysLogBO.setParams(list.toString());
            } catch (Exception e) {
            }
            sysLogService.save(sysLogBO);
        }
    
    }

    2  日志service

    package com.another.aspect.service;
    
    import com.another.aspect.SysLogBO;
    import com.another.book.dao.SysLogDao;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.PageImpl;
    import org.springframework.data.domain.PageRequest;
    import org.springframework.stereotype.Service;
    
    import javax.persistence.EntityManager;
    import javax.persistence.TypedQuery;
    import javax.persistence.criteria.CriteriaBuilder;
    import javax.persistence.criteria.CriteriaQuery;
    import javax.persistence.criteria.Root;
    import java.util.List;
    import java.util.Map;
    
    /**
     * @author kql
     * @date 2018/6/4 9:41
     * @email 1529949535@qq.com
     */
    @Slf4j
    @Service
    public class SysLogService {
    
        @Autowired
        private SysLogDao sysLogDao;
    
        @Autowired
        private EntityManager entityManager;
    
        public boolean save(SysLogBO sysLogBO) {
            //输出日志
            log.info(sysLogBO.toString());
            //保存
            sysLogDao.save(sysLogBO);
            return true;
        }
    }

    3 日志实体类:

    package com.another.aspect;
    
    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Data;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    /**
     * 系统日志bo
     * @author kuangQingLin
     * @version 1.0
     * @date 2019/12/12/012 14:48
     **/
    @ApiModel("系统日志bo")
    @Table(name = "log")
    @Entity
    @JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler"})
    @Data
    public class SysLogBO {
        /**
         * 主键id
         */
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Id
        @Column(name = "id")
        @ApiModelProperty(value = "主键id ", required = true)
        private Integer id;
    
        /**
         * 类名
         */
        @Column(name = "class_name")
        private String className;
    
        /**
         * 方法名
         */
        @Column(name = "method_name")
        private String methodName;
    
        /**
         * 参数
         */
        @Column(name = "params")
        private String params;
    
        /**
         * 执行时间,毫秒
         */
        @Column(name = "execute_time")
        private Long executeTime;
    
        /**
         * 备注(方法的备注)
         */
        @Column(name = "remark")
        private String remark;
    
        /**
         * 执行开始时间
         */
        @Column(name = "create_date")
        private String createDate;
    
        /**
         * 操作人
         */
        @Column(name = "operator_name")
        private String operatorName;
    }

    4:自定义日志注解:

    package com.another.aspect.anno;
     
    import java.lang.annotation.*;
     
    /**
     * 定义系统日志注解
     * @author zhuzhe
     * @date 2018/6/4 9:24
     * @email 1529949535@qq.com
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface SysLog {
        String value() default "";
    }
    

      5 代码里使用:

      这里举例controller,   

     @SysLog("查询审批")  
        @GetMapping("/{id}")
        @ApiOperation("查询审批")
        @SysLog("查询审批")
        public String getApprove(@PathVariable("id") int id) {
            logger.info("查询审批");
            approveService.select(id);
            return "index/index";
        }

    6 dao:

    这里重写的方法是我业务中做统计时候用的,可自行更改

    package com.another.book.dao;
    
    import com.another.aspect.SysLogBO;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.jpa.repository.Query;
    
    import java.util.List;
    import java.util.Map;
    
    /**
     * @author kuangQingLin
     * @version 1.0
     * @date 2019/12/12/012 15:09
     **/
    public interface SysLogDao  extends JpaRepository<SysLogBO,Integer> {
    
        /**
         * 分组统计
         * @return
         */
        @Query(value = "SELECT DATE_FORMAT(create_date,'%Y-%m') months,COUNT(id) count FROM log GROUP BY months  ORDER BY months",nativeQuery = true)
        List<Map> select();
    }

    注意:本例持久层用的jpa

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
  • 相关阅读:
    列举⼀下 HTTP 中关于 "资源缓存" 的头部指令 (Head) 有哪些 ? 并简要介绍⼀下设置的规则 ?
    从输入URL到页面渲染完成
    git删除远程仓库分支
    @font-face的format属性
    【React】的行内样式不支持rgb
    前端面试题
    常见元素居中的五种方法
    数组存储表格数据
    java.util.Arrays类
    for-each循环
  • 原文地址:https://www.cnblogs.com/woshuaile/p/12059630.html
Copyright © 2011-2022 走看看