Commit bbdf9e9b2e2b529a6cfec81f76bf90b520f27136

Authored by YunaiV
1 parent 63303539

【功能修复】全局:请求租户不存在时,记录访问日志、操作日志异常的问题

yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/service/ApiAccessLogFrameworkServiceImpl.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.apilog.core.service; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.apilog.core.service;
3 import cn.iocoder.yudao.module.infra.api.logger.ApiAccessLogApi; 3 import cn.iocoder.yudao.module.infra.api.logger.ApiAccessLogApi;
4 import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO; 4 import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
5 import lombok.RequiredArgsConstructor; 5 import lombok.RequiredArgsConstructor;
  6 +import lombok.extern.slf4j.Slf4j;
6 import org.springframework.scheduling.annotation.Async; 7 import org.springframework.scheduling.annotation.Async;
7 8
8 /** 9 /**
@@ -13,6 +14,7 @@ import org.springframework.scheduling.annotation.Async; @@ -13,6 +14,7 @@ import org.springframework.scheduling.annotation.Async;
13 * @author 芋道源码 14 * @author 芋道源码
14 */ 15 */
15 @RequiredArgsConstructor 16 @RequiredArgsConstructor
  17 +@Slf4j
16 public class ApiAccessLogFrameworkServiceImpl implements ApiAccessLogFrameworkService { 18 public class ApiAccessLogFrameworkServiceImpl implements ApiAccessLogFrameworkService {
17 19
18 private final ApiAccessLogApi apiAccessLogApi; 20 private final ApiAccessLogApi apiAccessLogApi;
@@ -20,7 +22,12 @@ public class ApiAccessLogFrameworkServiceImpl implements ApiAccessLogFrameworkSe @@ -20,7 +22,12 @@ public class ApiAccessLogFrameworkServiceImpl implements ApiAccessLogFrameworkSe
20 @Override 22 @Override
21 @Async 23 @Async
22 public void createApiAccessLog(ApiAccessLogCreateReqDTO reqDTO) { 24 public void createApiAccessLog(ApiAccessLogCreateReqDTO reqDTO) {
23 - apiAccessLogApi.createApiAccessLog(reqDTO); 25 + try {
  26 + apiAccessLogApi.createApiAccessLog(reqDTO);
  27 + } catch (Throwable ex) {
  28 + // 由于 @Async 异步调用,这里打印下日志,更容易跟进
  29 + log.error("[createApiAccessLog][url({}) log({}) 发生异常]", reqDTO.getRequestUrl(), reqDTO, ex);
  30 + }
24 } 31 }
25 32
26 } 33 }
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/service/ApiErrorLogFrameworkServiceImpl.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.apilog.core.service; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.apilog.core.service;
3 import cn.iocoder.yudao.module.infra.api.logger.ApiErrorLogApi; 3 import cn.iocoder.yudao.module.infra.api.logger.ApiErrorLogApi;
4 import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO; 4 import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
5 import lombok.RequiredArgsConstructor; 5 import lombok.RequiredArgsConstructor;
  6 +import lombok.extern.slf4j.Slf4j;
6 import org.springframework.scheduling.annotation.Async; 7 import org.springframework.scheduling.annotation.Async;
7 8
8 /** 9 /**
@@ -13,6 +14,7 @@ import org.springframework.scheduling.annotation.Async; @@ -13,6 +14,7 @@ import org.springframework.scheduling.annotation.Async;
13 * @author 芋道源码 14 * @author 芋道源码
14 */ 15 */
15 @RequiredArgsConstructor 16 @RequiredArgsConstructor
  17 +@Slf4j
16 public class ApiErrorLogFrameworkServiceImpl implements ApiErrorLogFrameworkService { 18 public class ApiErrorLogFrameworkServiceImpl implements ApiErrorLogFrameworkService {
17 19
18 private final ApiErrorLogApi apiErrorLogApi; 20 private final ApiErrorLogApi apiErrorLogApi;
@@ -20,7 +22,12 @@ public class ApiErrorLogFrameworkServiceImpl implements ApiErrorLogFrameworkServ @@ -20,7 +22,12 @@ public class ApiErrorLogFrameworkServiceImpl implements ApiErrorLogFrameworkServ
20 @Override 22 @Override
21 @Async 23 @Async
22 public void createApiErrorLog(ApiErrorLogCreateReqDTO reqDTO) { 24 public void createApiErrorLog(ApiErrorLogCreateReqDTO reqDTO) {
23 - apiErrorLogApi.createApiErrorLog(reqDTO); 25 + try {
  26 + apiErrorLogApi.createApiErrorLog(reqDTO);
  27 + } catch (Throwable ex) {
  28 + // 由于 @Async 异步调用,这里打印下日志,更容易跟进
  29 + log.error("[createApiErrorLog][url({}) log({}) 发生异常]", reqDTO.getRequestUrl(), reqDTO, ex);
  30 + }
24 } 31 }
25 32
26 } 33 }
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/handler/GlobalExceptionHandler.java
@@ -328,6 +328,12 @@ public class GlobalExceptionHandler { @@ -328,6 +328,12 @@ public class GlobalExceptionHandler {
328 return CommonResult.error(NOT_IMPLEMENTED.getCode(), 328 return CommonResult.error(NOT_IMPLEMENTED.getCode(),
329 "[支付模块 yudao-module-pay - 表结构未导入][参考 https://doc.iocoder.cn/pay/build/ 开启]"); 329 "[支付模块 yudao-module-pay - 表结构未导入][参考 https://doc.iocoder.cn/pay/build/ 开启]");
330 } 330 }
  331 + // 8. AI 大模型
  332 + if (message.contains("ai_")) {
  333 + log.error("[AI 大模型 yudao-module-ai - 表结构未导入][参考 https://doc.iocoder.cn/ai/build/ 开启]");
  334 + return CommonResult.error(NOT_IMPLEMENTED.getCode(),
  335 + "[AI 大模型 yudao-module-ai - 表结构未导入][参考 https://doc.iocoder.cn/ai/build/ 开启]");
  336 + }
331 return null; 337 return null;
332 } 338 }
333 339
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiAccessLogServiceImpl.java
@@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.infra.service.logger; @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.infra.service.logger;
3 import cn.hutool.core.util.StrUtil; 3 import cn.hutool.core.util.StrUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  6 +import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
  7 +import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
6 import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO; 8 import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
7 import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO; 9 import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apiaccesslog.ApiAccessLogPageReqVO;
8 import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiAccessLogDO; 10 import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiAccessLogDO;
@@ -35,7 +37,12 @@ public class ApiAccessLogServiceImpl implements ApiAccessLogService { @@ -35,7 +37,12 @@ public class ApiAccessLogServiceImpl implements ApiAccessLogService {
35 ApiAccessLogDO apiAccessLog = BeanUtils.toBean(createDTO, ApiAccessLogDO.class); 37 ApiAccessLogDO apiAccessLog = BeanUtils.toBean(createDTO, ApiAccessLogDO.class);
36 apiAccessLog.setRequestParams(StrUtil.maxLength(apiAccessLog.getRequestParams(), REQUEST_PARAMS_MAX_LENGTH)); 38 apiAccessLog.setRequestParams(StrUtil.maxLength(apiAccessLog.getRequestParams(), REQUEST_PARAMS_MAX_LENGTH));
37 apiAccessLog.setResultMsg(StrUtil.maxLength(apiAccessLog.getResultMsg(), RESULT_MSG_MAX_LENGTH)); 39 apiAccessLog.setResultMsg(StrUtil.maxLength(apiAccessLog.getResultMsg(), RESULT_MSG_MAX_LENGTH));
38 - apiAccessLogMapper.insert(apiAccessLog); 40 + if (TenantContextHolder.getTenantId() != null) {
  41 + apiAccessLogMapper.insert(apiAccessLog);
  42 + } else {
  43 + // 极端情况下,上下文中没有租户时,此时忽略租户上下文,避免插入失败!
  44 + TenantUtils.executeIgnore(() -> apiAccessLogMapper.insert(apiAccessLog));
  45 + }
39 } 46 }
40 47
41 @Override 48 @Override
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/logger/ApiErrorLogServiceImpl.java
@@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.infra.service.logger; @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.infra.service.logger;
3 import cn.hutool.core.util.StrUtil; 3 import cn.hutool.core.util.StrUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  6 +import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
  7 +import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
6 import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO; 8 import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
7 import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogPageReqVO; 9 import cn.iocoder.yudao.module.infra.controller.admin.logger.vo.apierrorlog.ApiErrorLogPageReqVO;
8 import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiErrorLogDO; 10 import cn.iocoder.yudao.module.infra.dal.dataobject.logger.ApiErrorLogDO;
@@ -25,9 +27,9 @@ import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.API_ERROR_L @@ -25,9 +27,9 @@ import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.API_ERROR_L
25 * 27 *
26 * @author 芋道源码 28 * @author 芋道源码
27 */ 29 */
28 -@Slf4j  
29 @Service 30 @Service
30 @Validated 31 @Validated
  32 +@Slf4j
31 public class ApiErrorLogServiceImpl implements ApiErrorLogService { 33 public class ApiErrorLogServiceImpl implements ApiErrorLogService {
32 34
33 @Resource 35 @Resource
@@ -38,7 +40,12 @@ public class ApiErrorLogServiceImpl implements ApiErrorLogService { @@ -38,7 +40,12 @@ public class ApiErrorLogServiceImpl implements ApiErrorLogService {
38 ApiErrorLogDO apiErrorLog = BeanUtils.toBean(createDTO, ApiErrorLogDO.class) 40 ApiErrorLogDO apiErrorLog = BeanUtils.toBean(createDTO, ApiErrorLogDO.class)
39 .setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus()); 41 .setProcessStatus(ApiErrorLogProcessStatusEnum.INIT.getStatus());
40 apiErrorLog.setRequestParams(StrUtil.maxLength(apiErrorLog.getRequestParams(), REQUEST_PARAMS_MAX_LENGTH)); 42 apiErrorLog.setRequestParams(StrUtil.maxLength(apiErrorLog.getRequestParams(), REQUEST_PARAMS_MAX_LENGTH));
41 - apiErrorLogMapper.insert(apiErrorLog); 43 + if (TenantContextHolder.getTenantId() != null) {
  44 + apiErrorLogMapper.insert(apiErrorLog);
  45 + } else {
  46 + // 极端情况下,上下文中没有租户时,此时忽略租户上下文,避免插入失败!
  47 + TenantUtils.executeIgnore(() -> apiErrorLogMapper.insert(apiErrorLog));
  48 + }
42 } 49 }
43 50
44 @Override 51 @Override
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/logger/OperateLogApi.java
@@ -23,9 +23,9 @@ public interface OperateLogApi { @@ -23,9 +23,9 @@ public interface OperateLogApi {
23 /** 23 /**
24 * 获取指定模块的指定数据的操作日志分页 24 * 获取指定模块的指定数据的操作日志分页
25 * 25 *
26 - * @param pageReqVO 请求 26 + * @param pageReqDTO 请求
27 * @return 操作日志分页 27 * @return 操作日志分页
28 */ 28 */
29 - PageResult<OperateLogRespDTO> getOperateLogPage(OperateLogPageReqDTO pageReqVO); 29 + PageResult<OperateLogRespDTO> getOperateLogPage(OperateLogPageReqDTO pageReqDTO);
30 30
31 } 31 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/logger/OperateLogApiImpl.java
@@ -33,8 +33,8 @@ public class OperateLogApiImpl implements OperateLogApi { @@ -33,8 +33,8 @@ public class OperateLogApiImpl implements OperateLogApi {
33 33
34 @Override 34 @Override
35 @TransMethodResult 35 @TransMethodResult
36 - public PageResult<OperateLogRespDTO> getOperateLogPage(OperateLogPageReqDTO pageReqVO) {  
37 - PageResult<OperateLogDO> operateLogPage = operateLogService.getOperateLogPage(pageReqVO); 36 + public PageResult<OperateLogRespDTO> getOperateLogPage(OperateLogPageReqDTO pageReqDTO) {
  37 + PageResult<OperateLogDO> operateLogPage = operateLogService.getOperateLogPage(pageReqDTO);
38 return BeanUtils.toBean(operateLogPage, OperateLogRespDTO.class); 38 return BeanUtils.toBean(operateLogPage, OperateLogRespDTO.class);
39 } 39 }
40 40