初始化项目

This commit is contained in:
2026-04-21 16:12:04 +08:00
parent 4541af2c63
commit f9d96473da
443 changed files with 36365 additions and 19 deletions

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.xujun</groupId>
<artifactId>xtools-app-common</artifactId>
<version>1.0.0</version>
</parent>
<packaging>pom</packaging>
<artifactId>xtools-app-common-log</artifactId>
<!-- 子模块 -->
<modules>
<module>xtools-app-common-log-bus</module>
<module>xtools-app-common-log-filter</module>
</modules>
</project>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.xujun</groupId>
<artifactId>xtools-app-common-log</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>xtools-app-common-log-bus</artifactId>
<!-- 依赖 -->
<dependencies>
<!-- xtools begin -->
<!-- xtools-boot-log -->
<dependency>
<groupId>org.xujun</groupId>
<artifactId>xtools-boot-log</artifactId>
</dependency>
<!-- xtools end -->
<!-- 项目模块 begin -->
<dependency>
<groupId>org.xujun</groupId>
<artifactId>xtools-app-common-mq</artifactId>
</dependency>
<!-- 项目模块 end -->
</dependencies>
</project>

View File

@@ -0,0 +1,71 @@
package xtools.app.common.log.bus.enums;
import xtools.boot.api.enums.BaseEnum;
import xtools.boot.log.interfaces.LogBusType;
/**
* <p>Title : SysLogType</p>
* <p>Description : SysLogType</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 1.0.0
* @date : 2026/2/3 11:26
*/
public enum SysLogType implements LogBusType {
;
/**
* 编码
**/
private final int code;
/**
* 说明
**/
private final String desc;
/**
* 初始化方法
*
* @param code Code
* @param desc 说明
*/
SysLogType(int code, String desc) {
this.code = code;
this.desc = desc;
}
/**
* 获取所有枚举
*
* @return 所有枚举
*/
@Override
public BaseEnum[] all() {
return values();
}
/**
* 获取枚举编码
*
* @return 枚举编码
*/
@Override
public int code() {
return code + BASE_CODE;
}
/**
* 获取枚举说明
*
* @return 枚举说明
*/
@Override
public String desc() {
return desc;
}
}

View File

@@ -0,0 +1,54 @@
package xtools.app.common.log.bus.handle;
import org.springframework.stereotype.Component;
import xtools.app.common.log.bus.service.LogBusService;
import xtools.app.common.mq.enums.RabbitMqEnums;
import xtools.boot.core.utils.SpringContextUtils;
import xtools.boot.log.interfaces.LogBusInterface;
import xtools.boot.log.model.dto.LogBody;
import xtools.boot.mq.base.utils.MqBus;
import java.util.Objects;
/**
* <p>Title : LogBusHandle</p>
* <p>Description : LogBusHandle</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 1.0.0
* @date : 2026/2/3 17:01
*/
@Component
public class LogBusHandle implements LogBusInterface {
/**
* 日志服务
*/
private static LogBusService logBusService;
/**
* 是否使用本地服务
*/
private static Boolean localService;
/**
* 保存日志
*
* @param logBody 日志
*/
@Override
public void save(LogBody logBody) {
if (Objects.isNull(localService)) {
logBusService = SpringContextUtils.getBeanDefNull(LogBusService.class);
localService = Objects.nonNull(logBusService);
}
if (localService) {
logBusService.saveLog(logBody);
} else {
MqBus.push(RabbitMqEnums.SYS_LOG, logBody);
}
}
}

View File

@@ -0,0 +1,25 @@
package xtools.app.common.log.bus.service;
import xtools.boot.log.model.dto.LogBody;
/**
* <p>Title : LogBusService</p>
* <p>Description : LogBusService</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 1.0.0
* @date : 2026/2/7 19:41
*/
public interface LogBusService {
/**
* 保存日志
*
* @param logBody 日志
*/
void saveLog(LogBody logBody);
}

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.xujun</groupId>
<artifactId>xtools-app-common-log</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>xtools-app-common-log-filter</artifactId>
<!-- 依赖 -->
<dependencies>
<!-- xtools begin -->
<!-- xtools-extend -->
<dependency>
<groupId>org.xujun</groupId>
<artifactId>xtools-extend</artifactId>
</dependency>
<!-- xtools-web -->
<dependency>
<groupId>org.xujun</groupId>
<artifactId>xtools-web</artifactId>
</dependency>
<!-- xtools-boot-web-filter -->
<dependency>
<groupId>org.xujun</groupId>
<artifactId>xtools-boot-web-filter</artifactId>
</dependency>
<!-- xtools end -->
<!-- 项目模块 begin -->
<!-- xtools-app-common-log-bus -->
<dependency>
<groupId>org.xujun</groupId>
<artifactId>xtools-app-common-log-bus</artifactId>
</dependency>
<!-- 项目模块 end -->
<!-- fastjson2 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,177 @@
package xtools.app.common.log.filter;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.jspecify.annotations.NonNull;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;
import xtools.app.common.log.whitelist.HttpLogWhitelist;
import xtools.base.config.BaseParams;
import xtools.boot.api.constant.BootCommonConstant;
import xtools.boot.core.utils.PathPatternUtils;
import xtools.boot.core.utils.SpringContextUtils;
import xtools.boot.log.LogBus;
import xtools.boot.log.enums.LogBusBaseType;
import xtools.boot.web.filter.base.BaseFilter;
import xtools.core.CollectionUtils;
import xtools.core.enums.LogLevel;
import xtools.web.HeaderUtils;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
/**
* <p>Title : HttpLogFilter</p>
* <p>Description : HttpLogFilter</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 1.0.0
* @date : 2026/1/6 16:37
*/
@Component
public class HttpLogFilter extends BaseFilter implements Ordered, BaseParams {
/**
* 日志白名单
*/
private static final Set<String> LOG_WHITE_LIST = new HashSet<>();
/**
* 响应体白名单
*/
private static final Set<String> RESP_WHITE_LIST = new HashSet<>();
/**
* 缓存大小
*/
private static final int DEFAULT_CACHE_LIMIT = 1024 * 1024;
@Override
public int getOrder() {
return CP_NUM200;
}
@Override
protected void initFilterBean() throws ServletException {
super.initFilterBean();
Collection<HttpLogWhitelist> beanList = SpringContextUtils.getBeanList(HttpLogWhitelist.class);
if (CollectionUtils.isEmpty(beanList)) {
return;
}
beanList.forEach(item -> {
LOG_WHITE_LIST.addAll(item.ignoreLog());
RESP_WHITE_LIST.addAll(item.ignoreResp());
});
}
@Override
protected void doFilterInternal(
@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull FilterChain filterChain
) throws ServletException, IOException {
long startTime = System.currentTimeMillis();
// 获取访问 uri
String uri = HeaderUtils.getUri(request);
if (PathPatternUtils.match(LOG_WHITE_LIST, uri)) {
filterChain.doFilter(request, response);
return;
}
// 获取请求日志
JSONObject log = getRequestLog(request);
// 记录请求日志
LogBus.init(LogLevel.INFO, LogBusBaseType.HTTP_REQUEST).data(log).save();
// 包装请求和响应
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request, DEFAULT_CACHE_LIMIT);
ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
// 处理请求
filterChain.doFilter(requestWrapper, responseWrapper);
// 获取请求参数
Object reqParam = getContent(requestWrapper.getContentAsByteArray());
log.put("reqBody", reqParam);
// 处理异常日志
LogLevel level = LogLevel.INFO;
if (!PathPatternUtils.match(RESP_WHITE_LIST, uri)) {
// 获取响应内容
Object respData = getContent(responseWrapper.getContentAsByteArray());
log.put("respData", respData);
if (respData instanceof JSONObject respJson) {
Boolean success = respJson.getBoolean("success");
if (Objects.equals(success, false)) {
level = LogLevel.ERROR;
}
}
}
long endTime = System.currentTimeMillis();
log.put("execTime", endTime - startTime);
// 将内容复制回原始响应
responseWrapper.copyBodyToResponse();
// 记录响应日志
LogBus.init(level, LogBusBaseType.HTTP_RESPONSE).data(log).save();
}
/**
* 获取内容
*
* @param content 内容
* @return 内容
*/
@NonNull
private Object getContent(byte[] content) {
if (Objects.isNull(content) || content.length == CP_NUM0) {
return "empty";
}
String data = new String(content, StandardCharsets.UTF_8);
try {
return JSONObject.parseObject(data);
} catch (Exception e) {
// ignore
}
try {
return JSONArray.parse(data);
} catch (Exception e) {
// ignore
}
return data;
}
/**
* 获取请求日志
*
* @param request 请求
* @return 请求日志
*/
public JSONObject getRequestLog(HttpServletRequest request) {
// 基础日志信息
JSONObject log = new JSONObject();
log.put("uri", HeaderUtils.getUri(request));
log.put("method", request.getMethod());
log.put("query", HeaderUtils.getQuery(request));
log.put("params", HeaderUtils.getParamsToString(request));
log.put("userAgent", HeaderUtils.getUserAgent(request));
log.put("referer", HeaderUtils.getReferer(request));
log.put("ip", HeaderUtils.getIp(request));
log.put(BootCommonConstant.UID, HeaderUtils.getRequestParam(request, BootCommonConstant.UID));
log.put(BootCommonConstant.AUTHORIZATION, HeaderUtils.getRequestParam(request, BootCommonConstant.AUTHORIZATION));
return log;
}
}

View File

@@ -0,0 +1,36 @@
package xtools.app.common.log.whitelist;
import java.util.Set;
/**
* <p>Title : HttpLogWhitelist</p>
* <p>Description : HttpLogWhitelist</p>
* <p>DevelopTools : Idea_x64_v2026.1</p>
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
* <p>Company : org.xujun</p>
*
* @author : XuJun
* @version : 1.0.0
* @date : 2026/4/2 14:36
*/
public interface HttpLogWhitelist {
/**
* 添加日志白名单
*
* @return 日志白名单
*/
default Set<String> ignoreLog() {
return Set.of();
}
/**
* 添加响应体白名单
*
* @return 响应体白名单
*/
default Set<String> ignoreResp() {
return Set.of();
}
}