ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

若依远程调用异步方法AOP日志无法写入

2022-06-28 11:01:00  阅读:222  来源: 互联网

标签:异步 String operLog 若依 sysOperLog AOP 日志 public


问题场景描述:

修改菜单是远程异步方法可以正常写入日志,但无法写入业务操作日志.异常如下:

/**
 * 保存系统日志记录
 */
@Async //取消异步请求可以正常写入日志,但为了用户体验效果和运行速度后来想来想去还是异步快。
public void saveSysLog(SysOperLog sysOperLog){
    remoteOperLogService.saveLog(sysOperLog);
}

目前系统写入日志流程如下
1、safe-business 模块->调用者
2、ruoyi-common-log 模块->异步方法
3、ruoyi-common-log 模块->操作日志远程服务接口 feign api
4、ruoyi-api-system 模块->system模块controller
5、ruoyi-system 模块->service-impl-mapper

@PostMapping
@ResponseBody
@Log(title = "测试", businessType = BusinessType.UPDATE)
public AjaxResult add(@RequestBody Demo demo) {
    System.out.println(demo.getName());
    return AjaxResult.success(null);
}
/**
 * 自定义操作日志记录注解
 * 
 * @author 黑猫
 *
 */
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log
{
    /**
     * 模块
     */
    public String title() default "";

    /**
     * 功能
     */
    public BusinessType businessType() default BusinessType.OTHER;

    /**
     * 操作人类别
     */
    public OperatorType operatorType() default OperatorType.PC;

    /**
     * 是否保存请求的参数
     */
    public boolean isSaveRequestData() default true;
}
/**
 * 操作日志记录处理
 * 
 * @author 黑猫
 */
@Aspect
@Component
public class LogAspect{ 
	protected void handleLog(final JoinPoint joinPoint, final Exception e, Object jsonResult) {
        try
        {
            // 获得注解
            Log controllerLog = getAnnotationLog(joinPoint);
            if (controllerLog == null)
            {
                return;
            }

            // *========数据库日志=========*//
            SysOperLog operLog = new SysOperLog();
            operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
            // 请求的地址
            String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
            operLog.setOperIp(ip);
            // 返回参数
            operLog.setJsonResult(JSON.toJSONString(jsonResult));

            operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
            String username = SecurityUtils.getUsername();
            if (StringUtils.isNotBlank(username))
            {
                operLog.setOperName(username);
            }

            if (e != null)
            {
                operLog.setStatus(BusinessStatus.FAIL.ordinal());
                operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
            }
            // 设置方法名称
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            operLog.setMethod(className + "." + methodName + "()");
            // 设置请求方式
            operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
            // 处理设置注解上的参数
            getControllerMethodDescription(joinPoint, controllerLog, operLog);
            // 保存数据库
            asyncLogService.saveSysLog(operLog);//主要看这行代码
        }
        catch (Exception exp)
        {
            // 记录本地异常日志
            log.error("==前置通知异常==");
            log.error("异常信息:{}", exp.getMessage());
            exp.printStackTrace();
        }
    }
}
/**
 * 异步调用日志服务
 * 
 * @author 黑猫
 */
@Service
public class AsyncLogService
{
    @Autowired
    private RemoteLogService remoteLogService;
    @Autowired
    private RemoteOperLogService remoteOperLogService;

    /**
     * 保存系统日志记录
     */
    @Async
    public void saveSysLog(SysOperLog sysOperLog)
    {
        remoteOperLogService.saveLog(sysOperLog);
    }


}
/** 操作日志远程服务接口
 * @Author: 黑猫
 * @Date: 2022/6/28 15:41
 */
@FeignClient(contextId = "remoteOperLogService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteOperLogFallbackFactory.class)
public interface RemoteOperLogService
{
    /**
     * 保存系统日志
     * @param sysOperLog 日志实体
     * @return 结果
     */
    @PostMapping("/operlog")
    R<Boolean> saveLog(@RequestBody SysOperLog sysOperLog);

    /**
     * 保存业务操作日志记录
     * @param operLog 业务日志实体
     * @return
     */
    @PostMapping("/businessoperlog")
    R<Boolean> saveBusinessOperLog(@RequestBody JsjdBusinessOperLog operLog);
}
/**
 * 操作日志记录
 * @Author: 黑猫
 * @Date: 2022/6/28 15:41
 */
@RestController
@RequestMapping("/operlog")
public class SysOperlogController extends BaseController
{
    @PostMapping
    public AjaxResult add(@RequestBody SysOperLog operLog)
    {
        return toAjax(operLogService.insertOperlog(operLog));
    }
}

其它的代码就忽略了。

最后发现本人的问题处在FeignSecureRequestInterceptor拦截器上. 注释掉就可以正常了。

/** feign拦截器:请求header传递
 * @Author: 黑猫
 * @Date: 2022/6/28 15:41
 */

@Component
public class FeignSecureRequestInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate requestTemplate) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        Enumeration<String> headerNames = request.getHeaderNames();
        if (headerNames != null) {
            while (headerNames.hasMoreElements()) {
                String name = headerNames.nextElement();
                String values = request.getHeader(name);
                requestTemplate.header(name, values);
            }
        }
    }
}

总结:

1:启动类添加@EnableAsync注解
2:异步方法添加@async注解

注意:异步方法跟调用异步的方法不能在同一个类,如果同一个类里放就等于同步不生效。

标签:异步,String,operLog,若依,sysOperLog,AOP,日志,public
来源: https://www.cnblogs.com/zhaodefu/p/16418724.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有