0
点赞
收藏
分享

微信扫一扫

自定义注解完成Logger记录日志功能

目标践行者 2022-02-17 阅读 84
javalogback

其目的是添加了@SysLog的注解【该注解通过自定义实现】的全部方法,以切面的方式,收集调用时的相关信息【如用户名称,调用接口名称,ip地址等信息】执行切面方法 ,将此信息存入到数据库中。
切面方法是通过发布一个SpringEvent监听事件实现,当Listener监听到此事件的发生时,异步执行数据库操作。将信息存入到数据库中。后续开发人员可根据logger日志信息分析并处理相关的异常

步骤1 定义日志操作事件类SysLogEvent

/**
 * @author lyf
 * @projectName demo
 * @date 2022/2/16 下午 08:00
 * @description 封装日志收集到的相关信息【可以根据实际情形自定义封装需要自定义的相关信息】
 */
@Data
public class SysLogEntity {

    private  String userEmp;
    private  String descprtion;
    private  String ip;
    private  String url;
    private  String method;

}
/**
 * @author lyf
 * @projectName demo
 * @date 2022/2/16 下午 08:03
 * @description 日志事件
 */
public class SysLogEvent extends ApplicationEvent {

    public SysLogEvent(SysLogEntity entity) {
        super(entity);
    }
}

步骤2、定义@SysLog注解【涉及到SpringEvent的发布】

该注解用于在Controller的方法上标注,标识当前方法需要进行操作日志的保存处理

@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SysLog {

    /**
     * 方法描述
     *
     * @return
     */
    String descprtion() default "";

}

步骤3、定义SpringEvent——SysLogEvent

public class SysLogEvent extends ApplicationEvent {

    public SysLogEvent(SysLogEntity entity) {
        super(entity);
    }
}

步骤4、定义切面类SysLogAspect,通知方法中发布事件SysLogEvent

@Aspect
@Component
public class SysLogAspect {

    private Logger logger= LoggerFactory.getLogger(SysLogAspect.class);
    @Autowired
    HttpServletRequest request;

    @Autowired
    private ApplicationEventPublisher publisher;

    /**
     * 定义切点,当标注了@SysLog的注解之后将会执行AOP增强切面操作,执行定义的通知,存储Log信息
     */
    @Pointcut("@annotation(com.anotation.SysLog)")
    public void logPointCut() {}

    /**
     * 环绕通知
     */
    @Around(value = "logPointCut()")
    public void aroundAdvice(ProceedingJoinPoint point){
        try {
            //日志对象
            SysLogEntity entity=new SysLogEntity();
            logger.info("执行前");
            //前置通知
            MethodSignature signature = (MethodSignature)point.getSignature();
            entity.setMethod(signature.getName());
            SysLog annotation = signature.getMethod().getAnnotation(SysLog.class);
            if(annotation!=null){
                //通过反射,获得当前注解中的相关信息
                entity.setDescription(annotation.descprtion());
            }
            long startTime= System.currentTimeMillis();
            point.proceed();
            long endTime= System.currentTimeMillis();
            entity.setMs(endTime-startTime);
            entity.setIp(request.getRemoteAddr());
            entity.setUrl(request.getRequestURI());
            entity.setController(point.getTarget().toString());
            //发送LogEvent;
            ApplicationEvent event=new SysLogEvent(entity);
            publisher.publishEvent(event);
        } catch (Throwable throwable) {
            //異常通知
            throwable.printStackTrace();
        }
    }
}

步骤6、 定义事件监听器

@Component
public class LogListener {

    /**
     * 监听SyslogEvent事件的发生
     */
    @EventListener(SysLogEvent.class)
    public void saveLogListener(SysLogEvent event){
        SysLogEntity source = (SysLogEntity)event.getSource();
        //打印信息模拟数据库操作
        System.out.println("event  save data ");
        System.out.println(source.toString());

    }
}

步骤7、 测试类

@RestController
@RequestMapping("/user")
public class UserController {

    Logger logger = LoggerFactory.getLogger(UserController.class);

    @SysLog(descprtion = "获得用户信息")
    @GetMapping("/get")
    public String getUser(String emp){
        //TRACE<DEBUG 忽略
        logger.trace("trace...");
        logger.debug("debug...");
        logger.info("info...");
        logger.warn("warn...");
        logger.error("error...");
        return "OK";
    }
}

项目结构图如下,当启动测试类后,浏览器请求http://localhost:8080/user/get后,标注了@SysLog的注解将进入增强切面,获得请求调用时的相关信息,log信息会打印在控制台上,自定义注解记录log功能正常!
在这里插入图片描述
在这里插入图片描述

举报

相关推荐

0 条评论