【代码优化】框架:简化 api 访问日志、错误日志的记录逻辑

pull/140/head
YunaiV 2024-09-06 22:03:08 +08:00
parent 975ed4ce10
commit 1a5755b03a
11 changed files with 39 additions and 138 deletions

View File

@ -2,15 +2,10 @@ package cn.iocoder.yudao.framework.apilog.config;
import cn.iocoder.yudao.framework.apilog.core.filter.ApiAccessLogFilter; import cn.iocoder.yudao.framework.apilog.core.filter.ApiAccessLogFilter;
import cn.iocoder.yudao.framework.apilog.core.interceptor.ApiAccessLogInterceptor; import cn.iocoder.yudao.framework.apilog.core.interceptor.ApiAccessLogInterceptor;
import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLogFrameworkService;
import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLogFrameworkServiceImpl;
import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService;
import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkServiceImpl;
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
import cn.iocoder.yudao.framework.web.config.WebProperties; import cn.iocoder.yudao.framework.web.config.WebProperties;
import cn.iocoder.yudao.framework.web.config.YudaoWebAutoConfiguration; import cn.iocoder.yudao.framework.web.config.YudaoWebAutoConfiguration;
import cn.iocoder.yudao.module.infra.api.logger.ApiAccessLogApi; import cn.iocoder.yudao.module.infra.api.logger.ApiAccessLogApi;
import cn.iocoder.yudao.module.infra.api.logger.ApiErrorLogApi;
import jakarta.servlet.Filter; import jakarta.servlet.Filter;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
@ -23,27 +18,16 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@AutoConfiguration(after = YudaoWebAutoConfiguration.class) @AutoConfiguration(after = YudaoWebAutoConfiguration.class)
public class YudaoApiLogAutoConfiguration implements WebMvcConfigurer { public class YudaoApiLogAutoConfiguration implements WebMvcConfigurer {
@Bean
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
public ApiAccessLogFrameworkService apiAccessLogFrameworkService(ApiAccessLogApi apiAccessLogApi) {
return new ApiAccessLogFrameworkServiceImpl(apiAccessLogApi);
}
@Bean
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
public ApiErrorLogFrameworkService apiErrorLogFrameworkService(ApiErrorLogApi apiErrorLogApi) {
return new ApiErrorLogFrameworkServiceImpl(apiErrorLogApi);
}
/** /**
* ApiAccessLogFilter Bean API * ApiAccessLogFilter Bean API
*/ */
@Bean @Bean
@ConditionalOnProperty(prefix = "yudao.access-log", value = "enable", matchIfMissing = true) // 允许使用 yudao.access-log.enable=false 禁用访问日志 @ConditionalOnProperty(prefix = "yudao.access-log", value = "enable", matchIfMissing = true) // 允许使用 yudao.access-log.enable=false 禁用访问日志
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
public FilterRegistrationBean<ApiAccessLogFilter> apiAccessLogFilter(WebProperties webProperties, public FilterRegistrationBean<ApiAccessLogFilter> apiAccessLogFilter(WebProperties webProperties,
@Value("${spring.application.name}") String applicationName, @Value("${spring.application.name}") String applicationName,
ApiAccessLogFrameworkService apiAccessLogFrameworkService) { ApiAccessLogApi apiAccessLogApi) {
ApiAccessLogFilter filter = new ApiAccessLogFilter(webProperties, applicationName, apiAccessLogFrameworkService); ApiAccessLogFilter filter = new ApiAccessLogFilter(webProperties, applicationName, apiAccessLogApi);
return createFilterBean(filter, WebFilterOrderEnum.API_ACCESS_LOG_FILTER); return createFilterBean(filter, WebFilterOrderEnum.API_ACCESS_LOG_FILTER);
} }

View File

@ -4,7 +4,6 @@ import cn.iocoder.yudao.module.infra.api.logger.ApiAccessLogApi;
import cn.iocoder.yudao.module.infra.api.logger.ApiErrorLogApi; import cn.iocoder.yudao.module.infra.api.logger.ApiErrorLogApi;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
/** /**
* API 使 Feign * API 使 Feign
@ -12,7 +11,6 @@ import org.springframework.context.annotation.Configuration;
* @author * @author
*/ */
@AutoConfiguration @AutoConfiguration
@EnableFeignClients(clients = {ApiAccessLogApi.class, // 主要是引入相关的 API 服务 @EnableFeignClients(clients = {ApiAccessLogApi.class, ApiErrorLogApi.class}) // 主要是引入相关的 API 服务
ApiErrorLogApi.class})
public class YudaoApiLogRpcAutoConfiguration { public class YudaoApiLogRpcAutoConfiguration {
} }

View File

@ -9,7 +9,6 @@ import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum; import cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum;
import cn.iocoder.yudao.framework.apilog.core.service.ApiAccessLogFrameworkService;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants; import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
@ -18,6 +17,7 @@ import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.framework.web.config.WebProperties; import cn.iocoder.yudao.framework.web.config.WebProperties;
import cn.iocoder.yudao.framework.web.core.filter.ApiRequestFilter; import cn.iocoder.yudao.framework.web.core.filter.ApiRequestFilter;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.infra.api.logger.ApiAccessLogApi;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO; import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -36,7 +36,7 @@ import java.time.temporal.ChronoUnit;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import static cn.iocoder.yudao.framework.apilog.core.interceptor.ApiAccessLogInterceptor.*; import static cn.iocoder.yudao.framework.apilog.core.interceptor.ApiAccessLogInterceptor.ATTRIBUTE_HANDLER_METHOD;
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
/** /**
@ -53,12 +53,12 @@ public class ApiAccessLogFilter extends ApiRequestFilter {
private final String applicationName; private final String applicationName;
private final ApiAccessLogFrameworkService apiAccessLogFrameworkService; private final ApiAccessLogApi apiAccessLogApi;
public ApiAccessLogFilter(WebProperties webProperties, String applicationName, ApiAccessLogFrameworkService apiAccessLogFrameworkService) { public ApiAccessLogFilter(WebProperties webProperties, String applicationName, ApiAccessLogApi apiAccessLogApi) {
super(webProperties); super(webProperties);
this.applicationName = applicationName; this.applicationName = applicationName;
this.apiAccessLogFrameworkService = apiAccessLogFrameworkService; this.apiAccessLogApi = apiAccessLogApi;
} }
@Override @Override
@ -91,7 +91,7 @@ public class ApiAccessLogFilter extends ApiRequestFilter {
if (!enable) { if (!enable) {
return; return;
} }
apiAccessLogFrameworkService.createApiAccessLog(accessLog); apiAccessLogApi.createApiAccessLog(accessLog);
} catch (Throwable th) { } catch (Throwable th) {
log.error("[createApiAccessLog][url({}) log({}) 发生异常]", request.getRequestURI(), toJsonString(accessLog), th); log.error("[createApiAccessLog][url({}) log({}) 发生异常]", request.getRequestURI(), toJsonString(accessLog), th);
} }

View File

@ -1,19 +0,0 @@
package cn.iocoder.yudao.framework.apilog.core.service;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
/**
* API 访 Framework Service
*
* @author
*/
public interface ApiAccessLogFrameworkService {
/**
* API 访
*
* @param reqDTO API 访
*/
void createApiAccessLog(ApiAccessLogCreateReqDTO reqDTO);
}

View File

@ -1,33 +0,0 @@
package cn.iocoder.yudao.framework.apilog.core.service;
import cn.iocoder.yudao.module.infra.api.logger.ApiAccessLogApi;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiAccessLogCreateReqDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
/**
* API 访 Framework Service
*
* {@link ApiAccessLogApi} 访
*
* @author
*/
@RequiredArgsConstructor
@Slf4j
public class ApiAccessLogFrameworkServiceImpl implements ApiAccessLogFrameworkService {
private final ApiAccessLogApi apiAccessLogApi;
@Override
@Async
public void createApiAccessLog(ApiAccessLogCreateReqDTO reqDTO) {
try {
apiAccessLogApi.createApiAccessLog(reqDTO).checkError();
} catch (Throwable ex) {
// 由于 @Async 异步调用,这里打印下日志,更容易跟进
log.error("[createApiAccessLog][url({}) log({}) 发生异常]", reqDTO.getRequestUrl(), reqDTO, ex);
}
}
}

View File

@ -1,19 +0,0 @@
package cn.iocoder.yudao.framework.apilog.core.service;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
/**
* API Framework Service
*
* @author
*/
public interface ApiErrorLogFrameworkService {
/**
* API
*
* @param reqDTO API
*/
void createApiErrorLog(ApiErrorLogCreateReqDTO reqDTO);
}

View File

@ -1,33 +0,0 @@
package cn.iocoder.yudao.framework.apilog.core.service;
import cn.iocoder.yudao.module.infra.api.logger.ApiErrorLogApi;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
/**
* API Framework Service
*
* {@link ApiErrorLogApi}
*
* @author
*/
@RequiredArgsConstructor
@Slf4j
public class ApiErrorLogFrameworkServiceImpl implements ApiErrorLogFrameworkService {
private final ApiErrorLogApi apiErrorLogApi;
@Override
@Async
public void createApiErrorLog(ApiErrorLogCreateReqDTO reqDTO) {
try {
apiErrorLogApi.createApiErrorLog(reqDTO).checkError();
} catch (Throwable ex) {
// 由于 @Async 异步调用,这里打印下日志,更容易跟进
log.error("[createApiErrorLog][url({}) log({}) 发生异常]", reqDTO.getRequestUrl(), reqDTO, ex);
}
}
}

View File

@ -1,12 +1,12 @@
package cn.iocoder.yudao.framework.web.config; package cn.iocoder.yudao.framework.web.config;
import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService;
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum; import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
import cn.iocoder.yudao.framework.web.core.filter.CacheRequestBodyFilter; import cn.iocoder.yudao.framework.web.core.filter.CacheRequestBodyFilter;
import cn.iocoder.yudao.framework.web.core.filter.DemoFilter; import cn.iocoder.yudao.framework.web.core.filter.DemoFilter;
import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler; import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
import cn.iocoder.yudao.framework.web.core.handler.GlobalResponseBodyHandler; import cn.iocoder.yudao.framework.web.core.handler.GlobalResponseBodyHandler;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.infra.api.logger.ApiErrorLogApi;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@ -59,8 +59,9 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer {
} }
@Bean @Bean
public GlobalExceptionHandler globalExceptionHandler(ApiErrorLogFrameworkService apiErrorLogFrameworkService) { @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
return new GlobalExceptionHandler(applicationName, apiErrorLogFrameworkService); public GlobalExceptionHandler globalExceptionHandler(ApiErrorLogApi apiErrorLogApi) {
return new GlobalExceptionHandler(applicationName, apiErrorLogApi);
} }
@Bean @Bean

View File

@ -5,7 +5,6 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.servlet.JakartaServletUtil; import cn.hutool.extra.servlet.JakartaServletUtil;
import cn.iocoder.yudao.framework.apilog.core.service.ApiErrorLogFrameworkService;
import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
@ -14,6 +13,7 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils; import cn.iocoder.yudao.framework.common.util.monitor.TracerUtils;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils; import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils; import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.infra.api.logger.ApiErrorLogApi;
import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO; import cn.iocoder.yudao.module.infra.api.logger.dto.ApiErrorLogCreateReqDTO;
import com.fasterxml.jackson.databind.exc.InvalidFormatException; import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
@ -65,7 +65,7 @@ public class GlobalExceptionHandler {
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
private final String applicationName; private final String applicationName;
private final ApiErrorLogFrameworkService apiErrorLogFrameworkService; private final ApiErrorLogApi apiErrorLogApi;
/** /**
* Filter 使 * Filter 使
@ -288,7 +288,7 @@ public class GlobalExceptionHandler {
// 初始化 errorLog // 初始化 errorLog
buildExceptionLog(errorLog, req, e); buildExceptionLog(errorLog, req, e);
// 执行插入 errorLog // 执行插入 errorLog
apiErrorLogFrameworkService.createApiErrorLog(errorLog); apiErrorLogApi.createApiErrorLogAsync(errorLog);
} catch (Throwable th) { } catch (Throwable th) {
log.error("[createExceptionLog][url({}) log({}) 发生异常]", req.getRequestURI(), JsonUtils.toJsonString(errorLog), th); log.error("[createExceptionLog][url({}) log({}) 发生异常]", req.getRequestURI(), JsonUtils.toJsonString(errorLog), th);
} }

View File

@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.infra.enums.ApiConstants;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@ -21,4 +22,14 @@ public interface ApiAccessLogApi {
@Operation(summary = "创建 API 访问日志") @Operation(summary = "创建 API 访问日志")
CommonResult<Boolean> createApiAccessLog(@Valid @RequestBody ApiAccessLogCreateReqDTO createDTO); CommonResult<Boolean> createApiAccessLog(@Valid @RequestBody ApiAccessLogCreateReqDTO createDTO);
/**
* API 访
*
* @param createDTO 访 DTO
*/
@Async
default void createApiAccessLogAsync(ApiAccessLogCreateReqDTO createDTO) {
createApiAccessLog(createDTO).checkError();
}
} }

View File

@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.infra.enums.ApiConstants;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
@ -21,4 +22,14 @@ public interface ApiErrorLogApi {
@Operation(summary = "创建 API 异常日志") @Operation(summary = "创建 API 异常日志")
CommonResult<Boolean> createApiErrorLog(@Valid @RequestBody ApiErrorLogCreateReqDTO createDTO); CommonResult<Boolean> createApiErrorLog(@Valid @RequestBody ApiErrorLogCreateReqDTO createDTO);
/**
* API
*
* @param createDTO DTO
*/
@Async
default void createApiErrorLogAsync(ApiErrorLogCreateReqDTO createDTO) {
createApiErrorLog(createDTO).checkError();
}
} }