天天看点

日志管理(若依框架)

表设计

日志管理(若依框架)

登录日志

逻辑:在登录或者退出时创建记录日志的任务,交给线程池执行。

代码分析

注入线程池 bean

/**
 * 执行周期性或定时任务
 */
@Bean(name = "scheduledExecutorService")
protected ScheduledExecutorService scheduledExecutorService()
{
    return new ScheduledThreadPoolExecutor(corePoolSize,
            new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build())
    {
        @Override
        protected void afterExecute(Runnable r, Throwable t)
        {
            super.afterExecute(r, t);
            Threads.printException(r, t);
        }
    };
}
           

登录

com.ruoyi.web.controller.system.SysLoginController#login

​ com.ruoyi.framework.web.service.SysLoginService#login

​ com.ruoyi.framework.manager.AsyncManager#execute

退出(LogoutSuccessHandler接口onLogoutSuccess方法,处理用户登出成功请求)

com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl#onLogoutSuccess

​ com.ruoyi.framework.manager.AsyncManager#execute

LogoutSuccessHandler配置

class: com.ruoyi.framework.config.SecurityConfig
    /**
     * 退出处理类
     */
    @Autowired
    private LogoutSuccessHandlerImpl logoutSuccessHandler;

	@Override
    protected void configure(HttpSecurity httpSecurity) throws Exception
    {
        ......
        httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler);
 		......	
    }

           

任务执行

//异步操作任务调度线程池
private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");

/**
 * 执行任务
 * 
 * @param task 任务
 */
public void execute(TimerTask task)
{
    executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
}
           

创建任务

/**
     * 记录登录信息
     * 
     * @param username 用户名
     * @param status 状态
     * @param message 消息
     * @param args 列表
     * @return 任务task
     */
    public static TimerTask recordLogininfor(final String username, final String status, final String message,
            final Object... args)
    {
		......
        return new TimerTask()
        {
            @Override
            public void run()
            {
				.......
                // 插入数据
                SpringUtils.getBean(ISysLogininforService.class).insertLogininfor(logininfor);
            }
        };
    }
           

操作日志

使用:在方法上使用注解@Log就可以实现记录操作日志的功能

@Log(title = "用户管理", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@Validated @RequestBody SysUser user)
{
    ......
    return toAjax(userService.insertUser(user));
}
           

逻辑:AOP实现,通过后置通知,异常通知来创建记录日志的任务,交给线程池执行。

代码分析

调用栈

com.ruoyi.framework.aspectj.LogAspect#doAfterReturning

com.ruoyi.framework.aspectj.LogAspect#doAfterThrowing

​ com.ruoyi.framework.aspectj.LogAspect#handleLog

​ com.ruoyi.framework.manager.AsyncManager#execute

核心类: com.ruoyi.framework.aspectj.LogAspect

/**
 * 操作日志记录处理
 * 
 * @author ruoyi
 */
@Aspect
@Component
public class LogAspect
{
    // 配置织入点
    @Pointcut("@annotation(com.ruoyi.common.annotation.Log)")
    public void logPointCut()
    {
    }

    /**
     * 处理完请求后执行
     *
     * @param joinPoint 切点
     */
    @AfterReturning(pointcut = "logPointCut()", returning = "jsonResult")
    public void doAfterReturning(JoinPoint joinPoint, Object jsonResult)
    {
        handleLog(joinPoint, null, jsonResult);
    }

    /**
     * 拦截异常操作
     * 
     * @param joinPoint 切点
     * @param e 异常
     */
    @AfterThrowing(value = "logPointCut()", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, Exception e)
    {
        handleLog(joinPoint, e, null);
    }

    protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult)
    {
        ......
            // 保存数据库
            AsyncManager.me().execute(AsyncFactory.recordOper(operLog));
        ......
    }
           

创建任务

/**
 * 操作日志记录
 * 
 * @param operLog 操作日志信息
 * @return 任务task
 */
public static TimerTask recordOper(final SysOperLog operLog)
{
    return new TimerTask()
    {
        @Override
        public void run()
        {
            // 远程查询操作地点
            operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
            // 执行插入操作
            SpringUtils.getBean(ISysOperLogService.class).insertOperlog(operLog);
        }
    };
}