Merge branch 'develop/oprlog_modify/221014' into 'dev'

Develop/oprlog modify/221014

See merge request infra/xlog!9
This commit is contained in:
彭健 2022-10-10 10:29:32 +00:00
commit 634ee4f527
55 changed files with 952 additions and 368 deletions

3
Dockerfile Normal file
View File

@ -0,0 +1,3 @@
FROM harbor.axzo.cn/images_base/jdk1.8-fc:v1
COPY axzo-log-server/target/axzo-log-server.jar ./axzo-log-server.jar
ENTRYPOINT [{ENTRYPOINT}]

View File

@ -1,19 +1,16 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>xlog</artifactId>
<groupId>cn.axzo.xlog</groupId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
<artifactId>axzo-log-plat</artifactId>
<groupId>cn.axzo.platform</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>xlog-client</artifactId>
<artifactId>axzo-log-api</artifactId>
<packaging>jar</packaging>
<name>xlog-client</name>
<name>axzo-log-api</name>
<url>http://maven.apache.org</url>
<properties>
@ -21,7 +18,6 @@
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>

View File

@ -1,9 +1,9 @@
package cn.axzo.xlog.client;
package cn.axzo.log.platform.client;
import cn.axzo.xlog.client.feign.XLogApi;
import cn.axzo.xlog.client.model.OperateLogQueryReq;
import cn.axzo.xlog.client.model.OperateLogQueryResp;
import cn.axzo.xlog.client.model.OperateLogReq;
import cn.axzo.log.platform.client.feign.XLogApi;
import cn.axzo.log.platform.client.model.OperateLogQueryReq;
import cn.axzo.log.platform.client.model.OperateLogQueryResp;
import cn.axzo.log.platform.client.model.OperateLogReq;
import cn.azxo.framework.common.model.CommonPageResponse;
import cn.azxo.framework.common.model.CommonResponse;
import lombok.RequiredArgsConstructor;

View File

@ -1,7 +1,8 @@
package cn.axzo.xlog.client.config;
package cn.axzo.log.platform.client.config;
import cn.axzo.xlog.client.XLogClient;
import cn.axzo.xlog.client.feign.XLogApi;
import cn.axzo.log.platform.client.XLogClient;
import cn.axzo.log.platform.client.feign.XLogApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

View File

@ -1,8 +1,8 @@
package cn.axzo.xlog.client.feign;
package cn.axzo.log.platform.client.feign;
import cn.axzo.xlog.client.model.OperateLogQueryReq;
import cn.axzo.xlog.client.model.OperateLogQueryResp;
import cn.axzo.xlog.client.model.OperateLogReq;
import cn.axzo.log.platform.client.model.OperateLogQueryReq;
import cn.axzo.log.platform.client.model.OperateLogQueryResp;
import cn.axzo.log.platform.client.model.OperateLogReq;
import cn.azxo.framework.common.model.CommonPageResponse;
import cn.azxo.framework.common.model.CommonResponse;
import org.springframework.cloud.openfeign.FeignClient;
@ -18,7 +18,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
* @description: TODO
* @date: 2022/9/16
*/
@FeignClient(name = "xlog", url = "http://xlog:10999", fallbackFactory = XLogApiFallback.class)
@FeignClient(name = "log-plat", url = "http://log-plat:8080", fallbackFactory = XLogApiFallback.class)
public interface XLogApi {
@PostMapping(value = "/api/operateLog/create", consumes = APPLICATION_JSON_VALUE)

View File

@ -1,8 +1,8 @@
package cn.axzo.xlog.client.feign;
package cn.axzo.log.platform.client.feign;
import cn.axzo.xlog.client.model.OperateLogQueryReq;
import cn.axzo.xlog.client.model.OperateLogQueryResp;
import cn.axzo.xlog.client.model.OperateLogReq;
import cn.axzo.log.platform.client.model.OperateLogQueryReq;
import cn.axzo.log.platform.client.model.OperateLogQueryResp;
import cn.axzo.log.platform.client.model.OperateLogReq;
import cn.azxo.framework.common.model.CommonPageResponse;
import cn.azxo.framework.common.model.CommonResponse;
import com.alibaba.fastjson.JSON;
@ -16,7 +16,7 @@ import lombok.extern.slf4j.Slf4j;
*/
@Slf4j
@RequiredArgsConstructor
public class XLogApiFallback implements XLogApi{
public class XLogApiFallback implements XLogApi {
@Override
public CommonResponse<Boolean> operateLogCreate(OperateLogReq req) {

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.client.model;
package cn.axzo.log.platform.client.model;
import cn.axzo.core.domain.PageRequest;
import com.fasterxml.jackson.annotation.JsonFormat;

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.client.model;
package cn.axzo.log.platform.client.model;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.client.model;
package cn.axzo.log.platform.client.model;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;

View File

@ -1,2 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.axzo.xlog.client.config.XLogClientAutoConfiguration
cn.axzo.log.platform.client.config.XLogClientAutoConfiguration

View File

@ -0,0 +1,8 @@
package cn.axzo.log.platform.client;
/**
* Unit test for simple App.
*/
public class AppTest {
}

View File

@ -1,18 +1,16 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>xlog</artifactId>
<groupId>cn.axzo.xlog</groupId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
<artifactId>axzo-log-plat</artifactId>
<groupId>cn.axzo.platform</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>xlog-server</artifactId>
<artifactId>axzo-log-server</artifactId>
<packaging>jar</packaging>
<name>xlog-server</name>
<name>axzo-log-server</name>
<url>http://maven.apache.org</url>
<properties>
@ -127,7 +125,6 @@
<groupId>cn.axzo.basics</groupId>
<artifactId>basics-profiles-api</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,30 @@
create table log_record (
id bigint auto_increment not null comment '主键' primary key,
service_name varchar(64) default '' not null comment '调用方服务名',
feature_name varchar(128) default '' not null comment '功能名称',
feature_code varchar(128) default '' not null comment '功能名称Code',
log_grade tinyint default 4 not null comment '日志等级 0:P0 1:P1 2:P2 3:P3 4:P4',
operate_time datetime default CURRENT_TIMESTAMP not null comment '操作时间',
terminal varchar(64) default '' not null comment '所属终端',
identity_id bigint default 0 not null comment '操作人Id',
identity_user_name varchar(64) default '' not null comment '操作人名字',
identity_user_phone varchar(64) default '' not null comment '操作人手机号',
identity_type bigint default 0 not null comment '操作人类型-与档案域一致 1:工人 2:班组长 3:从业人员 4:监管人员 5:运营人员',
workspace_id bigint default 0 not null comment '工作台Id',
ou_id bigint default 0 not null comment '单位Id',
workspace_name varchar(255) default '0' not null comment '工作台名字',
ou_name varchar(255) default '0' not null comment '单位名字',
resource_id bigint default 0 not null comment '资源Id 预防更小范围数据权限预留字段',
resource_type int default 0 not null comment '资源类型 预防更小范围数据权限预留字段',
operate_user_ip varchar(32) default '' not null comment '操作人Ip',
operate_before text null comment '操作前内容',
is_delete bigint default 0 not null,
create_at datetime default CURRENT_TIMESTAMP not null,
update_at datetime null,
content_summary varchar(255) default '' not null comment '内容摘要',
log_ext varchar(255) default '' not null comment '日志拓展内容',
operate_table varchar(64) default '' not null comment '操作表名',
operate_after text null comment '操作后内容',
operate_type tinyint not null comment '操作类型 1:add 2:add_batch 3:update 4:update_batch 5:delete 6:delete_batch',
operate_param text null comment '操作参数'
) comment '操作日志记录表';

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.server;
package cn.axzo.log.platform.server;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -22,7 +22,7 @@ import org.springframework.core.env.Environment;
"cn.axzo.basics"
})
@EnableDiscoveryClient
@SpringBootApplication(scanBasePackages = "cn.axzo.xlog.server")
@SpringBootApplication(scanBasePackages = "cn.axzo.log.platform.server")
public class XlogApplication {
private static final Logger logger = LoggerFactory.getLogger(XlogApplication.class);
@ -31,15 +31,11 @@ public class XlogApplication {
Environment env = context.getEnvironment();
logger.info("Application 【{}】 is running on 【{}】 environment!\n\t" +
"MySQL: \t{}\t username:{}\t\n\t" +
"Redis: \t{}:{}\t database:{}\t\n\t" +
"RabbitMQ: \t{}\t username:{},\t\n",
env.getProperty("spring.application.name"),
env.getProperty("spring.profiles.active"),
env.getProperty("spring.datasource.url"),
env.getProperty("spring.datasource.username"),
env.getProperty("spring.redis.host"),
env.getProperty("spring.redis.port"),
env.getProperty("spring.redis.database"),
env.getProperty("spring.rabbitmq.addresses"),
env.getProperty("spring.rabbitmq.username"));
}

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.server.config;
package cn.axzo.log.platform.server.config;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
@ -25,16 +25,16 @@ public class EsClientConfig {
private final Logger logger = LoggerFactory.getLogger(EsClientConfig.class);
@Value("${xlog.elasticsearch.host:121.196.20.126}")
@Value("${log-plat.elasticsearch.host:121.196.20.126}")
private String host;
@Value("${xlog.elasticsearch.port:31647}")
@Value("${log-plat.elasticsearch.port:31647}")
private int port;
@Value("${xlog.elasticsearch.username:elastic}")
@Value("${log-plat.elasticsearch.username:elastic}")
private String userName;
@Value("${xlog.elasticsearch.pwd:Axz0ES2021}")
@Value("${log-plat.elasticsearch.pwd:Axz0ES2021}")
private String password;
@Bean

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.server.config;
package cn.axzo.log.platform.server.config;
import cn.axzo.pudge.core.service.ServiceException;
import cn.azxo.framework.common.constatns.Constants;
@ -30,7 +30,7 @@ import java.util.regex.Pattern;
* @author xiajiafu
* @date 2022/08/08
**/
@Configuration(value = "xlogFeignConfig")
@Configuration(value = "logPlatFeignConfig")
public class FeignConfig implements RequestInterceptor {
private static final Logger log = LoggerFactory.getLogger(FeignConfig.class);

View File

@ -1,6 +1,6 @@
package cn.axzo.xlog.server.config;
package cn.axzo.log.platform.server.config;
import cn.axzo.xlog.server.entity.BaseEntity;
import cn.axzo.log.platform.server.entity.BaseEntity;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.server.config;
package cn.axzo.log.platform.server.config;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;

View File

@ -1,13 +1,13 @@
package cn.axzo.xlog.server.consumer;
package cn.axzo.log.platform.server.consumer;
import cn.axzo.xlog.server.config.RabbitMqConfig;
import cn.axzo.xlog.server.dto.OperateLogReqDTO;
import cn.axzo.xlog.server.service.OperateLogService;
import cn.axzo.log.platform.server.dto.OperateLogReqDTO;
import cn.axzo.log.platform.server.service.OperateLogService;
import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@ -27,7 +27,7 @@ public class OperateLogMqConsumer {
@Resource
private OperateLogService operateLogService;
@RabbitListener(queues = RabbitMqConfig.OPERATE_LOG_QUEUE_NAME)
@RabbitListener(queuesToDeclare = @Queue("${log-plat.oprlog.queue.name:log-plat.oprlog.queue}"))
public void consumerOprlogs(Message message, Channel channel) throws IOException {
String msg = new String(message.getBody(), StandardCharsets.UTF_8);
try {

View File

@ -0,0 +1,22 @@
package cn.axzo.log.platform.server.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/***
* @author: pepsi
* @description: TODO
* @date: 2022/9/21
*/
@RestController
public class HealthCheckController {
/**
* 探活
*
* @return 字符串
*/
@GetMapping("/checkDeath")
public String checkDeath() {
return "alive";
}
}

View File

@ -0,0 +1,87 @@
package cn.axzo.log.platform.server.controller.api;
import cn.axzo.log.platform.server.dto.*;
import cn.axzo.log.platform.server.service.OperateLogService;
import cn.azxo.framework.common.model.CommonPageResponse;
import cn.azxo.framework.common.model.CommonResponse;
import cn.hutool.core.date.DateUtil;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
/***
* @author: pepsi
* @description: TODO
* @date: 2022/9/16
*/
@Api(tags = "web-操作日志接口")
@ApiSupport(author = "田立勇")
@RestController
@RequestMapping("/api/v1")
public class OperateLogController {
private final Logger logger = LoggerFactory.getLogger(OperateLogController.class);
@Resource
private OperateLogService operateLogService;
@RequestMapping(value = "/operateLog/create", method = RequestMethod.POST)
@ApiOperation(value = "操作日志创建")
public CommonResponse<Boolean> operateLogCreate(@RequestBody @Valid OperateLogReqDTO req,
BindingResult bindingResult) {
//参数缺失等返回
if (bindingResult.hasErrors()) {
return CommonResponse.fail(bindingResult.getAllErrors().get(0).getDefaultMessage());
}
try {
return CommonResponse.success(operateLogService.insertOperaLog(req));
} catch (Exception e) {
logger.error("create operate log failed.", e);
return CommonResponse.fail(e.getMessage());
}
}
@RequestMapping(value = "/operateLog/queryForPage", method = RequestMethod.POST)
@ApiOperation(value = "操作日志分页查询")
public CommonResponse<CommonPageResponse<OperateLogQueryRespDTO>> operateLogsQuery(@RequestBody @Valid OperateLogQueryReqDTO req,
BindingResult bindingResult) {
//参数缺失等返回
if (bindingResult.hasErrors()) {
return CommonResponse.fail(bindingResult.getAllErrors().get(0).getDefaultMessage());
}
//时间跨度校验
if (DateUtil.betweenDay(req.getStartTime(), req.getEndTime(), true) > 7) {
logger.error("start and end date interval greater than 7.");
return CommonResponse.fail("the time span is greater than 7");
}
try {
CommonPageResponse<OperateLogQueryRespDTO> resp = operateLogService.queryForPage(req);
return CommonResponse.success(resp);
} catch (Exception e) {
logger.error("query operate logs failed,", e);
return CommonResponse.fail(e.getMessage());
}
}
@RequestMapping(value = "/operateLog/queryDetail", method = RequestMethod.POST)
@ApiOperation(value = "操作日志详情查询")
public CommonResponse<OperateLogQueryDetailRespDTO> operateLogDetail(@RequestBody OperateLogQueryDetailReqDTO reqDTO) {
try {
OperateLogQueryDetailRespDTO detail = operateLogService.queryOperateLogDetail(reqDTO);
return CommonResponse.success(detail);
} catch (Exception e) {
return CommonResponse.fail(e.getMessage());
}
}
}

View File

@ -0,0 +1,34 @@
package cn.axzo.log.platform.server.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* @author : liuchuntao
* @date : 2022/6/28 20:08
* @description : 操作日志请求参数
*/
@Data
public class OperateLogQueryDetailReqDTO {
/**
* ID
*/
@ApiModelProperty(value = "记录ID", position = 1, required = true)
private String id;
/**
* 操作时间
*/
@ApiModelProperty(value = "操作时间", position = 2)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@NotNull
private Date operateTime;
}

View File

@ -0,0 +1,119 @@
package cn.axzo.log.platform.server.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/***
* @author: pepsi
* @description: 操作日志详情返回
* @date: 2022/10/8
*/
@Data
public class OperateLogQueryDetailRespDTO {
/**
* 操作人
*/
@ApiModelProperty(value = "操作人名称", position = 1)
private String operateUserName;
/**
* 事件类型
*/
@ApiModelProperty(value = "事件code", position = 2)
private String featureCode;
/**
* 事件类型
*/
@ApiModelProperty(value = "事件名称", position = 3)
private String featureName;
/**
* 事件摘要
*/
@ApiModelProperty(value = "事件摘要", position = 4)
private String contentSummary;
/**
* 操作时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@ApiModelProperty(value = "操作时间", position = 5)
private Date operateTime;
/**
* 操作人手机号
*/
@ApiModelProperty(value = "操作人手机号", position = 6)
private String operateUserPhone;
/**
* 所属单位名称
*/
@ApiModelProperty(value = "单位名称", position = 7)
private String ouName;
/**
* 操作人IP
*/
@ApiModelProperty(value = "操作人IP", position = 8)
private String operateUserIp;
/**
* 操作那张表
*/
@ApiModelProperty(value = "操作的表名称", position = 9)
private String operateTable;
/**
* 操作前内容
*/
@ApiModelProperty(value = "操作前信息", position = 10)
private String operateBefore;
/**
* 操作后内容
*/
@ApiModelProperty(value = "操作后信息", position = 11)
private String operateAfter;
/**
* 操作参数
*/
@ApiModelProperty(value = "操作的参数信息", position = 12)
private String operateParam;
/**
* 日志拓展内容
*/
@ApiModelProperty(value = "扩展信息", position = 13)
private String logExt;
/**
* 工作台
*/
@ApiModelProperty(value = "工作台名字", position = 14)
private String workspaceName;
/**
* 操作人名字
*/
@ApiModelProperty(value = "操作人名称", position = 15)
private String identityUserName;
/**
* 操作人手机号
*/
@ApiModelProperty(value = "操作人电话", position = 16)
private String identityUserPhone;
/**
* 所属终端
*/
@ApiModelProperty(value = "所属终端", position = 17)
private String terminal;
}

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.server.dto;
package cn.axzo.log.platform.server.dto;
import cn.axzo.basics.common.page.PageRequest;
@ -7,6 +7,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;
@ -27,72 +28,74 @@ public class OperateLogQueryReqDTO extends PageRequest {
/**
* 操作人
*/
@ApiModelProperty(value = "操作人", position = 1)
@ApiModelProperty(value = "操作人", position = 2)
private String operateUserName;
/**
* 事件类型
*/
@ApiModelProperty(value = "事件类型", position = 1)
@ApiModelProperty(value = "事件类型", position = 3)
private List<String> featureCodes;
/**
* 功能name
*/
@ApiModelProperty(value = "功能名称", position = 1)
@ApiModelProperty(value = "功能名称", position = 4)
private String featureName;
/**
* 开始时间
*/
@ApiModelProperty(value = "开始时间", position = 1)
@ApiModelProperty(value = "操作开始时间", position = 5, required = true, example = "2022-10-10 12:12:12")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@NotNull
private Date startTime;
/**
* 结束时间
*/
@ApiModelProperty(value = "结束时间", position = 1)
@ApiModelProperty(value = "操作结束时间", position = 6, required = true, example = "2022-10-10 12:12:12")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@NotNull
private Date endTime;
/**
* 工作台Id
*/
@ApiModelProperty(value = "工作台Id", position = 1)
@ApiModelProperty(value = "工作台Id", position = 7)
@JsonIgnore
private Long workspaceId;
/**
* 单位Id
*/
@ApiModelProperty(value = "单位Id", position = 1)
@ApiModelProperty(value = "单位Id", position = 8)
@JsonIgnore
private Long ouId;
/**
* 身份Id
*/
@ApiModelProperty(value = "身份Id", position = 1)
@ApiModelProperty(value = "身份Id", position = 9)
@JsonIgnore
private Long identityId;
/**
* 身份类型
*/
@ApiModelProperty(value = "身份类型", position = 1)
@ApiModelProperty(value = "身份类型", position = 10)
@JsonIgnore
private Integer identityType;
/**
* 操作类型 1:add 2:add_batch 3:update 4:update_batch 5:delete 6:delete_batch
*/
@ApiModelProperty(value = "操作类型", position = 1)
@ApiModelProperty(value = "操作类型", position = 11)
private Integer operateType;
/**
* 操作表名
*/
@ApiModelProperty(value = "操作表名", position = 1)
@ApiModelProperty(value = "操作表名", position = 12)
private String operateTable;
}

View File

@ -1,6 +1,7 @@
package cn.axzo.xlog.server.dto;
package cn.axzo.log.platform.server.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@ -13,39 +14,52 @@ import java.util.Date;
@Data
public class OperateLogQueryRespDTO {
/**
* 记录ID,为后面单条详情查询提供
*/
@ApiModelProperty(value = "ID", position = 0)
private String id;
/**
* 操作人
*/
@ApiModelProperty(value = "操作人名称", position = 1)
private String operateUserName;
/**
* 事件类型
*/
@ApiModelProperty(value = "事件code", position = 2)
private String featureCode;
/**
* 事件类型
*/
@ApiModelProperty(value = "事件名称", position = 3)
private String featureName;
/**
* 事件摘要
*/
@ApiModelProperty(value = "事件摘要", position = 4)
private String contentSummary;
/**
* 操作时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@ApiModelProperty(value = "操作时间", position = 5)
private Date operateTime;
/**
* 操作人手机号
*/
@ApiModelProperty(value = "操作人手机号", position = 6)
private String operateUserPhone;
/**
* 所属单位名称
*/
@ApiModelProperty(value = "单位名称", position = 7)
private String ouName;
}

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.server.dto;
package cn.axzo.log.platform.server.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
@ -41,30 +41,30 @@ public class OperateLogReqDTO {
private String featureName;
/**
* 日志等级 为空默认P4 请参照 {@link cn.axzo.xlog.client.enums.LogGradeEnum}
* 日志等级 为空默认P0:0, P1:1, P2:2, P3:3, P4:4
*/
@ApiModelProperty(value = "日志登记", position = 4)
@ApiModelProperty(value = "日志等级", position = 4)
private Integer logGrade = 4;
/**
* 操作时间
*/
@ApiModelProperty(value = "操作时间", position = 5, required = true)
@ApiModelProperty(value = "操作时间", required = true, position = 5, example = "2022-10-10 12:12:12")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@NotNull(message = "操作时间不能为空")
private Date operateTime;
/**
* 操作人安心筑Id
*/
@ApiModelProperty(value = "操作人ID", position = 6)
@ApiModelProperty(value = "操作人ID", required = true, position = 6)
@NotNull(message = "操作人Id不能为空")
private Long identityId;
/**
* 人员类型 1:工人 2:班组长 3:从业人员..实际情况拓展
* 请参照 {@link cn.axzo.xlog.client.enums.IdentityType}
* 人员类型 1:工人 2:班组长 3:从业人员..实际情况拓展}
*/
@ApiModelProperty(value = "身份类型", position = 7)
@ApiModelProperty(value = "身份类型", required = true, position = 7)
@NotNull(message = "人员类型身份不能为空")
private Integer identityType;
/**
@ -135,7 +135,7 @@ public class OperateLogReqDTO {
/**
* 操作类型 1:add 2:add_batch 3:update 4:update_batch 5:delete 6:delete_batch
*/
@ApiModelProperty(value = "操作类型", position = 19)
@ApiModelProperty(value = "操作类型", required = true, position = 19)
@NotNull(message = "操作类型不能为空")
private Integer operateType;

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.server.entity;
package cn.axzo.log.platform.server.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.server.entity;
package cn.axzo.log.platform.server.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.EqualsAndHashCode;
@ -18,7 +18,7 @@ import java.util.Date;
@Setter
@ToString
@EqualsAndHashCode(callSuper = true)
@TableName("unified_log_record")
@TableName("log_record")
public class OperateLogRecordEntity extends BaseEntity<OperateLogRecordEntity> {
/**
* 调用方服务名

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.server.enums;
package cn.axzo.log.platform.server.enums;
/**
* 项目名称pudge

View File

@ -1,6 +1,6 @@
package cn.axzo.xlog.server.enums;
package cn.axzo.log.platform.server.enums;
import cn.axzo.xlog.server.exception.ServiceException;
import cn.axzo.log.platform.server.exception.ServiceException;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.server.enums;
package cn.axzo.log.platform.server.enums;
import lombok.Getter;

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.server.exception;
package cn.axzo.log.platform.server.exception;
/**
* @author Smile

View File

@ -1,6 +1,6 @@
package cn.axzo.xlog.server.mapper;
package cn.axzo.log.platform.server.mapper;
import cn.axzo.xlog.server.entity.OperateLogRecordEntity;
import cn.axzo.log.platform.server.entity.OperateLogRecordEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;

View File

@ -0,0 +1,35 @@
package cn.axzo.log.platform.server.repository;
import cn.axzo.log.platform.server.dto.OperateLogQueryReqDTO;
import cn.axzo.log.platform.server.entity.OperateLogRecordEntity;
import com.baomidou.mybatisplus.core.metadata.IPage;
/***
* @author: pepsi
* @description: TODO
* @date: 2022/9/15
*/
public interface OperateLogRepository {
/**
* @param user
* @return
*/
OperateLogRecordEntity save(OperateLogRecordEntity user);
/**
* 分页查询
*
* @param req
* @return
*/
IPage<OperateLogRecordEntity> pageLogRecord(OperateLogQueryReqDTO req);
/**
* 根据ID获取
*
* @param id
* @return
*/
OperateLogRecordEntity queryById(Long id);
}

View File

@ -1,9 +1,9 @@
package cn.axzo.xlog.server.repository.impl;
package cn.axzo.log.platform.server.repository.impl;
import cn.axzo.xlog.server.dto.OperateLogQueryReqDTO;
import cn.axzo.xlog.server.entity.OperateLogRecordEntity;
import cn.axzo.xlog.server.mapper.OperateLogMapper;
import cn.axzo.xlog.server.repository.OperateLogRepository;
import cn.axzo.log.platform.server.dto.OperateLogQueryReqDTO;
import cn.axzo.log.platform.server.entity.OperateLogRecordEntity;
import cn.axzo.log.platform.server.mapper.OperateLogMapper;
import cn.axzo.log.platform.server.repository.OperateLogRepository;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
@ -45,4 +45,9 @@ public class OperateLogRepositoryImpl implements OperateLogRepository {
.orderByDesc(OperateLogRecordEntity::getCreateAt)
);
}
@Override
public OperateLogRecordEntity queryById(Long id) {
return mapper.selectById(id);
}
}

View File

@ -1,8 +1,13 @@
package cn.axzo.xlog.server.service;
package cn.axzo.log.platform.server.service;
import cn.axzo.xlog.server.config.SpringContextAware;
import cn.axzo.log.platform.server.config.SpringContextAware;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
@ -16,7 +21,10 @@ import org.elasticsearch.rest.RestStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
/***
* @author: pepsi
@ -27,13 +35,55 @@ public class BaseEsService {
private final Logger logger = LoggerFactory.getLogger(BaseEsService.class);
/**
* 索引缓存, 索引数量不大新增频率不高等可以做成内存缓存
*/
private LoadingCache<String, List<String>> INDICES_CACHE = CacheBuilder.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(new CacheLoader<String, List<String>>() {
@Override
public List<String> load(String key) throws Exception {
return loadIndices(key);
}
});
public List<String> getIndices(String indexName) {
try {
return INDICES_CACHE.get(indexName);
} catch (Exception e) {
logger.error("get indices from cache exception,indexName=" + indexName, e);
return null;
}
}
/***
* 根据索引前置获取到索引列表,并排序
* @param key
* @return
*/
private List<String> loadIndices(String key) {
ArrayList<String> lists = new ArrayList<String>();
try {
String[] indices = queryIndices(key + "*");
if (indices.length == 0) {
return lists;
}
lists.addAll(Arrays.asList(indices));
return lists;
} catch (Exception e) {
logger.error("load indices exception", e);
return null;
}
}
/**
* 获取索引
*
* @param wildcardIndex
* @return
*/
public String[] getIndices(String wildcardIndex) throws Exception {
public String[] queryIndices(String wildcardIndex) throws Exception {
GetIndexRequest request = new GetIndexRequest(wildcardIndex);
try {
RestHighLevelClient client = SpringContextAware.getBean(RestHighLevelClient.class);
@ -89,7 +139,7 @@ public class BaseEsService {
}
return true;
} catch (Exception e) {
logger.error("bulk insert failed,", e);
logger.error("es bulk insert failed,", e);
throw new Exception(e.getMessage());
}
}
@ -107,8 +157,25 @@ public class BaseEsService {
RestHighLevelClient client = SpringContextAware.getBean(RestHighLevelClient.class);
return client.search(request, RequestOptions.DEFAULT);
} catch (Exception e) {
logger.error("query failed,", e);
throw new Exception("");
logger.error("es search query occur exception,", e);
throw new Exception(e.getMessage());
}
}
/**
* get 方式获取
*
* @param request
* @return
* @throws Exception
*/
public GetResponse get(GetRequest request) throws Exception {
try {
RestHighLevelClient client = SpringContextAware.getBean(RestHighLevelClient.class);
return client.get(request, RequestOptions.DEFAULT);
} catch (Exception e) {
logger.error("es get query occur exception,", e);
throw new Exception(e.getMessage());
}
}
}

View File

@ -1,9 +1,6 @@
package cn.axzo.xlog.server.service;
package cn.axzo.log.platform.server.service;
import cn.axzo.xlog.server.dto.OperateLogQueryReqDTO;
import cn.axzo.xlog.server.dto.OperateLogQueryRespDTO;
import cn.axzo.xlog.server.dto.OperateLogReqDTO;
import cn.axzo.xlog.server.entity.OperateLogRecordEntity;
import cn.axzo.log.platform.server.dto.*;
import cn.azxo.framework.common.model.CommonPageResponse;
/***
@ -25,7 +22,7 @@ public interface OperateLogService {
* @param req
* @return
*/
CommonPageResponse<OperateLogQueryRespDTO> queryForPage(OperateLogQueryReqDTO req);
CommonPageResponse<OperateLogQueryRespDTO> queryForPage(OperateLogQueryReqDTO req) throws Exception;
/**
* query from es
@ -35,4 +32,12 @@ public interface OperateLogService {
* @throws Exception
*/
CommonPageResponse<OperateLogQueryRespDTO> queryForPageFromEs(OperateLogQueryReqDTO req) throws Exception;
/**
* 查询每个日志的详情
*
* @param req
* @return
*/
OperateLogQueryDetailRespDTO queryOperateLogDetail(OperateLogQueryDetailReqDTO req) throws Exception;
}

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.server.service.converter;
package cn.axzo.log.platform.server.service.converter;
import java.util.List;

View File

@ -1,7 +1,8 @@
package cn.axzo.xlog.server.service.converter;
package cn.axzo.log.platform.server.service.converter;
import cn.axzo.xlog.server.dto.OperateLogReqDTO;
import cn.axzo.xlog.server.entity.OperateLogRecordEntity;
import cn.axzo.log.platform.server.dto.OperateLogQueryDetailRespDTO;
import cn.axzo.log.platform.server.dto.OperateLogReqDTO;
import cn.axzo.log.platform.server.entity.OperateLogRecordEntity;
import org.mapstruct.Mapper;
import static org.mapstruct.NullValueCheckStrategy.ALWAYS;
@ -18,4 +19,7 @@ import static org.mapstruct.NullValueCheckStrategy.ALWAYS;
public interface OperateLogConverter {
OperateLogRecordEntity toEntity(OperateLogReqDTO dto);
OperateLogQueryDetailRespDTO toDetailDto(OperateLogRecordEntity entity);
}

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.server.service.impl;
package cn.axzo.log.platform.server.service.impl;
import cn.axzo.apollo.core.web.Result;
import cn.axzo.apollo.workspace.api.workspace.WorkspaceApi;
@ -8,21 +8,22 @@ import cn.axzo.basics.organizational.api.OrganizationalUnitApi;
import cn.axzo.basics.organizational.api.vo.response.OrganizationalUnitVO;
import cn.axzo.basics.profiles.api.UserProfileServiceApi;
import cn.axzo.basics.profiles.dto.basic.IdentityProfileDto;
import cn.axzo.log.platform.server.dto.*;
import cn.axzo.log.platform.server.entity.OperateLogRecordEntity;
import cn.axzo.log.platform.server.repository.OperateLogRepository;
import cn.axzo.log.platform.server.service.BaseEsService;
import cn.axzo.log.platform.server.service.OperateLogService;
import cn.axzo.log.platform.server.service.converter.OperateLogConverter;
import cn.axzo.pudge.core.service.ServiceException;
import cn.axzo.xlog.server.dto.OperateLogQueryReqDTO;
import cn.axzo.xlog.server.dto.OperateLogQueryRespDTO;
import cn.axzo.xlog.server.dto.OperateLogReqDTO;
import cn.axzo.xlog.server.entity.OperateLogRecordEntity;
import cn.axzo.xlog.server.enums.IdentityType;
import cn.axzo.xlog.server.repository.OperateLogRepository;
import cn.axzo.xlog.server.service.BaseEsService;
import cn.axzo.xlog.server.service.OperateLogService;
import cn.axzo.xlog.server.service.converter.OperateLogConverter;
import cn.azxo.framework.common.model.CommonPageResponse;
import cn.azxo.framework.common.model.CommonResponse;
import cn.hutool.core.date.CalendarUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.*;
@ -37,8 +38,7 @@ import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
/***
* @author: pepsi
@ -50,12 +50,21 @@ public class OperateLogServiceImpl extends BaseEsService implements OperateLogSe
private final Logger logger = LoggerFactory.getLogger(OperateLogServiceImpl.class);
@Value("${xlog.elastic.index.name:xlog_operatelog_}")
/**
* 索引前置名称,看后续是否要修改
*/
@Value("${xlog.elastic.index.name:axzo_operatelog_}")
private String indexNamePrex;
@Value("${xlog.es.storage:true}")
@Value("${xlog.es.storage:false}")
private boolean esStorageFlag;
@Value("${oprlog.index.interval.days:7}")
private int intervalDays;
@Value("${oprlog.index.interval.mills:604800000}")
private long intervalMills;
@Resource
private OperateLogRepository operateLogRepository;
@ -80,17 +89,29 @@ public class OperateLogServiceImpl extends BaseEsService implements OperateLogSe
operateLogRepository.save(record);
return true;
}
//todo ES,根据日期决定索引,目前索引规则还没定,暂定一个月一个
String indexDate = DateUtil.format(operateLogReq.getOperateTime(), "YYYYMM");
//目前决定根据operateTime时间定,7天 (一般查询限制时间都是7天或者30天) 数据落一个索引中
// 目前查看pre_new环境数据很少上线前再查看一波线上数据决定索引生成的时间跨度,再做调整
String indexSuffixDate = findIndexSuffixDate(operateLogReq.getOperateTime());
String json = JSONObject.toJSONString(operateLogReq);
return insert(json, indexNamePrex + indexDate);
return insert(json, indexNamePrex + indexSuffixDate);
}
/***
* 根据数据中的日期信息找到所属的索引
* 目前是按7天的规则
* @param date
* @return
*/
private String findIndexSuffixDate(Date date) {
long mills = date.getTime();
long weekMills = mills % intervalMills;
Date currDate = new Date(mills - weekMills);
return DateUtil.format(currDate, DatePattern.PURE_DATE_PATTERN);
}
private OperateLogRecordEntity fieldFill(OperateLogReqDTO req) {
//补充 termimnal identityType featureName
//补充 termimnal identityType featureName.
OperateLogRecordEntity unifiedLogRecord = operateLogConverter.toEntity(req);
// 通过接口调用获取用户手机姓名
IdentityProfileDto identityProfile = qryIdentityProfile(req.getIdentityId(), req.getIdentityType());
if (identityProfile != null && identityProfile.getPersonProfile() != null) {
@ -106,8 +127,11 @@ public class OperateLogServiceImpl extends BaseEsService implements OperateLogSe
}
@Override
public CommonPageResponse<OperateLogQueryRespDTO> queryForPage(OperateLogQueryReqDTO req) {
//todo entity 对象
public CommonPageResponse<OperateLogQueryRespDTO> queryForPage(OperateLogQueryReqDTO req) throws Exception {
//这里做个区分时从ES查询获取还是从DB获取.
if (esStorageFlag) {
return queryForPageFromEs(req);
}
IPage<OperateLogRecordEntity> page = operateLogRepository.pageLogRecord(req);
//为空则返回空
List<OperateLogRecordEntity> recordList = page.getRecords();
@ -118,34 +142,98 @@ public class OperateLogServiceImpl extends BaseEsService implements OperateLogSe
return CommonPageResponse.list(req.getPage(), req.getPageSize(), page.getTotal(), respList);
}
/***
* 从ES获取查询结果
* @param req
* @return
*/
public CommonPageResponse<OperateLogQueryRespDTO> queryForPageFromEs(OperateLogQueryReqDTO req) throws Exception {
//todo 根据时间段获取数据所在的索引s,目前索引规则还没定
String[] indices = new String[]{"xlog_operatelog_202209"};
//根据查询的时间段获取所属的索引集合
Set<String> indices = betweenIndices(req.getStartTime(), req.getEndTime());
if (indices.isEmpty()) {
logger.warn("can not find index,startDate={}.", DateUtil.format(req.getStartTime(), DatePattern.PURE_DATE_PATTERN));
return CommonPageResponse.zero(req.getPage(), req.getPageSize());
}
//组装查询条件.
SearchSourceBuilder builder = assembleQueryBuilder(req);
SearchRequest request = new SearchRequest();
request.source(builder);
SearchResponse response = search(request, indices);
SearchResponse response = search(request, indices.toArray(new String[]{}));
//处理查询结果的数据
SearchHits hits = response.getHits();
SearchHit[] searchHits = hits.getHits();
List<OperateLogRecordEntity> resList = new ArrayList<>(searchHits.length);
Map<String, OperateLogRecordEntity> resMap = new HashMap<>(searchHits.length);
if (searchHits.length == 0) {
return CommonPageResponse.zero(req.getPage(), req.getPageSize());
}
for (SearchHit hit : searchHits) {
String oprLogStr = hit.getSourceAsString();
resList.add(JSONObject.parseObject(oprLogStr, OperateLogRecordEntity.class));
resMap.put(hit.getId(), JSONObject.parseObject(oprLogStr, OperateLogRecordEntity.class));
}
List<OperateLogQueryRespDTO> respList = assembleOperateLogResp(resList);
List<OperateLogQueryRespDTO> respList = assembleOperateLogResp(resMap);
return CommonPageResponse.list(req.getPage(), req.getPageSize(), hits.getTotalHits().value, respList);
}
@Override
public OperateLogQueryDetailRespDTO queryOperateLogDetail(OperateLogQueryDetailReqDTO req) throws Exception {
if (esStorageFlag) {
return queryOperateLogDetailFromEs(req.getOperateTime(), req.getId());
}
//从DB查询
OperateLogRecordEntity entity = operateLogRepository.queryById(Long.valueOf(req.getId()));
if (entity == null) {
return null;
}
return operateLogConverter.toDetailDto(entity);
}
/**
* 对于 es 而言需要索引信息.
*
* @param id
* @return
*/
public OperateLogQueryDetailRespDTO queryOperateLogDetailFromEs(Date oprDateTime, String id) throws Exception {
//根据日期找索引,
String indexName = indexNamePrex + findIndexSuffixDate(oprDateTime);
//需要判断下索引是否存在,
List<String> indices = getIndices(indexNamePrex);
if (!indices.contains(indexName)) {
logger.warn("can not find index,oprDateTime={},id={}", oprDateTime, id);
return null;
}
GetRequest getRequest = new GetRequest(indexName, id);
GetResponse response = get(getRequest);
String oprLogStr = response.getSourceAsString();
OperateLogRecordEntity entity = JSONObject.parseObject(oprLogStr, OperateLogRecordEntity.class);
return operateLogConverter.toDetailDto(entity);
}
/***
* 获取2个时间段之间的索引startTime + 7 < endTime 即可
* @param startDate
* @param endDate
* @return
*/
private Set<String> betweenIndices(Date startDate, Date endDate) {
Set<String> betweenIndices = new HashSet<>();
long startMills = startDate.getTime();
long startIntervalMills = startMills % intervalMills;
Date startWeekDate = new Date(startMills - startIntervalMills);
while (startWeekDate.before(endDate)) {
String index = indexNamePrex + DateUtil.format(startWeekDate, DatePattern.PURE_DATE_PATTERN);
betweenIndices.add(index);
Calendar calendar = CalendarUtil.calendar(startWeekDate);
calendar.add(Calendar.DAY_OF_MONTH, intervalDays);
startWeekDate = calendar.getTime();
}
//需要判断下索引是否存在,
List<String> indices = getIndices(indexNamePrex);
betweenIndices.removeIf(index -> !indices.contains(index));
return betweenIndices;
}
/***
* 组装ES查询条件
* @param req
@ -192,17 +280,18 @@ public class OperateLogServiceImpl extends BaseEsService implements OperateLogSe
.lte(req.getEndTime().getTime());
boolQueryBuilder.filter(rangeQueryBuilder);
searchSourceBuilder.sort("operateTime", SortOrder.DESC);
//todo 分页,先采用 from +size 模式后续优化考虑scroll或者 after.
int offset = (req.getPage().intValue() - 1) * req.getPageSize().intValue();
searchSourceBuilder.from(offset).size(req.getPageSize().intValue());
//采用 from +size条件限制多一点不做深查询了因为scroll 快照数据不准确问题
int page = req.getPage() == null ? 1 : req.getPage().intValue();
int size = req.getPageSize() == null ? 20 : req.getPageSize().intValue();
searchSourceBuilder.from((page - 1) * size).size(size);
searchSourceBuilder.query(boolQueryBuilder);
return searchSourceBuilder;
}
private List<OperateLogQueryRespDTO> assembleOperateLogResp(List<OperateLogRecordEntity> recordList) {
private List<OperateLogQueryRespDTO> assembleOperateLogResp(Map<String, OperateLogRecordEntity> recordMap) {
List<OperateLogQueryRespDTO> resList = new ArrayList<>();
recordList.forEach(item -> {
recordMap.forEach((id, item) -> {
OperateLogQueryRespDTO resp = new OperateLogQueryRespDTO();
resp.setOperateUserName(item.getIdentityUserName());
resp.setFeatureCode(item.getFeatureCode());
@ -211,11 +300,28 @@ public class OperateLogServiceImpl extends BaseEsService implements OperateLogSe
resp.setOperateTime(item.getOperateTime());
resp.setOperateUserPhone(item.getIdentityUserPhone());
resp.setOuName(item.getOuName());
resp.setId(id);
resList.add(resp);
});
return resList;
}
private List<OperateLogQueryRespDTO> assembleOperateLogResp(List<OperateLogRecordEntity> recordList) {
List<OperateLogQueryRespDTO> resList = new ArrayList<>();
recordList.forEach((ele) -> {
OperateLogQueryRespDTO response = new OperateLogQueryRespDTO();
response.setOperateUserName(ele.getIdentityUserName());
response.setFeatureCode(ele.getFeatureCode());
response.setFeatureName(ele.getFeatureName());
response.setContentSummary(ele.getContentSummary());
response.setOperateTime(ele.getOperateTime());
response.setOperateUserPhone(ele.getIdentityUserPhone());
response.setOuName(ele.getOuName());
response.setId(ele.getId().toString());
resList.add(response);
});
return resList;
}
/***
* workspaceId 查询 WS 信息
@ -227,6 +333,7 @@ public class OperateLogServiceImpl extends BaseEsService implements OperateLogSe
getDetailReq.setId(workspaceId);
Result<GetDetailRes> res = workspaceApi.getDetail(getDetailReq);
if (res.getCode() != 200) {
logger.error("query workspace with wsId failed,wsId={},errMsg={}.", workspaceId, res.getMsg());
throw new ServiceException(res.getMsg());
}
return res.getData();

View File

@ -1,15 +1,15 @@
spring:
application:
name: xlog
name: axzo-log-plat
cloud:
nacos:
config:
server-addr: ${NACOS_HOST:test1-nacos.axzo.cn}:${NACOS_PORT:80}
server-addr: ${NACOS_HOST:dev-nacos.axzo.cn}:${NACOS_PORT:80}
file-extension: yaml
namespace: ${NACOS_NAMESPACE_ID:6b278234-1409-4054-beb7-4bbc0def8e54}
namespace: ${NACOS_NAMESPACE_ID:35eada10-9574-4db8-9fea-bc6a4960b6c7}
prefix: ${spring.application.name}
profiles:
active: ${NACOS_PROFILES_ACTIVE:test1}
active: ${NACOS_PROFILES_ACTIVE:dev}
main:
allow-bean-definition-overriding: true
datasource:

View File

@ -1,4 +1,4 @@
package cn.axzo.xlog.server;
package cn.axzo.log.platform.server;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;

View File

@ -0,0 +1,118 @@
package cn.axzo.log.platform.server.config;
import cn.axzo.log.platform.server.entity.OperateLogRecordEntity;
import cn.axzo.log.platform.server.service.BaseEsService;
import cn.hutool.core.date.CalendarUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import org.elasticsearch.client.RestHighLevelClient;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/***
* @author: pepsi
* @description: TODO
* @date: 2022/9/19
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class ElasticClientConfigTest extends BaseEsService {
@Autowired
private RestHighLevelClient client;
private long sevenDayMills = 7 * 24 * 60 * 60 * 1000;
@Test
public void testInsert() throws Exception {
OperateLogRecordEntity entity = new OperateLogRecordEntity();
entity.setLogGrade(1);
entity.setLogExt("test");
entity.setIdentityId(15L);
entity.setOperateAfter("test");
entity.setOperateParam("test");
entity.setFeatureCode("test");
entity.setOperateTable("test");
entity.setOperateType(1);
entity.setContentSummary("test");
entity.setOperateTime(new Date());
entity.setServiceName("test");
entity.setOuId(1L);
entity.setOperateUserIp("test");
entity.setWorkspaceId(1L);
entity.setResourceType(1);
entity.setIdentityType(3);
entity.setTerminal("test");
entity.setOperateBefore("test");
entity.setFeatureName("test");
entity.setResourceId(1L);
String data = JSONObject.toJSONString(entity);
String index = "xlog_operatelog_202209";
List<String> list = new ArrayList<>();
list.add(data);
boolean flag = this.bulkInsert(list, index);
Assert.assertTrue(flag);
}
@Test
public void testIndexInterval() {
long sevenDayMills = 7 * 24 * 60 * 60 * 1000;
Date now = new Date();
String weekDate = interval(now);
System.out.println("now:" + weekDate);
String weekDateThreeDaysAgo = interval(add(now, -3));
System.out.println("ThreeDaysAgo:" + weekDateThreeDaysAgo);
String weekDateTwoDaysAgo = interval(add(now, -2));
System.out.println("now:" + weekDateTwoDaysAgo);
String weekDateAfter1 = interval(add(now, 1));
System.out.println("After1:" + weekDateAfter1);
String weekDateAfter2 = interval(add(now, 2));
System.out.println("After2:" + weekDateAfter2);
String weekDateAfter3 = interval(add(now, 3));
System.out.println("After3:" + weekDateAfter3);
String weekDateAfter4 = interval(add(now, 4));
System.out.println("After4:" + weekDateAfter4);
String weekDateAfter5 = interval(add(now, 5));
System.out.println("After5:" + weekDateAfter5);
String weekDateAfter6 = interval(add(now, 6));
System.out.println("After6:" + weekDateAfter6);
String weekDateAfter7 = interval(add(now, 7));
System.out.println("After7:" + weekDateAfter7);
String weekDateAfter8 = interval(add(now, 8));
System.out.println("After8:" + weekDateAfter8);
}
private Date add(Date date, int interval) {
Calendar calendar = CalendarUtil.calendar(date);
calendar.add(Calendar.DAY_OF_MONTH, interval);
return calendar.getTime();
}
private String interval(Date date) {
long mills = date.getTime();
long intervalMills = mills % sevenDayMills;
Date currDate = new Date(mills - intervalMills);
return DateUtil.format(currDate, DatePattern.PURE_DATE_PATTERN);
}
}

View File

@ -1,6 +1,6 @@
package cn.axzo.xlog.server.config;
package cn.axzo.log.platform.server.config;
import cn.axzo.xlog.server.XlogApplicationTestBase;
import cn.axzo.log.platform.server.XlogApplicationTestBase;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;

View File

@ -1,7 +1,7 @@
package cn.axzo.xlog.server.config;
package cn.axzo.log.platform.server.config;
import cn.axzo.xlog.server.XlogApplicationTestBase;
import cn.axzo.xlog.server.dto.OperateLogReqDTO;
import cn.axzo.log.platform.server.XlogApplicationTestBase;
import cn.axzo.log.platform.server.dto.OperateLogReqDTO;
import com.alibaba.fastjson.JSONObject;
import org.junit.Test;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
@ -16,12 +16,15 @@ import java.util.Date;
*/
public class RabbitMqConsumerTest extends XlogApplicationTestBase {
public static final String OPERATE_LOG_QUEUE_NAME = "log-plat.oprlog.queue";
public static final String OPERATE_LOG_EXCHANGE = "log-plat.oprlog.test.exchange";
public static final String OPERATE_LOG_ROUTING_KEY = "log-plat.oprlog.test.routingKey";
@Resource
private RabbitTemplate rabbitTemplate;
@Test
public void testSendMsg() throws InterruptedException {
for (int i = 0; i < 10; i++) {
for (int i = 0; i < 1; i++) {
OperateLogReqDTO reqData = new OperateLogReqDTO();
reqData.setLogGrade(1);
reqData.setLogExt("test");
@ -43,7 +46,7 @@ public class RabbitMqConsumerTest extends XlogApplicationTestBase {
reqData.setOperateBefore("test");
reqData.setFeatureName("test");
reqData.setResourceId(1L);
rabbitTemplate.convertAndSend(RabbitMqConfig.OPERATE_LOG_QUEUE_NAME, JSONObject.toJSONString(reqData));
rabbitTemplate.convertAndSend(OPERATE_LOG_QUEUE_NAME, JSONObject.toJSONString(reqData));
System.out.println("send msg success");
}
Thread.sleep(1000 * 10);

View File

@ -1,11 +1,11 @@
package cn.axzo.xlog.server.service;
package cn.axzo.log.platform.server.service;
import cn.axzo.xlog.server.XlogApplicationTestBase;
import cn.axzo.xlog.server.dto.OperateLogQueryReqDTO;
import cn.axzo.xlog.server.dto.OperateLogQueryRespDTO;
import cn.axzo.xlog.server.dto.OperateLogReqDTO;
import cn.axzo.xlog.server.entity.OperateLogRecordEntity;
import cn.axzo.xlog.server.service.converter.OperateLogConverter;
import cn.axzo.log.platform.server.XlogApplicationTestBase;
import cn.axzo.log.platform.server.dto.OperateLogQueryReqDTO;
import cn.axzo.log.platform.server.dto.OperateLogQueryRespDTO;
import cn.axzo.log.platform.server.dto.OperateLogReqDTO;
import cn.axzo.log.platform.server.entity.OperateLogRecordEntity;
import cn.axzo.log.platform.server.service.converter.OperateLogConverter;
import cn.azxo.framework.common.model.CommonPageResponse;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
@ -73,7 +73,7 @@ public class OperateLogServiceTest extends XlogApplicationTestBase {
}
@Test
public void testPageQuery() {
public void testPageQuery() throws Exception {
OperateLogQueryReqDTO req = new OperateLogQueryReqDTO();
req.setPage(1L);
req.setPageSize(3L);

123
deployment.yaml Normal file
View File

@ -0,0 +1,123 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {ProjectName}
spec:
minReadySeconds: 2
replicas: 1
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
selector:
matchLabels:
app: {ProjectName}
template:
metadata:
labels:
app: {ProjectName}
prometheus: {PROMETHEUS}
logging: '{LOGGING}'
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: work
operator: In
values:
- {nodeSelector}
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- {ProjectName}
topologyKey: kubernetes.io/hostname
weight: 100
terminationGracePeriodSeconds: 60 ##k8s将会给应用发送SIGTERM信号可以用来正确、优雅地关闭应用,默认为30秒
containers:
- name: {ProjectName}
image: registry.cn-hangzhou.aliyuncs.com/axzo-k8s/{namespace}-{ProjectName}:{BUILD_ID}
imagePullPolicy: Always
livenessProbe: #该pod是存活的,不存活则需要重启
httpGet:
path: /checkDeath
port: {port}
scheme: HTTP
initialDelaySeconds: 60 ## equals to the maximum startup time of the application + couple of seconds
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
readinessProbe: #kubernetes认为该pod是启动成功的
httpGet:
path: /checkDeath
port: {port}
scheme: HTTP
initialDelaySeconds: 30 ## equals to minimum startup time of the application
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 5
volumeMounts:
- name: tz-config
mountPath: /etc/localtime
- name: jmx-exporter
mountPath: /data/jmx
env:
- name: NACOS_HOST
value: {NACOS_HOST}
- name: NACOS_PORT
value: "{NACOS_PORT}"
- name: NACOS_NAMESPACE_ID
value: {NACOS_NAMESPACE_ID}
- name: NACOS_PROFILES_ACTIVE
value: {NACOS_PROFILES_ACTIVE}
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
ports:
- containerPort: {port}
resources:
limits:
memory: {limitMemory}
requests:
memory: {requestsMemory}
imagePullSecrets:
- name: aliyun
volumes:
- name: tz-config
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
- name: jmx-exporter
persistentVolumeClaim:
claimName: jmx
---
apiVersion: v1
kind: Service
metadata:
name: {ProjectName}
labels:
app: {ProjectName}
spec:
type: ClusterIP
ports:
- port: {port}
targetPort: {port}
selector:
app: {ProjectName}

19
pom.xml
View File

@ -8,19 +8,20 @@
<version>2.4.13</version>
</parent>
<groupId>cn.axzo.xlog</groupId>
<artifactId>xlog</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>xlog</name>
<url>http://maven.apache.org</url>
<groupId>cn.axzo.platform</groupId>
<artifactId>axzo-log-plat</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>xlog-client</module>
<module>xlog-server</module>
<module>axzo-log-server</module>
<module>axzo-log-api</module>
</modules>
<packaging>pom</packaging>
<name>axzo-log-plat</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mapstruct.version>1.4.2.Final</mapstruct.version>

View File

@ -1,41 +0,0 @@
package cn.axzo.xlog.server.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/***
* @author: pepsi
* @description: TODO
* @date: 2022/9/16
*/
@Configuration
public class RabbitMqConfig {
private final Logger logger = LoggerFactory.getLogger(RabbitMqConfig.class);
// 操作日志队列
public static final String OPERATE_LOG_QUEUE_NAME = "unified.operate.log";
public static final String OPERATE_LOG_EXCHANGE = "unified.operate.log.exchange";
public static final String OPERATE_LOG_ROUTING_KEY = "unified.operate.log.routingKey";
@Bean
public Queue operateLogQueue() {
return new Queue(OPERATE_LOG_QUEUE_NAME, true);
}
@Bean
public DirectExchange operateLogExchange() {
return new DirectExchange(OPERATE_LOG_EXCHANGE, true, false);
}
@Bean
public Binding operateLogBindingDirect(DirectExchange exchange, Queue oprlogeQueue) {
Binding binding = BindingBuilder.bind(oprlogeQueue).to(exchange).with(OPERATE_LOG_ROUTING_KEY);
logger.info("rabbitmq queue:[{}] binding exchange:[{}] success.", oprlogeQueue.getName(), exchange.getName());
return binding;
}
}

View File

@ -1,10 +0,0 @@
package cn.axzo.xlog.server.controller;
/***
* @author: pepsi
* @description: TODO
* @date: 2022/9/16
*/
public abstract class BaseController {
}

View File

@ -1,60 +0,0 @@
package cn.axzo.xlog.server.controller.api;
import cn.axzo.xlog.server.dto.OperateLogQueryReqDTO;
import cn.axzo.xlog.server.dto.OperateLogQueryRespDTO;
import cn.axzo.xlog.server.dto.OperateLogReqDTO;
import cn.axzo.xlog.server.exception.ServiceException;
import cn.axzo.xlog.server.service.OperateLogService;
import cn.azxo.framework.common.model.CommonPageResponse;
import cn.azxo.framework.common.model.CommonResponse;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;
/***
* @author: pepsi
* @description: TODO
* @date: 2022/9/16
*/
@Api(tags = "web-操作日志接口")
@ApiSupport(author = "田立勇")
@RestController
@RequestMapping("/api/v1")
public class OperateLogController {
private final Logger logger = LoggerFactory.getLogger(OperateLogController.class);
@Resource
private OperateLogService operateLogService;
@RequestMapping(value = "/operateLog/create", method = RequestMethod.POST)
@ApiOperation(value = "操作日志创建")
public CommonResponse<Boolean> operateLogCreate(@RequestBody @Valid OperateLogReqDTO req) {
try {
return CommonResponse.success(operateLogService.insertOperaLog(req));
} catch (Exception e) {
logger.error("create operate log failed,", e);
return CommonResponse.fail(e.getMessage());
}
}
@RequestMapping(value = "/operateLog/queryForPage", method = RequestMethod.POST)
@ApiOperation(value = "操作日志查询")
public CommonResponse<CommonPageResponse<OperateLogQueryRespDTO>> operateLogsQuery(@RequestBody @Valid OperateLogQueryReqDTO req) {
try {
return CommonResponse.success(operateLogService.queryForPage(req));
} catch (ServiceException e) {
logger.error("query operate logs failed,", e);
return CommonResponse.fail(e.getMessage());
}
}
}

View File

@ -1,22 +0,0 @@
package cn.axzo.xlog.server.repository;
import cn.axzo.xlog.server.dto.OperateLogQueryReqDTO;
import cn.axzo.xlog.server.entity.OperateLogRecordEntity;
import com.baomidou.mybatisplus.core.metadata.IPage;
/***
* @author: pepsi
* @description: TODO
* @date: 2022/9/15
*/
public interface OperateLogRepository {
/**
* @param user
* @return
*/
OperateLogRecordEntity save(OperateLogRecordEntity user);
IPage<OperateLogRecordEntity> pageLogRecord(OperateLogQueryReqDTO req);
}

View File

@ -1,61 +0,0 @@
package cn.axzo.xlog.server.config;
import cn.axzo.xlog.server.entity.OperateLogRecordEntity;
import cn.axzo.xlog.server.service.BaseEsService;
import com.alibaba.fastjson.JSONObject;
import org.elasticsearch.client.RestHighLevelClient;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/***
* @author: pepsi
* @description: TODO
* @date: 2022/9/19
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class ElasticClientConfigTest extends BaseEsService {
@Autowired
private RestHighLevelClient client;
@Test
public void testInsert() throws Exception {
OperateLogRecordEntity entity = new OperateLogRecordEntity();
entity.setLogGrade(1);
entity.setLogExt("test");
entity.setIdentityId(15L);
entity.setOperateAfter("test");
entity.setOperateParam("test");
entity.setFeatureCode("test");
entity.setOperateTable("test");
entity.setOperateType(1);
entity.setContentSummary("test");
entity.setOperateTime(new Date());
entity.setServiceName("test");
entity.setOuId(1L);
entity.setOperateUserIp("test");
entity.setWorkspaceId(1L);
entity.setResourceType(1);
entity.setIdentityType(3);
entity.setTerminal("test");
entity.setOperateBefore("test");
entity.setFeatureName("test");
entity.setResourceId(1L);
String data = JSONObject.toJSONString(entity);
String index = "xlog_operatelog_202209";
List<String> list = new ArrayList<>();
list.add(data);
boolean flag = this.bulkInsert(list, index);
Assert.assertTrue(flag);
}
}