日志系统

2019-10-13  本文已影响0人  榷奕

1. 日志系统的难点在于AOP的应用

得把aop到底能拿来干什么整理一下,常用的那些函数,怎么构建切点切面什么的都得整理!!!

2. 日志数据表设计

从这张表的设计上面也就能看出日志系统的基本功能是什么,即:

核心是记录:谁,在什么时候,调用了哪个接口。
字段名 注释 类型 长度 是否必填 是否主键
client_ip 客户端ip varchar 100
req_uri 请求映射路径 varchar 100
method 方法名 varchar 200
param 参数 text 0
operator 操作人姓名 varchar 100
start_time 接口请求时间 varchar 50
end_time 接口返回时间 varchar 50
total_time 总消耗时间 varchar 50
return_data 接口返回数据 text 0
gmt_create 创建时间 datatime 0
gmt_create_user 创建人 varchar 50
gmt_modified 修改时间 datatime 0
gmt_modified_user 修改人 varchar 50
is_delete 是否删除(0:否 1:是) tinyint 2

3. 切面类代码

@Aspect
@Component
public class SystemLogAspect {
    
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Autowired
    private SystemLogDAO systemLogDAO;
    
    //这个逻辑还是有趣,只要是这个包里面的类都自动建立代理类,所有方法就都给代理了。
    @Pointcut("execution(public * com.cy.ops.api.*.controller..*(..))")
    public void systemLog() {}
 
    @Around(value = "systemLog()")
    public ResponseResult doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        HttpServletResponse response = attributes.getResponse();
        UserInfoBO userInfo = WebSession.getUserInfo(request, response);
        if(userInfo == null) {
            return new ResponseResult().setSuccess(false).setMessage(ResultCode.RECORD_LOGIN_EXPIRE.getMessage()).setCode(ResultCode.RECORD_LOGIN_EXPIRE.getCOde());
        }
                
        // 1、记录执行时间
        long startTime = System.currentTimeMillis();
        ResponseResult result = (ResponseResult) joinPoint.proceed(joinPoint.getArgs());
        long endTime = System.currentTimeMillis();
        long totalTime = endTime - startTime;
        
        
        // 2、有无日志监控注解,有则输出
        String methodName = joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()";
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method targetMethod = nethodSignature.getMethod();
        //这个注解的意思是如果有这个注解,就log出来
        //打这个注解的应该是debug用到的重点,这里可以换一下逻辑,log的时候把参数和输出打印出来
        if(targetMethod.isAnnotationPresent(ControllerMonitor.class)) {
            logger.info("**********Method: {}, Start: {}, End: {}, Total: {}ms**********", methodName, dateFormat.format(startTime), dateFormat.format(endTime), totalTime);
        }
        
        
        // 3、存入数据库
        //不管有没有注解,都要把访问记录存到数据库里面去
        //(感觉这才是比较赞的逻辑,只要访问了,那就要存到数据表里面,不过查bug的时候,可以重点查一下输出出来的日志)
        SystemLogDO systemLogDO = new SystemLogDO();
        if(joinPoint.getArgs().length > 0){
            systemLogDO.setPara(JsonToBeanUtil.beanToJSON(joinPoint.getArgs()[0]));
        }
        systemLogDO.setClientIp(IpUtil.getClientIp(request));
        systemLogDO.setMethod(joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()");
        systemLogDO.setOperator(userInfo.getUserName());
        systemLogDO.setReqUri(request.getRequestURI());
        systemLogDO.setReturnData(JsonToBeanUtil.beanToJSON(result));
        systemLogDO.setStartTime(String.valueOf(startTime));
        systemLogDO.setEndTime(String.valueOf(endTime));
        systemLogDO.setTotalTime(String.valueOf(totalTime));
        systemLogDO.setGmtCreateUser(userInfo.getUserName());
        systemLogDO.setGmtModifiedUser(userInfo.getUserName());
        systemLogDO.setIsDelete(0);
        systemLogDAO.insert(systemLogDO);
        return result;
    }
}
上一篇 下一篇

猜你喜欢

热点阅读