Merge branch 'feature/REQ-2972' into 'master'
Feature/req 2972 See merge request universal/infrastructure/backend/axzo-log-plat!126
This commit is contained in:
commit
bcfa1ed5e5
2
.reviewboardrc
Normal file
2
.reviewboardrc
Normal file
@ -0,0 +1,2 @@
|
||||
REPOSITORY = 'axzo-log-plat'
|
||||
REVIEWBOARD_URL = "https://reviewboard.axzo.cn"
|
||||
@ -0,0 +1,65 @@
|
||||
package cn.axzo.log.platform.client.feign;
|
||||
|
||||
import cn.axzo.log.platform.client.model.req.LogAddReq;
|
||||
import cn.axzo.log.platform.client.model.req.LogBatchAddReq;
|
||||
import cn.axzo.log.platform.client.model.req.LogFindReq;
|
||||
import cn.axzo.log.platform.client.model.resp.LogResp;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/11 10:31
|
||||
*/
|
||||
@FeignClient(name = "log-plat", url = "http://log-plat:8080")
|
||||
public interface LogApi {
|
||||
|
||||
/**
|
||||
* 通过筛查条件查询日志列表
|
||||
* <p>
|
||||
* 1. 若所有条件为空,则返回最近的1000条日志
|
||||
* 2. 支持分页(可通过开关控制),默认开启,最多返回1000条
|
||||
* </p>
|
||||
*
|
||||
* @param req 查询条件 {@link LogFindReq}
|
||||
* @return 日志列表
|
||||
*/
|
||||
@PostMapping(value = "/api/log/findLogsWithExample", consumes = "application/json")
|
||||
CommonResponse<List<LogResp>> findLogsWithExample(@RequestBody LogFindReq req);
|
||||
|
||||
/**
|
||||
* 通过日志id查询日志详情
|
||||
*
|
||||
* @param id 日志id
|
||||
* @return 日志
|
||||
*/
|
||||
@GetMapping(value = "/api/log/findLogById")
|
||||
CommonResponse<LogResp> findLogById(@RequestParam("id") @NotBlank(message = "id is required") String id);
|
||||
|
||||
/**
|
||||
* 添加日志
|
||||
*
|
||||
* @param req 日志信息 {@link LogAddReq}
|
||||
* @return 日志id
|
||||
*/
|
||||
@PostMapping(value = "/api/log/add", consumes = "application/json")
|
||||
CommonResponse<String> addLog(@RequestBody @Valid LogAddReq req);
|
||||
|
||||
/**
|
||||
* 批量添加日志
|
||||
*
|
||||
* @param req 日志列表 {@link LogBatchAddReq}
|
||||
* @return 日志id列表
|
||||
*/
|
||||
@PostMapping(value = "/api/log/add/batch", consumes = "application/json")
|
||||
CommonResponse<List<String>> batchAddLogs(@RequestBody @Valid LogBatchAddReq req);
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
package cn.axzo.log.platform.client.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/13 10:20
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Condition {
|
||||
|
||||
/**
|
||||
* 字段名
|
||||
*/
|
||||
@NotBlank(message = "key is required")
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* 操作符, 等于:eq, 大于:gt, 小于:le, 大于等于:ge, 小于等于:le, 不等于:ne, 包含:like, 不包含:not like, 存在:exists, 不存在:not exists
|
||||
*/
|
||||
@NotBlank(message = "operator is required")
|
||||
private String operator;
|
||||
|
||||
/**
|
||||
* 字段值
|
||||
*/
|
||||
private Object value;
|
||||
}
|
||||
@ -0,0 +1,46 @@
|
||||
package cn.axzo.log.platform.client.model.req;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 新增日志请求参数
|
||||
*
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/11 10:51
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class LogAddReq {
|
||||
|
||||
/**
|
||||
* 场景
|
||||
*/
|
||||
@NotBlank(message = "scene is required")
|
||||
private String scene;
|
||||
|
||||
/**
|
||||
* 日志级别, DEBUG, INFO, WARN, ERROR
|
||||
*/
|
||||
@NotBlank(message = "level is required")
|
||||
private String level;
|
||||
|
||||
/**
|
||||
* 日志标签,建议可以将服务名称、操作等信息作为tag
|
||||
*/
|
||||
private List<String> tags;
|
||||
|
||||
/**
|
||||
* 日志内容,需要是json格式
|
||||
*/
|
||||
@NotBlank(message = "message is required")
|
||||
private String message;
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package cn.axzo.log.platform.client.model.req;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/12 10:56
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class LogBatchAddReq {
|
||||
|
||||
@NotEmpty(message = "logs is required")
|
||||
private List<@Valid LogAddReq> logs;
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package cn.axzo.log.platform.client.model.req;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/24 14:37
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class LogBatchDeleteReq {
|
||||
|
||||
/**
|
||||
* 待删除的日志id列表
|
||||
*/
|
||||
private List<String> ids;
|
||||
}
|
||||
@ -0,0 +1,93 @@
|
||||
package cn.axzo.log.platform.client.model.req;
|
||||
|
||||
import cn.axzo.log.platform.client.model.Condition;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 查询日志列表请求参数
|
||||
*
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/11 10:45
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class LogFindReq {
|
||||
|
||||
/**
|
||||
* 场景
|
||||
*/
|
||||
private String scene;
|
||||
|
||||
/**
|
||||
* 日志级别, DEBUG, INFO, WARN, ERROR
|
||||
*/
|
||||
private String level;
|
||||
|
||||
/**
|
||||
* 日志标签
|
||||
*/
|
||||
private List<String> tags;
|
||||
|
||||
/**
|
||||
* 日志内容筛查
|
||||
* 具体使用可参考:https://alidocs.dingtalk.com/i/nodes/YndMj49yWj7q1dB9hQLNneo0V3pmz5aA
|
||||
* <p>
|
||||
* message中可嵌套json,当需要查询内部json中某个字段的相关情况时,key为message.xxx,例如:message.comments.commentId
|
||||
* "messageConditions": [
|
||||
* {
|
||||
* "key": "comments.commentId",
|
||||
* "operator": "like",
|
||||
* "value": "c"
|
||||
* },{
|
||||
* "key": "articleId",
|
||||
* "operator": "not exists"
|
||||
* }
|
||||
* ]
|
||||
* </p>
|
||||
*/
|
||||
private List<@Valid Condition> messageConditions;
|
||||
|
||||
/**
|
||||
* 开始时间,时间戳
|
||||
*/
|
||||
private Long start;
|
||||
|
||||
/**
|
||||
* 结束时间,时间戳
|
||||
*/
|
||||
private Long end;
|
||||
|
||||
/**
|
||||
* 分页页码,从1开始,与{@code pageSize}搭配使用
|
||||
* <p>
|
||||
* 1. 分页开关开启后生效,默认开启分页
|
||||
* 2. 若与{@code lastId}同时存在,则优先使用{@code lastId}参数
|
||||
* </p>
|
||||
*/
|
||||
private Integer pageNum;
|
||||
|
||||
/**
|
||||
* 分页大小,与{@code pageNum}或{@code lastId}搭配使用
|
||||
* <p>最大限制为1000</p>
|
||||
*/
|
||||
private Integer pageSize;
|
||||
|
||||
/**
|
||||
* 游标:上次请求返回的最后一条日志的id,与{@code pageSize}搭配使用
|
||||
* <p>
|
||||
* 1. 分页开关开启后生效,默认开启分页
|
||||
* 2. 默认为空,首次请求时,不传此参数
|
||||
* 3. 若与{@code pageNum}同时存在,则优先使用本参数
|
||||
* </p>
|
||||
*/
|
||||
private String lastId;
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package cn.axzo.log.platform.client.model.resp;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/11 10:38
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class LogResp {
|
||||
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 日志场景
|
||||
*/
|
||||
private String scene;
|
||||
|
||||
/**
|
||||
* 日志级别, DEBUG, INFO, WARN, ERROR
|
||||
*/
|
||||
private String level;
|
||||
|
||||
/**
|
||||
* 日志时间戳
|
||||
*/
|
||||
private Long timestamp;
|
||||
|
||||
/**
|
||||
* 日志标签,建议可以将服务名称、操作等信息作为tag
|
||||
*/
|
||||
private List<String> tags;
|
||||
|
||||
/**
|
||||
* 日志内容, json格式
|
||||
*/
|
||||
private String message;
|
||||
|
||||
public String getTimestampAsString() {
|
||||
return String.valueOf(timestamp);
|
||||
}
|
||||
}
|
||||
@ -146,6 +146,29 @@
|
||||
<groupId>cn.axzo.trade</groupId>
|
||||
<artifactId>trade-data-security-sd-extension</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.axzo.platform</groupId>
|
||||
<artifactId>axzo-log-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.graphql-java</groupId>
|
||||
<artifactId>graphql-spring-boot-starter</artifactId>
|
||||
<version>5.0.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.graphql-java</groupId>
|
||||
<artifactId>graphql-java-tools</artifactId>
|
||||
<version>5.2.4</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
||||
@ -19,7 +19,8 @@ import org.springframework.core.env.Environment;
|
||||
"cn.axzo.apollo",
|
||||
"cn.axzo.pudge",
|
||||
"cn.axzo.elise",
|
||||
"cn.axzo.basics"
|
||||
"cn.axzo.basics",
|
||||
"cn.axzo.log.platform.client"
|
||||
})
|
||||
@EnableDiscoveryClient
|
||||
@SpringBootApplication(scanBasePackages = "cn.axzo.log.platform.server")
|
||||
|
||||
@ -0,0 +1,32 @@
|
||||
package cn.axzo.log.platform.server.config;
|
||||
|
||||
import cn.axzo.basics.common.exception.ServiceException;
|
||||
import cn.axzo.framework.domain.web.result.ApiResult;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
/**
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/11 10:31
|
||||
*/
|
||||
@Order(value = 0)
|
||||
@RestControllerAdvice
|
||||
@Slf4j
|
||||
public class ExceptionAdviceHandler {
|
||||
|
||||
@ExceptionHandler(ServiceException.class)
|
||||
public ApiResult<Void> basicsServiceExceptionHandler(ServiceException e) {
|
||||
log.warn("业务异常", e);
|
||||
return ApiResult.err(e.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(cn.axzo.framework.domain.ServiceException.class)
|
||||
public ApiResult<Void> domainServiceExceptionHandler(cn.axzo.framework.domain.ServiceException e) {
|
||||
log.warn("业务异常", e);
|
||||
return ApiResult.err(e.getMessage());
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
package cn.axzo.log.platform.server.controller.api;
|
||||
|
||||
import cn.axzo.log.platform.client.feign.LogApi;
|
||||
import cn.axzo.log.platform.client.model.req.LogAddReq;
|
||||
import cn.axzo.log.platform.client.model.req.LogBatchAddReq;
|
||||
import cn.axzo.log.platform.client.model.req.LogFindReq;
|
||||
import cn.axzo.log.platform.client.model.resp.LogResp;
|
||||
import cn.axzo.log.platform.server.service.LogService;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 日志接口实现
|
||||
*
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/11 10:55
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
public class LogController implements LogApi {
|
||||
|
||||
private final LogService logService;
|
||||
|
||||
@Override
|
||||
public CommonResponse<List<LogResp>> findLogsWithExample(LogFindReq req) {
|
||||
return CommonResponse.success(logService.findLogsWithExample(req));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResponse<LogResp> findLogById(String id) {
|
||||
return CommonResponse.success(logService.findLogById(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResponse<String> addLog(LogAddReq req) {
|
||||
return CommonResponse.success(logService.addLog(req));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommonResponse<List<String>> batchAddLogs(@RequestBody @Valid LogBatchAddReq req) {
|
||||
return CommonResponse.success(logService.batchAddLogs(req));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
package cn.axzo.log.platform.server.controller.web;
|
||||
|
||||
import cn.axzo.log.platform.client.model.req.LogAddReq;
|
||||
import cn.axzo.log.platform.client.model.req.LogBatchAddReq;
|
||||
import cn.axzo.log.platform.client.model.req.LogBatchDeleteReq;
|
||||
import cn.axzo.log.platform.client.model.req.LogFindReq;
|
||||
import cn.axzo.log.platform.client.model.resp.LogResp;
|
||||
import cn.axzo.log.platform.server.service.LogService;
|
||||
import cn.azxo.framework.common.model.CommonResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/11 18:16
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/webApi/log")
|
||||
@RequiredArgsConstructor
|
||||
public class WebLogController {
|
||||
|
||||
private final LogService logService;
|
||||
|
||||
/**
|
||||
* 通过筛查条件查询日志列表
|
||||
* <p>
|
||||
* 1. 若所有条件为空,则返回最近的1000条日志
|
||||
* 2. 支持分页(可通过开关控制),默认开启,最多返回1000条
|
||||
* </p>
|
||||
*
|
||||
* @param req 查询条件 {@link LogFindReq}
|
||||
* @return 日志列表
|
||||
*/
|
||||
@PostMapping(value = "/findLogsWithExample", consumes = "application/json")
|
||||
CommonResponse<List<LogResp>> findLogsWithExample(@RequestBody @Valid LogFindReq req) {
|
||||
return CommonResponse.success(logService.findLogsWithExample(req));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过日志id查询日志详情
|
||||
*
|
||||
* @param id 日志id
|
||||
* @return 日志
|
||||
*/
|
||||
@GetMapping(value = "/findLogById")
|
||||
CommonResponse<LogResp> findLogById(@RequestParam("id") @NotBlank(message = "id is required") String id) {
|
||||
return CommonResponse.success(logService.findLogById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加日志
|
||||
*
|
||||
* @param req 日志信息 {@link LogAddReq}
|
||||
* @return 日志id
|
||||
*/
|
||||
@PostMapping(value = "/add", consumes = "application/json")
|
||||
CommonResponse<String> addLog(@RequestBody @Valid LogAddReq req) {
|
||||
return CommonResponse.success(logService.addLog(req));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加日志
|
||||
*
|
||||
* @param req 日志列表 {@link LogBatchAddReq}
|
||||
* @return 日志id列表
|
||||
*/
|
||||
@PostMapping(value = "/add/batch", consumes = "application/json")
|
||||
CommonResponse<List<String>> batchAddLogs(@RequestBody @Valid LogBatchAddReq req) {
|
||||
return CommonResponse.success(logService.batchAddLogs(req));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除日志
|
||||
*
|
||||
* @param req 待删除日志id
|
||||
*/
|
||||
@PostMapping(value = "/delete/batch")
|
||||
CommonResponse<Boolean> batchDeleteLogs(@RequestBody LogBatchDeleteReq req) {
|
||||
return CommonResponse.success(logService.batchDeleteLogs(req));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
package cn.axzo.log.platform.server.entity;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/10 11:41
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Document(collection = "log")
|
||||
public class LogEntity {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 日志场景
|
||||
*/
|
||||
private String scene;
|
||||
|
||||
/**
|
||||
* 日志级别, DEBUG, INFO, WARN, ERROR
|
||||
*/
|
||||
private String level;
|
||||
|
||||
/**
|
||||
* 日志时间
|
||||
*/
|
||||
private Long timestamp;
|
||||
|
||||
/**
|
||||
* 日志标签,建议可以将服务名称、操作等信息作为tag
|
||||
*/
|
||||
private List<String> tags;
|
||||
|
||||
/**
|
||||
* 日志内容,json格式
|
||||
*/
|
||||
private org.bson.Document message;
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package cn.axzo.log.platform.server.mapper;
|
||||
|
||||
import cn.axzo.log.platform.server.entity.LogEntity;
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/10 13:56
|
||||
*/
|
||||
@Repository
|
||||
public interface LogMapper extends MongoRepository<LogEntity, String> {
|
||||
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
package cn.axzo.log.platform.server.resolvers;
|
||||
|
||||
import cn.axzo.log.platform.client.model.req.LogAddReq;
|
||||
import cn.axzo.log.platform.client.model.req.LogBatchAddReq;
|
||||
import cn.axzo.log.platform.client.model.req.LogBatchDeleteReq;
|
||||
import cn.axzo.log.platform.client.model.req.LogFindReq;
|
||||
import cn.axzo.log.platform.client.model.resp.LogResp;
|
||||
import cn.axzo.log.platform.server.service.LogService;
|
||||
import com.coxautodev.graphql.tools.GraphQLMutationResolver;
|
||||
import com.coxautodev.graphql.tools.GraphQLQueryResolver;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/10 14:52
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class LogResolver implements GraphQLQueryResolver, GraphQLMutationResolver {
|
||||
|
||||
private final LogService logService;
|
||||
|
||||
/**
|
||||
* 通过条件筛查日志
|
||||
* <p>
|
||||
* 若所有条件为空,则返回按时间序倒排的1000条日志
|
||||
* </p>
|
||||
*
|
||||
* @param req 查询条件 {@link LogFindReq}
|
||||
* @return 按时间倒序排序的日志记录集合
|
||||
*/
|
||||
public List<LogResp> findLogsWithExample(LogFindReq req) {
|
||||
return logService.findLogsWithExample(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过id查询日志
|
||||
*
|
||||
* @param id 日志id
|
||||
* @return 日志记录
|
||||
*/
|
||||
public LogResp findLogById(String id) {
|
||||
return logService.findLogById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加日志
|
||||
*
|
||||
* @param req 日志
|
||||
* @return 日志记录id
|
||||
*/
|
||||
public String addLog(LogAddReq req) {
|
||||
return logService.addLog(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加日志
|
||||
*
|
||||
* @param req 日志列表 {@link LogBatchAddReq}
|
||||
* @return 日志id列表
|
||||
*/
|
||||
public List<String> batchAddLogs(LogBatchAddReq req) {
|
||||
return logService.batchAddLogs(req);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除日志
|
||||
*
|
||||
* @param req 待删除日志id
|
||||
*/
|
||||
public Boolean batchDeleteLogs(LogBatchDeleteReq req) {
|
||||
return logService.batchDeleteLogs(req);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package cn.axzo.log.platform.server.service;
|
||||
|
||||
import cn.axzo.log.platform.client.model.req.LogAddReq;
|
||||
import cn.axzo.log.platform.client.model.req.LogBatchAddReq;
|
||||
import cn.axzo.log.platform.client.model.req.LogBatchDeleteReq;
|
||||
import cn.axzo.log.platform.client.model.req.LogFindReq;
|
||||
import cn.axzo.log.platform.client.model.resp.LogResp;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/11 11:02
|
||||
*/
|
||||
public interface LogService {
|
||||
|
||||
String addLog(LogAddReq req);
|
||||
|
||||
LogResp findLogById(String id);
|
||||
|
||||
List<LogResp> findLogsWithExample(LogFindReq req);
|
||||
|
||||
List<String> batchAddLogs(LogBatchAddReq req);
|
||||
|
||||
Boolean batchDeleteLogs(LogBatchDeleteReq req);
|
||||
}
|
||||
@ -0,0 +1,358 @@
|
||||
package cn.axzo.log.platform.server.service.impl;
|
||||
|
||||
import cn.axzo.basics.common.util.NumberUtil;
|
||||
import cn.axzo.framework.domain.ServiceException;
|
||||
import cn.axzo.log.platform.client.model.Condition;
|
||||
import cn.axzo.log.platform.client.model.req.LogAddReq;
|
||||
import cn.axzo.log.platform.client.model.req.LogBatchAddReq;
|
||||
import cn.axzo.log.platform.client.model.req.LogBatchDeleteReq;
|
||||
import cn.axzo.log.platform.client.model.req.LogFindReq;
|
||||
import cn.axzo.log.platform.client.model.resp.LogResp;
|
||||
import cn.axzo.log.platform.server.entity.LogEntity;
|
||||
import cn.axzo.log.platform.server.mapper.LogMapper;
|
||||
import cn.axzo.log.platform.server.service.LogService;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.mongodb.client.result.DeleteResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bson.Document;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||
import org.springframework.data.mongodb.core.query.Criteria;
|
||||
import org.springframework.data.mongodb.core.query.Query;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/11 11:04
|
||||
*/
|
||||
@RefreshScope
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LogServiceImpl implements LogService {
|
||||
|
||||
private final LogMapper logMapper;
|
||||
|
||||
private final MongoTemplate mongoTemplate;
|
||||
|
||||
public static String MESSAGE_FIELD_PREFIX = "message.";
|
||||
|
||||
public static String MESSAGE_FIELD_ARRAY_DEFAULT_KEY = "\"defaultItems\"";
|
||||
|
||||
/**
|
||||
* 是否开启分页查询
|
||||
*/
|
||||
@Value("${log.enable-page:true}")
|
||||
public boolean enablePage;
|
||||
|
||||
/**
|
||||
* 添加日志
|
||||
*
|
||||
* @param req 日志信息 {@link LogAddReq}
|
||||
* @return 日志id
|
||||
*/
|
||||
@Override
|
||||
public String addLog(LogAddReq req) {
|
||||
LogEntity logEntity = buildToLogEntity(req);
|
||||
logMapper.save(logEntity);
|
||||
return logEntity.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过日志id查询日志详情
|
||||
*
|
||||
* @param id 日志id
|
||||
* @return 日志
|
||||
*/
|
||||
@Override
|
||||
public LogResp findLogById(String id) {
|
||||
return logMapper.findById(id)
|
||||
.map(logEntity -> {
|
||||
LogResp logResp = BeanUtil.copyProperties(logEntity, LogResp.class);
|
||||
logResp.setMessage(logEntity.getMessage()
|
||||
.toJson());
|
||||
return logResp;
|
||||
})
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过筛查条件查询日志列表
|
||||
* <p>
|
||||
* 若所有条件为空,则返回按时间序倒排的1000条日志
|
||||
* </p>
|
||||
*
|
||||
* @param req 查询条件 {@link LogFindReq}
|
||||
* @return 按时间倒序排序的日志列表
|
||||
*/
|
||||
@Override
|
||||
public List<LogResp> findLogsWithExample(LogFindReq req) {
|
||||
List<LogEntity> logs;
|
||||
if (Objects.isNull(req) || isAllFieldsNullOrBlankOrEmpty(req)) {
|
||||
// 按照时间倒序(即字段timestamp)查询1000条
|
||||
logs = findTopLimitOrderById(-1, 1000L);
|
||||
if (ObjectUtil.isEmpty(logs)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
} else {
|
||||
// 根据条件查询
|
||||
Query query = buildQueryCriteria(req);
|
||||
logs = mongoTemplate.find(query, LogEntity.class);
|
||||
if (CollUtil.isEmpty(logs)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
return logs.stream()
|
||||
.map(logEntity -> {
|
||||
LogResp logResp = BeanUtil.copyProperties(logEntity, LogResp.class, "message");
|
||||
logResp.setMessage(logEntity.getMessage()
|
||||
.toJson());
|
||||
return logResp;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量添加日志
|
||||
*
|
||||
* @param req 日志列表 {@link LogBatchAddReq}
|
||||
* @return 日志id列表
|
||||
*/
|
||||
@Override
|
||||
public List<String> batchAddLogs(LogBatchAddReq req) {
|
||||
List<LogEntity> logEntities = req.getLogs()
|
||||
.stream()
|
||||
.map(this::buildToLogEntity)
|
||||
.collect(Collectors.toList());
|
||||
logMapper.saveAll(logEntities);
|
||||
return logEntities.stream()
|
||||
.map(LogEntity::getId)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除日志
|
||||
*
|
||||
* @param req 待删除日志id
|
||||
*/
|
||||
@Override
|
||||
public Boolean batchDeleteLogs(LogBatchDeleteReq req) {
|
||||
if (Objects.isNull(req) || CollUtil.isEmpty(req.getIds())) {
|
||||
return true;
|
||||
}
|
||||
DeleteResult result = mongoTemplate.remove(new Query(Criteria.where("_id").in(req.getIds())), LogEntity.class);
|
||||
return result.wasAcknowledged();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建查询条件
|
||||
*
|
||||
* @param req 查询条件 {@link LogFindReq}
|
||||
* @return Query对象
|
||||
*/
|
||||
@NotNull
|
||||
private Query buildQueryCriteria(LogFindReq req) {
|
||||
Criteria criteria = new Criteria();
|
||||
if (CharSequenceUtil.isNotBlank(req.getScene())) {
|
||||
criteria.and("scene")
|
||||
.regex(req.getScene());
|
||||
}
|
||||
if (CharSequenceUtil.isNotBlank(req.getLevel())) {
|
||||
criteria.and("level")
|
||||
.is(req.getLevel());
|
||||
}
|
||||
if (CollUtil.isNotEmpty(req.getTags())) {
|
||||
criteria.and("tags")
|
||||
.all(req.getTags());
|
||||
}
|
||||
if (CollUtil.isNotEmpty(req.getMessageConditions())) {
|
||||
buildMessageCriteria(req.getMessageConditions(), criteria);
|
||||
}
|
||||
if (NumberUtil.isPositiveNumber(req.getStart())) {
|
||||
criteria.and("timestamp")
|
||||
.gte(req.getStart());
|
||||
}
|
||||
if (NumberUtil.isPositiveNumber(req.getEnd())) {
|
||||
criteria.and("timestamp")
|
||||
.lte(req.getEnd());
|
||||
}
|
||||
Query query = new Query(criteria);
|
||||
// 构建分页条件
|
||||
if (enablePage) {
|
||||
if (CharSequenceUtil.isNotBlank(req.getLastId())) {
|
||||
criteria.and("_id").lt(new ObjectId(req.getLastId()));
|
||||
} else if (NumberUtil.isPositiveNumber(req.getPageNum())) {
|
||||
query.skip((req.getPageNum() - 1) * req.getPageSize());
|
||||
}
|
||||
|
||||
if (NumberUtil.isNotPositiveNumber(req.getPageSize()) || req.getPageSize() > 1000) {
|
||||
req.setPageSize(1000);
|
||||
}
|
||||
query.limit(req.getPageSize());
|
||||
}
|
||||
Sort sort = Sort.by(Sort.Direction.DESC, "_id");
|
||||
query.with(sort);
|
||||
return query;
|
||||
}
|
||||
|
||||
private static void buildMessageCriteria(List<Condition> messageConditions, Criteria criteria) {
|
||||
for (Condition condition : messageConditions) {
|
||||
String key = condition.getKey();
|
||||
Object value = condition.getValue();
|
||||
String operator = condition.getOperator();
|
||||
switch (operator) {
|
||||
case "exists":
|
||||
// 若message字段为json对象,则判断其是否存在,若message.items 字段为数组
|
||||
criteria.and(MESSAGE_FIELD_PREFIX + key)
|
||||
.exists(true);
|
||||
break;
|
||||
case "not exists":
|
||||
criteria.and(MESSAGE_FIELD_PREFIX + key)
|
||||
.exists(false);
|
||||
break;
|
||||
case "eq":
|
||||
criteria.and(MESSAGE_FIELD_PREFIX + key)
|
||||
.is(value);
|
||||
break;
|
||||
case "ne":
|
||||
criteria.and(MESSAGE_FIELD_PREFIX + key)
|
||||
.ne(value);
|
||||
break;
|
||||
case "gt":
|
||||
criteria.and(MESSAGE_FIELD_PREFIX + key)
|
||||
.gt(value);
|
||||
break;
|
||||
case "lt":
|
||||
criteria.and(MESSAGE_FIELD_PREFIX + key)
|
||||
.lt(value);
|
||||
break;
|
||||
case "ge":
|
||||
criteria.and(MESSAGE_FIELD_PREFIX + key)
|
||||
.gte(value);
|
||||
break;
|
||||
case "le":
|
||||
criteria.and(MESSAGE_FIELD_PREFIX + key)
|
||||
.lte(value);
|
||||
break;
|
||||
case "like":
|
||||
criteria.and(MESSAGE_FIELD_PREFIX + key)
|
||||
.regex(value.toString());
|
||||
break;
|
||||
case "not like":
|
||||
criteria.and(MESSAGE_FIELD_PREFIX + key)
|
||||
.not()
|
||||
.regex(value.toString());
|
||||
break;
|
||||
default:
|
||||
throw new ServiceException("operator is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询按timestamp字段指定顺序排序后的指定条数日志记录
|
||||
*
|
||||
* @param order 1:升序,-1:降序
|
||||
* @param size 查询条数
|
||||
* @return 日志列表
|
||||
*/
|
||||
List<LogEntity> findTopLimitOrderById(Integer order, Long size) {
|
||||
Criteria criteria = Criteria.where("timestamp")
|
||||
.exists(true);
|
||||
Query query = new Query(criteria);
|
||||
query.with(Sort.by(order > 0 ? Sort.Direction.ASC : Sort.Direction.DESC, "timestamp"))
|
||||
.limit(size.intValue());
|
||||
return mongoTemplate.find(query, LogEntity.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断对象的所有字段是否都为空或空字符串。
|
||||
*
|
||||
* @param obj 需要检查的对象
|
||||
* @return 如果所有字段都是 null 或 "",返回 true;否则返回 false。
|
||||
*/
|
||||
public static boolean isAllFieldsNullOrBlankOrEmpty(Object obj) {
|
||||
Class<?> clazz = obj.getClass();
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
|
||||
for (Field field : fields) {
|
||||
try {
|
||||
// 设置访问权限,因为有些字段可能是私有的
|
||||
field.setAccessible(true);
|
||||
|
||||
Object value = field.get(obj);
|
||||
if (value instanceof String) {
|
||||
if (!((String) value).trim()
|
||||
.isEmpty()) {
|
||||
return false; // 字段不是空字符串
|
||||
}
|
||||
} else if (value instanceof Collection) {
|
||||
if (!((Collection<?>) value).isEmpty()) {
|
||||
return false; // 字段不是空集合
|
||||
}
|
||||
} else if (value != null) {
|
||||
return false; // 字段不为 null
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("Error accessing field", e);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否是合法的json对象
|
||||
*
|
||||
* @param str 字符串
|
||||
* @return true:合法,false:非法
|
||||
*/
|
||||
public static Boolean isValidJsonObject(String str) {
|
||||
if (JSONUtil.isTypeJSON(str)) {
|
||||
try {
|
||||
JSONUtil.parseObj(str);
|
||||
return true;
|
||||
} catch (Exception e1) {
|
||||
try {
|
||||
JSONUtil.parseArray(str);
|
||||
return true;
|
||||
} catch (Exception e2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private LogEntity buildToLogEntity(LogAddReq req) {
|
||||
String message = req.getMessage();
|
||||
if (JSONUtil.isTypeJSONArray(req.getMessage())) {
|
||||
message = "{" + MESSAGE_FIELD_ARRAY_DEFAULT_KEY + ":" + req.getMessage() + "}";
|
||||
}
|
||||
// 判断req.message字段是否是一个合法的json字符串
|
||||
if (Boolean.TRUE.equals(!isValidJsonObject(message))) {
|
||||
throw new ServiceException("message is not a valid json string, message: " + message);
|
||||
}
|
||||
LogEntity logEntity = BeanUtil.copyProperties(req, LogEntity.class, "message");
|
||||
logEntity.setTimestamp(System.currentTimeMillis());
|
||||
logEntity.setMessage(Document.parse(message));
|
||||
return logEntity;
|
||||
}
|
||||
}
|
||||
@ -49,8 +49,7 @@ public class LogSinkELKServiceImpl implements LogSinkELKService {
|
||||
|
||||
private Map<String, String> appKeyConfigMap = new HashMap<>();
|
||||
|
||||
@Value("${log-plat.sign.keysecret.config}")
|
||||
public void setAppKeyConfigMap(String appKeyConfig) {
|
||||
public void setAppKeyConfigMap(@Value("${log-plat.sign.keysecret.config}")String appKeyConfig) {
|
||||
Map<String, String> configMap = JSONObject.parseObject(appKeyConfig, Map.class);
|
||||
if (configMap != null) {
|
||||
this.appKeyConfigMap = configMap;
|
||||
|
||||
@ -4,7 +4,7 @@ spring:
|
||||
cloud:
|
||||
nacos:
|
||||
config:
|
||||
server-addr: ${NACOS_HOST:dev-nacos.axzo.cn}:${NACOS_PORT:80}
|
||||
server-addr: ${NACOS_HOST:https://dev-nacos.axzo.cn}:${NACOS_PORT:443}
|
||||
file-extension: yaml
|
||||
namespace: ${NACOS_NAMESPACE_ID:35eada10-9574-4db8-9fea-bc6a4960b6c7}
|
||||
prefix: ${spring.application.name}
|
||||
@ -42,4 +42,7 @@ trade:
|
||||
desensitization:
|
||||
enabled: true #开启全局脱敏
|
||||
crypt:
|
||||
enable: true #开启全局加解密
|
||||
enable: true #开启全局加解密
|
||||
|
||||
server:
|
||||
shutdown: graceful
|
||||
58
axzo-log-server/src/main/resources/graphql/log.graphqls
Normal file
58
axzo-log-server/src/main/resources/graphql/log.graphqls
Normal file
@ -0,0 +1,58 @@
|
||||
type Query {
|
||||
findLogsWithExample(logFindReq: LogFindReq): [LogResp]
|
||||
findLogById(id: ID!): LogResp
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
addLog(logReq: LogAddReq): String!
|
||||
batchAddLogs(logsReq: LogBatchAddReq): [String!]!
|
||||
batchDeleteLogs(logsReq: LogBatchDeleteReq): Boolean
|
||||
}
|
||||
|
||||
type LogResp {
|
||||
id: ID!
|
||||
scene: String!
|
||||
level: String!
|
||||
timestamp: String!
|
||||
tags: [String]
|
||||
message: String!
|
||||
}
|
||||
|
||||
# 查询日志入参
|
||||
input LogFindReq {
|
||||
scene: String
|
||||
level: String
|
||||
tags: [String]
|
||||
messageConditions: [Condition]
|
||||
start: String
|
||||
end: String
|
||||
pageNum: Int
|
||||
pageSize: Int
|
||||
lastId: String
|
||||
}
|
||||
|
||||
input Condition {
|
||||
key: String!
|
||||
operator: String!
|
||||
# 可能是字符串,数字,或浮点数
|
||||
value: String
|
||||
}
|
||||
|
||||
# 添加日志入参
|
||||
input LogAddReq {
|
||||
scene: String!
|
||||
level: String!
|
||||
tags: [String]
|
||||
message: String!
|
||||
}
|
||||
|
||||
# 批量添加日志入参
|
||||
input LogBatchAddReq {
|
||||
logs: [LogAddReq]!
|
||||
}
|
||||
|
||||
# 批量删除日志入参
|
||||
input LogBatchDeleteReq {
|
||||
ids: [ID]!
|
||||
}
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
package cn.axzo.log.platform.server.api;
|
||||
|
||||
import cn.axzo.log.platform.client.model.req.LogAddReq;
|
||||
import cn.axzo.log.platform.server.LogPlatApplicationTestBase;
|
||||
import cn.axzo.log.platform.server.controller.api.LogController;
|
||||
import cn.axzo.log.platform.server.service.MongoLogOperationTest;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/11 17:10
|
||||
*/
|
||||
public class LogApiTest extends LogPlatApplicationTestBase {
|
||||
|
||||
@Autowired
|
||||
private LogController logApi;
|
||||
|
||||
@Test
|
||||
public void addLog() {
|
||||
MongoLogOperationTest.User user = new MongoLogOperationTest.User();
|
||||
user.setName("test");
|
||||
user.setAge(18);
|
||||
LogAddReq logAddReq = LogAddReq.builder()
|
||||
.scene("test")
|
||||
.level("INFO")
|
||||
.tags(Lists.newArrayList("tag1", "tag2", "tag3", "demo", "test"))
|
||||
.message(JSONUtil.toJsonStr(user))
|
||||
.build();
|
||||
logApi.addLog(logAddReq);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,106 @@
|
||||
package cn.axzo.log.platform.server.service;
|
||||
|
||||
import cn.axzo.log.platform.server.LogPlatApplicationTestBase;
|
||||
import cn.axzo.log.platform.server.entity.LogEntity;
|
||||
import cn.axzo.log.platform.server.mapper.LogMapper;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import lombok.Data;
|
||||
import org.bson.Document;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Example;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author chenwenjian
|
||||
* @version 1.0
|
||||
* @date 2024/9/10 16:37
|
||||
*/
|
||||
public class MongoLogOperationTest extends LogPlatApplicationTestBase {
|
||||
|
||||
@Autowired
|
||||
private LogMapper logMapper;
|
||||
|
||||
@Test
|
||||
public void insertOne() {
|
||||
User user = new User();
|
||||
user.setName("whymechen");
|
||||
user.setAge(18);
|
||||
LogEntity logEntity = LogEntity.builder()
|
||||
.scene("add user")
|
||||
.level("INFO")
|
||||
.timestamp(System.currentTimeMillis())
|
||||
.tags(Arrays.asList(new String[]{"user", "axzo-log-plat"}))
|
||||
.message(Document.parse(JSONUtil.toJsonStr(user)))
|
||||
.build();
|
||||
logMapper.insert(logEntity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void insertMany() {
|
||||
User user = new User();
|
||||
user.setName("lucy");
|
||||
user.setAge(20);
|
||||
LogEntity logEntity = LogEntity.builder()
|
||||
.scene("add user")
|
||||
.level("INFO")
|
||||
.timestamp(System.currentTimeMillis())
|
||||
.tags(Arrays.asList(new String[]{"user", "axzo-log-plat"}))
|
||||
.message(Document.parse(JSONUtil.toJsonStr(user)))
|
||||
.build();
|
||||
|
||||
Animal animal = new Animal();
|
||||
animal.setName("dog");
|
||||
animal.setType("dog");
|
||||
animal.setColor("black");
|
||||
LogEntity logEntity2 = LogEntity.builder()
|
||||
.scene("add animal")
|
||||
.level("INFO")
|
||||
.timestamp(System.currentTimeMillis())
|
||||
.tags(Arrays.asList(new String[]{"animal", "axzo-log-plat"}))
|
||||
.message(Document.parse(JSONUtil.toJsonStr(animal)))
|
||||
.build();
|
||||
logMapper.insert(Lists.newArrayList(logEntity, logEntity2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findAll() {
|
||||
List<LogEntity> all = logMapper.findAll();
|
||||
System.out.println(all);
|
||||
|
||||
// logMapper.findAllByTimestampBetween(LocalDateTime.now().minusDays(1), LocalDateTime.now());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findTagWithUser() {
|
||||
LogEntity logEntity = new LogEntity();
|
||||
logEntity.setTags(Arrays.asList(new String[]{"user"}));
|
||||
Example<LogEntity> example = Example.of(logEntity);
|
||||
List<LogEntity> all = logMapper.findAll(example);
|
||||
System.out.println(all);
|
||||
|
||||
// logMapper.findAllByTimestampBetween(LocalDateTime.now().minusDays(1), LocalDateTime.now());
|
||||
}
|
||||
|
||||
public
|
||||
|
||||
|
||||
|
||||
@Data
|
||||
static class User {
|
||||
private String name;
|
||||
private Integer age;
|
||||
}
|
||||
|
||||
@Data
|
||||
static class Animal {
|
||||
private String name;
|
||||
private String type;
|
||||
|
||||
private String color;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user