提交 284ee500 authored 作者: YunaiV's avatar YunaiV

优化 yudao-spring-boot-starter-biz-operatelog 的封装,和 yudao-cloud 保持一致

上级 8174916c
...@@ -34,6 +34,20 @@ ...@@ -34,6 +34,20 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- RPC 远程调用相关 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-spring-boot-starter-rpc</artifactId>
<optional>true</optional>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>cn.iocoder.cloud</groupId>
<artifactId>yudao-module-system-api</artifactId> <!-- 需要使用它,进行操作日志的记录 -->
<version>${revision}</version>
</dependency>
<!-- 工具类相关 --> <!-- 工具类相关 -->
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
......
package cn.iocoder.yudao.framework.operatelog.config; package cn.iocoder.yudao.framework.operatelog.config;
import cn.iocoder.yudao.framework.operatelog.core.aop.OperateLogAspect; import cn.iocoder.yudao.framework.operatelog.core.aop.OperateLogAspect;
import cn.iocoder.yudao.framework.operatelog.core.service.OperateLogFrameworkService;
import cn.iocoder.yudao.framework.operatelog.core.service.OperateLogFrameworkServiceImpl;
import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
...@@ -12,4 +15,9 @@ public class YudaoOperateLogAutoConfiguration { ...@@ -12,4 +15,9 @@ public class YudaoOperateLogAutoConfiguration {
return new OperateLogAspect(); return new OperateLogAspect();
} }
@Bean
public OperateLogFrameworkService operateLogFrameworkService(OperateLogApi operateLogApi) {
return new OperateLogFrameworkServiceImpl(operateLogApi);
}
} }
package cn.iocoder.yudao.framework.operatelog.config;
import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration;
/**
* 操作日志使用到 Feign 的配置项
*
* @author 芋道源码
*/
@Configuration(proxyBeanMethods = false)
@EnableFeignClients(clients = OperateLogApi.class) // 主要是引入相关的 API 服务
public class YudaoOperateLogRpcAutoConfiguration {
}
package cn.iocoder.yudao.framework.operatelog.core.service;
import lombok.Data;
import java.util.Date;
import java.util.Map;
/**
* 操作日志
*
* @author 芋道源码
*/
@Data
public class OperateLog {
/**
* 链路追踪编号
*/
private String traceId;
/**
* 用户编号
*/
private Long userId;
/**
* 用户类型
*/
private Integer userType;
/**
* 操作模块
*/
private String module;
/**
* 操作名
*/
private String name;
/**
* 操作分类
*/
private Integer type;
/**
* 操作明细
*/
private String content;
/**
* 拓展字段
*/
private Map<String, Object> exts;
/**
* 请求方法名
*/
private String requestMethod;
/**
* 请求地址
*/
private String requestUrl;
/**
* 用户 IP
*/
private String userIp;
/**
* 浏览器 UserAgent
*/
private String userAgent;
/**
* Java 方法名
*/
private String javaMethod;
/**
* Java 方法的参数
*/
private String javaMethodArgs;
/**
* 开始时间
*/
private Date startTime;
/**
* 执行时长,单位:毫秒
*/
private Integer duration;
/**
* 结果码
*/
private Integer resultCode;
/**
* 结果提示
*/
private String resultMsg;
/**
* 结果数据
*/
private String resultData;
}
package cn.iocoder.yudao.framework.operatelog.core.service; package cn.iocoder.yudao.framework.operatelog.core.service;
import cn.iocoder.yudao.framework.operatelog.core.dto.OperateLogCreateReqDTO; /**
* 操作日志 Framework Service 接口
import java.util.concurrent.Future; *
* @author 芋道源码
*/
public interface OperateLogFrameworkService { public interface OperateLogFrameworkService {
/** /**
* 异步记录操作日志 * 异步记录操作日志
* *
* @param reqVO 操作日志请求 * @param operateLog 操作日志请求
* @return true: 记录成功,false: 记录失败
*/ */
Future<Boolean> createOperateLogAsync(OperateLogCreateReqDTO reqVO); void createOperateLog(OperateLog operateLog);
} }
package cn.iocoder.yudao.framework.operatelog.core.service;
import cn.hutool.core.bean.BeanUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.system.api.logger.OperateLogApi;
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Async;
/**
* 操作日志 Framework Service 实现类
*
* 基于 {@link OperateLogApi} 远程服务,记录操作日志
*
* @author 芋道源码
*/
@RequiredArgsConstructor
public class OperateLogFrameworkServiceImpl implements OperateLogFrameworkService {
private final OperateLogApi operateLogApi;
@Override
@Async
public void createOperateLog(OperateLog operateLog) {
OperateLogCreateReqDTO reqDTO = BeanUtil.copyProperties(operateLog, OperateLogCreateReqDTO.class);
CommonResult<Boolean> result = operateLogApi.createOperateLog(reqDTO);
result.checkError();
}
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.iocoder.yudao.framework.operatelog.config.YudaoOperateLogRpcAutoConfiguration,\
cn.iocoder.yudao.framework.operatelog.config.YudaoOperateLogAutoConfiguration cn.iocoder.yudao.framework.operatelog.config.YudaoOperateLogAutoConfiguration
...@@ -19,7 +19,7 @@ Authorization: Bearer {{token}} ...@@ -19,7 +19,7 @@ Authorization: Bearer {{token}}
} }
### 请求 /infra/file-config/update 接口 => 成功 ### 请求 /infra/file-config/update 接口 => 成功
PUT {{baseUrl}}/infra/file-config/update PUT {{infaBaseUrl}}/infra/file-config/update
Content-Type: application/json Content-Type: application/json
tenant-id: {{adminTenentId}} tenant-id: {{adminTenentId}}
Authorization: Bearer {{token}} Authorization: Bearer {{token}}
......
package cn.iocoder.yudao.module.infra.framework; package cn.iocoder.yudao.module.infra.framework;
import cn.iocoder.yudao.framework.operatelog.core.dto.OperateLogCreateReqDTO;
import cn.iocoder.yudao.framework.operatelog.core.service.OperateLogFrameworkService;
import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService; import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import java.util.List; import java.util.List;
import java.util.concurrent.Future;
@Configuration @Configuration
public class TmpConfiguration { public class TmpConfiguration {
@Bean
public OperateLogFrameworkService operateLogFrameworkService() {
return new OperateLogFrameworkService() {
@Override
public Future<Boolean> createOperateLogAsync(OperateLogCreateReqDTO reqVO) {
return null;
}
};
}
@Bean @Bean
public TenantFrameworkService tenantFrameworkService() { public TenantFrameworkService tenantFrameworkService() {
return new TenantFrameworkService() { return new TenantFrameworkService() {
......
package cn.iocoder.yudao.module.system.api.logger;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
import cn.iocoder.yudao.module.system.enums.ApiConstants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import javax.validation.Valid;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿:fallbackFactory =
@Api(tags = "RPC 服务 - 操作日志")
public interface OperateLogApi {
String PREFIX = ApiConstants.PREFIX + "/operate-log";
@PostMapping(PREFIX + "/create")
@ApiOperation("创建操作日志")
CommonResult<Boolean> createOperateLog(@Valid @RequestBody OperateLogCreateReqDTO createReqDTO);
}
package cn.iocoder.yudao.framework.operatelog.core.dto; package cn.iocoder.yudao.module.system.api.logger.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
...@@ -8,14 +9,11 @@ import javax.validation.constraints.NotNull; ...@@ -8,14 +9,11 @@ import javax.validation.constraints.NotNull;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
/** @ApiModel("操作日志创建 Request DTO")
* 操作日志创建 Request DTO
*/
@Data @Data
public class OperateLogCreateReqDTO { public class OperateLogCreateReqDTO {
@ApiModelProperty(value = "链路追踪编号", required = true, example = "89aca178-a370-411c-ae02-3f0d672be4ab") @ApiModelProperty(value = "链路追踪编号", required = true, example = "89aca178-a370-411c-ae02-3f0d672be4ab")
@NotEmpty(message = "链路追踪编号不能为空")
private String traceId; private String traceId;
@ApiModelProperty(value = "用户编号", required = true, example = "1024") @ApiModelProperty(value = "用户编号", required = true, example = "1024")
......
package cn.iocoder.yudao.module.system.api.logger;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
import cn.iocoder.yudao.module.system.service.logger.OperateLogService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.module.system.enums.ApiConstants.VERSION;
@RestController // 提供 RESTful API 接口,给 Feign 调用
@DubboService(version = VERSION) // 提供 Dubbo RPC 接口,给 Dubbo Consumer 调用
@Validated
public class OperateLogApiImpl implements OperateLogApi {
@Resource
private OperateLogService operateLogService;
@Override
public CommonResult<Boolean> createOperateLog(OperateLogCreateReqDTO createReqDTO) {
operateLogService.createOperateLog(createReqDTO);
return success(true);
}
}
### 请求 /system/sms-template/send-sms 接口 => 成功 ### 请求 /system/sms-template/send-sms 接口 => 成功
POST {{baseUrl}}/system/sms-template/send-sms POST {{systemBaseUrl}}/system/sms-template/send-sms
Authorization: Bearer {{token}} Authorization: Bearer {{token}}
Content-Type: application/json Content-Type: application/json
tenant-id: {{adminTenentId}} tenant-id: {{adminTenentId}}
{ {
"code": "test_01", "templateCode": "test_01",
"mobile": "156016913900",
"params": { "params": {
"key01": "value01", "key01": "value01",
"key02": "value02" "key02": "value02"
......
package cn.iocoder.yudao.module.system.convert.logger; package cn.iocoder.yudao.module.system.convert.logger;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogExcelVO; import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogExcelVO;
import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogRespVO; import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogRespVO;
import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO; import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.operatelog.core.dto.OperateLogCreateReqDTO;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
......
package cn.iocoder.yudao.module.system.service.logger; package cn.iocoder.yudao.module.system.service.logger;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.operatelog.core.service.OperateLog;
import cn.iocoder.yudao.framework.operatelog.core.service.OperateLogFrameworkService; import cn.iocoder.yudao.framework.operatelog.core.service.OperateLogFrameworkService;
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogExportReqVO; import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogExportReqVO;
import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO; import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO;
import javax.validation.Valid;
import java.util.List; import java.util.List;
/** /**
* 操作日志 Service 接口 * 操作日志 Service 接口
*
* @author 芋道源码
*/ */
public interface OperateLogService extends OperateLogFrameworkService { public interface OperateLogService {
/**
* 记录操作日志
*
* @param createReqDTO 操作日志请求
*/
void createOperateLog(@Valid OperateLogCreateReqDTO createReqDTO);
/** /**
* 获得操作日志分页列表 * 获得操作日志分页列表
......
...@@ -4,7 +4,8 @@ import cn.hutool.core.collection.CollUtil; ...@@ -4,7 +4,8 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.string.StrUtils; import cn.iocoder.yudao.framework.common.util.string.StrUtils;
import cn.iocoder.yudao.framework.operatelog.core.dto.OperateLogCreateReqDTO; import cn.iocoder.yudao.framework.operatelog.core.service.OperateLog;
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogExportReqVO; import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogExportReqVO;
import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO;
import cn.iocoder.yudao.module.system.convert.logger.OperateLogConvert; import cn.iocoder.yudao.module.system.convert.logger.OperateLogConvert;
...@@ -40,19 +41,11 @@ public class OperateLogServiceImpl implements OperateLogService { ...@@ -40,19 +41,11 @@ public class OperateLogServiceImpl implements OperateLogService {
private AdminUserService userService; private AdminUserService userService;
@Override @Override
@Async public void createOperateLog(OperateLogCreateReqDTO createReqDTO) {
public Future<Boolean> createOperateLogAsync(OperateLogCreateReqDTO reqVO) { OperateLogDO logDO = OperateLogConvert.INSTANCE.convert(createReqDTO);
boolean success = false; logDO.setJavaMethodArgs(StrUtils.maxLength(logDO.getJavaMethodArgs(), JAVA_METHOD_ARGS_MAX_LENGTH));
try { logDO.setResultData(StrUtils.maxLength(logDO.getResultData(), RESULT_MAX_LENGTH));
OperateLogDO logDO = OperateLogConvert.INSTANCE.convert(reqVO); operateLogMapper.insert(logDO);
logDO.setJavaMethodArgs(StrUtils.maxLength(logDO.getJavaMethodArgs(), JAVA_METHOD_ARGS_MAX_LENGTH));
logDO.setResultData(StrUtils.maxLength(logDO.getResultData(), RESULT_MAX_LENGTH));
success = operateLogMapper.insert(logDO) == 1;
} catch (Throwable throwable) {
// 仅仅打印日志,不对外抛出。原因是,还是要保留现场数据。
log.error("[createOperateLogAsync][记录操作日志异常,日志为 ({})]", reqVO, throwable);
}
return new AsyncResult<>(success);
} }
@Override @Override
......
...@@ -7,9 +7,10 @@ import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstant ...@@ -7,9 +7,10 @@ import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstant
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
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.object.ObjectUtils; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.framework.operatelog.core.dto.OperateLogCreateReqDTO; import cn.iocoder.yudao.framework.operatelog.core.service.OperateLog;
import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum; import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum;
import cn.iocoder.yudao.framework.test.core.util.RandomUtils; import cn.iocoder.yudao.framework.test.core.util.RandomUtils;
import cn.iocoder.yudao.module.system.api.logger.dto.OperateLogCreateReqDTO;
import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogExportReqVO; import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogExportReqVO;
import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO; import cn.iocoder.yudao.module.system.controller.admin.logger.vo.operatelog.OperateLogPageReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO; import cn.iocoder.yudao.module.system.dal.dataobject.logger.OperateLogDO;
...@@ -49,7 +50,7 @@ public class OperateLogServiceImplTest extends BaseDbUnitTest { ...@@ -49,7 +50,7 @@ public class OperateLogServiceImplTest extends BaseDbUnitTest {
private AdminUserService userService; private AdminUserService userService;
@Test @Test
public void testCreateOperateLogAsync() throws InterruptedException, ExecutionException { public void testCreateOperateLogAsync() {
String traceId = TracerUtils.getTraceId(); String traceId = TracerUtils.getTraceId();
OperateLogCreateReqDTO reqVO = RandomUtils.randomPojo(OperateLogCreateReqDTO.class, o -> { OperateLogCreateReqDTO reqVO = RandomUtils.randomPojo(OperateLogCreateReqDTO.class, o -> {
o.setTraceId(traceId); o.setTraceId(traceId);
...@@ -59,8 +60,7 @@ public class OperateLogServiceImplTest extends BaseDbUnitTest { ...@@ -59,8 +60,7 @@ public class OperateLogServiceImplTest extends BaseDbUnitTest {
}); });
// 执行service方法 // 执行service方法
Future<Boolean> future = operateLogServiceImpl.createOperateLogAsync(reqVO); operateLogServiceImpl.createOperateLog(reqVO);
future.get();
// 断言插入是否正确 // 断言插入是否正确
OperateLogDO sysOperateLogDO = operateLogMapper.selectOne("trace_id", traceId); OperateLogDO sysOperateLogDO = operateLogMapper.selectOne("trace_id", traceId);
assertPojoEquals(reqVO, sysOperateLogDO); assertPojoEquals(reqVO, sysOperateLogDO);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论