diff --git a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/LogAutoConfiguration.java b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/LogAutoConfiguration.java
index d94397729..112d4791a 100644
--- a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/LogAutoConfiguration.java
+++ b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/LogAutoConfiguration.java
@@ -22,9 +22,12 @@ package com.pig4cloud.pigx.common.log;
import com.pig4cloud.pigx.admin.api.feign.RemoteLogService;
import com.pig4cloud.pigx.common.core.util.KeyStrResolver;
import com.pig4cloud.pigx.common.log.aspect.SysLogAspect;
+import com.pig4cloud.pigx.common.log.config.PigXLogProperties;
import com.pig4cloud.pigx.common.log.event.SysLogListener;
import lombok.AllArgsConstructor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -37,21 +40,19 @@ import org.springframework.scheduling.annotation.EnableAsync;
* 日志自动配置
*/
@EnableAsync
-@Configuration
-@AllArgsConstructor
-@ConditionalOnWebApplication
+@Configuration(proxyBeanMethods = false)
+@EnableConfigurationProperties(PigXLogProperties.class)
+@ConditionalOnProperty(value = "pigx.log.enabled", matchIfMissing = true)
public class LogAutoConfiguration {
- private final RemoteLogService remoteLogService;
-
@Bean
- public SysLogListener sysLogListener() {
- return new SysLogListener(remoteLogService);
+ public SysLogListener sysLogListener(PigXLogProperties logProperties, RemoteLogService remoteLogService) {
+ return new SysLogListener(remoteLogService, logProperties);
}
@Bean
- public SysLogAspect sysLogAspect(ApplicationEventPublisher publisher, KeyStrResolver resolver) {
- return new SysLogAspect(publisher, resolver);
+ public SysLogAspect sysLogAspect(KeyStrResolver resolver) {
+ return new SysLogAspect(resolver);
}
}
diff --git a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/aspect/SysLogAspect.java b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/aspect/SysLogAspect.java
old mode 100644
new mode 100755
index 1ea5507ec..56ba6b288
--- a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/aspect/SysLogAspect.java
+++ b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/aspect/SysLogAspect.java
@@ -1,20 +1,17 @@
/*
+ * Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
+ * http://www.apache.org/licenses/LICENSE-2.0
*
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.pig4cloud.pigx.common.log.aspect;
@@ -22,6 +19,7 @@ package com.pig4cloud.pigx.common.log.aspect;
import cn.hutool.core.util.StrUtil;
import com.pig4cloud.pigx.admin.api.dto.SysLogDTO;
import com.pig4cloud.pigx.common.core.util.KeyStrResolver;
+import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import com.pig4cloud.pigx.common.log.annotation.SysLog;
import com.pig4cloud.pigx.common.log.event.SysLogEvent;
import com.pig4cloud.pigx.common.log.util.LogTypeEnum;
@@ -33,7 +31,6 @@ import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
-import org.springframework.context.ApplicationEventPublisher;
import org.springframework.expression.EvaluationContext;
/**
@@ -41,17 +38,15 @@ import org.springframework.expression.EvaluationContext;
*
* @author L.cm
*/
-@Slf4j
@Aspect
+@Slf4j
@RequiredArgsConstructor
public class SysLogAspect {
- private final ApplicationEventPublisher publisher;
-
private final KeyStrResolver tenantKeyStrResolver;
- @SneakyThrows
@Around("@annotation(sysLog)")
+ @SneakyThrows
public Object around(ProceedingJoinPoint point, SysLog sysLog) {
String strClassName = point.getTarget().getClass().getName();
String strMethodName = point.getSignature().getName();
@@ -68,30 +63,36 @@ public class SysLogAspect {
value = SysLogUtils.getValue(context, expression, String.class);
}
catch (Exception e) {
- // SPEL 表达式异常,则获取 value 的值
+ // SPEL 表达式异常,获取 value 的值
log.error("@SysLog 解析SPEL {} 异常", expression);
}
}
- SysLogDTO logDTO = SysLogUtils.getSysLog();
- logDTO.setTitle(value);
+ SysLogDTO logVo = SysLogUtils.getSysLog();
+ logVo.setTitle(value);
+ // 获取请求body参数
+ if (StrUtil.isBlank(logVo.getParams())) {
+ logVo.setBody(point.getArgs());
+ }
// 发送异步日志事件
Long startTime = System.currentTimeMillis();
Object obj;
+
try {
obj = point.proceed();
}
catch (Exception e) {
- logDTO.setLogType(LogTypeEnum.ERROR.getType());
- logDTO.setException(e.getMessage());
+ logVo.setLogType(LogTypeEnum.ERROR.getType());
+ logVo.setException(e.getMessage());
throw e;
}
finally {
Long endTime = System.currentTimeMillis();
- logDTO.setTime(endTime - startTime);
- logDTO.setTenantId(Long.parseLong(tenantKeyStrResolver.key()));
- publisher.publishEvent(new SysLogEvent(logDTO));
+ logVo.setTime(endTime - startTime);
+ logVo.setTenantId(Long.parseLong(tenantKeyStrResolver.key()));
+ SpringContextHolder.publishEvent(new SysLogEvent(logVo));
}
+
return obj;
}
diff --git a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/config/PigXLogProperties.java b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/config/PigXLogProperties.java
new file mode 100644
index 000000000..b0f14efdc
--- /dev/null
+++ b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/config/PigXLogProperties.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2019-2029, Dreamlu 卢春梦 (596392912@qq.com & www.dreamlu.net).
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.pig4cloud.pigx.common.log.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.util.List;
+
+/**
+ * 日志配置类
+ *
+ * @author L.cm
+ */
+@Getter
+@Setter
+@ConfigurationProperties(PigXLogProperties.PREFIX)
+public class PigXLogProperties {
+
+ public static final String PREFIX = "pigx.log";
+
+ /**
+ * 开启日志记录
+ */
+ private boolean enabled = true;
+
+ /**
+ * 记录请求报文体
+ */
+ private boolean requestEnabled = true;
+
+ /**
+ * 放行字段,password,mobile,idcard,phone
+ */
+ @Value("${pigx.log.exclude-fields:password,mobile,idcard,phone}")
+ private List excludeFields;
+
+ /**
+ * 请求报文最大存储长度
+ */
+ private Integer maxLength = 2000;
+
+}
diff --git a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/event/SysLogEvent.java b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/event/SysLogEvent.java
old mode 100644
new mode 100755
index ba678d78a..6cf373b48
--- a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/event/SysLogEvent.java
+++ b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/event/SysLogEvent.java
@@ -1,35 +1,31 @@
/*
+ * Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
+ * http://www.apache.org/licenses/LICENSE-2.0
*
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.pig4cloud.pigx.common.log.event;
import com.pig4cloud.pigx.admin.api.dto.SysLogDTO;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
+import org.springframework.context.ApplicationEvent;
/**
* @author lengleng 系统日志事件
*/
-@Getter
-@AllArgsConstructor
-public class SysLogEvent {
+public class SysLogEvent extends ApplicationEvent {
- private final SysLogDTO sysLog;
+ public SysLogEvent(SysLogDTO source) {
+ super(source);
+ }
}
diff --git a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/event/SysLogListener.java b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/event/SysLogListener.java
old mode 100644
new mode 100755
index 461ba7391..85f1e97b2
--- a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/event/SysLogListener.java
+++ b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/event/SysLogListener.java
@@ -1,48 +1,89 @@
/*
+ * Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
+ * http://www.apache.org/licenses/LICENSE-2.0
*
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.pig4cloud.pigx.common.log.event;
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.annotation.JsonFilter;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.ser.FilterProvider;
+import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
+import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.pig4cloud.pigx.admin.api.dto.SysLogDTO;
+import com.pig4cloud.pigx.admin.api.entity.SysLog;
import com.pig4cloud.pigx.admin.api.feign.RemoteLogService;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
-import lombok.AllArgsConstructor;
+import com.pig4cloud.pigx.common.core.jackson.PigxJavaTimeModule;
+import com.pig4cloud.pigx.common.log.config.PigXLogProperties;
+import lombok.RequiredArgsConstructor;
+import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
+import java.util.Objects;
+
/**
* @author lengleng 异步监听日志事件
*/
@Slf4j
-@AllArgsConstructor
-public class SysLogListener {
+@RequiredArgsConstructor
+public class SysLogListener implements InitializingBean {
+
+ // new 一个 避免日志脱敏策略影响全局ObjectMapper
+ private final static ObjectMapper objectMapper = new ObjectMapper();
private final RemoteLogService remoteLogService;
+ private final PigXLogProperties logProperties;
+
+ @SneakyThrows
@Async
@Order
@EventListener(SysLogEvent.class)
public void saveSysLog(SysLogEvent event) {
- SysLogDTO sysLog = event.getSysLog();
- remoteLogService.saveLog(sysLog, SecurityConstants.FROM_IN);
+ SysLogDTO source = (SysLogDTO) event.getSource();
+
+ // json 格式刷参数放在异步中处理,提升性能
+ if (Objects.nonNull(source.getBody()) && logProperties.isRequestEnabled()) {
+ String params = objectMapper.writeValueAsString(source.getBody());
+ source.setParams(StrUtil.subPre(params, logProperties.getMaxLength()));
+ }
+
+ source.setBody(null);
+ remoteLogService.saveLog(source, SecurityConstants.FROM_IN);
+ }
+
+ @Override
+ public void afterPropertiesSet() {
+ objectMapper.addMixIn(Object.class, PropertyFilterMixIn.class);
+ String[] ignorableFieldNames = logProperties.getExcludeFields().toArray(new String[0]);
+
+ FilterProvider filters = new SimpleFilterProvider().addFilter("filter properties by name",
+ SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames));
+ objectMapper.setFilterProvider(filters);
+ objectMapper.registerModule(new PigxJavaTimeModule());
+ }
+
+ @JsonFilter("filter properties by name")
+ class PropertyFilterMixIn {
+
}
}
diff --git a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/util/SysLogUtils.java b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/util/SysLogUtils.java
old mode 100644
new mode 100755
index 96fa47b9f..4e1749e4a
--- a/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/util/SysLogUtils.java
+++ b/pigx-common/pigx-common-log/src/main/java/com/pig4cloud/pigx/common/log/util/SysLogUtils.java
@@ -1,44 +1,46 @@
/*
+ * Copyright (c) 2020 pig4cloud Authors. All Rights Reserved.
*
- * Copyright (c) 2018-2025, lengleng All rights reserved.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * Neither the name of the pig4cloud.com developer nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * Author: lengleng (wangiegie@gmail.com)
+ * http://www.apache.org/licenses/LICENSE-2.0
*
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package com.pig4cloud.pigx.common.log.util;
import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.extra.servlet.JakartaServletUtil;
+import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HttpUtil;
import com.pig4cloud.pigx.admin.api.dto.SysLogDTO;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
+import com.pig4cloud.pigx.common.log.config.PigXLogProperties;
+import jakarta.servlet.http.HttpServletRequest;
import lombok.experimental.UtilityClass;
import org.springframework.core.StandardReflectionParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
+import org.springframework.http.HttpHeaders;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
-import jakarta.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
+import java.util.Map;
import java.util.Objects;
/**
@@ -53,35 +55,22 @@ public class SysLogUtils {
HttpServletRequest request = ((ServletRequestAttributes) Objects
.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
SysLogDTO sysLog = new SysLogDTO();
- sysLog.setCreateBy(getUsername());
sysLog.setLogType(LogTypeEnum.NORMAL.getType());
- sysLog.setRemoteAddr(JakartaServletUtil.getClientIP(request));
sysLog.setRequestUri(URLUtil.getPath(request.getRequestURI()));
sysLog.setMethod(request.getMethod());
- sysLog.setUserAgent(request.getHeader("user-agent"));
- sysLog.setParams(HttpUtil.toParams(request.getParameterMap()));
+ sysLog.setRemoteAddr(JakartaServletUtil.getClientIP(request));
+ sysLog.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT));
+ sysLog.setCreateBy(getUsername());
sysLog.setServiceId(getClientId());
+
+ // get 参数脱敏
+ PigXLogProperties logProperties = SpringUtil.getBean(PigXLogProperties.class);
+ Map paramsMap = MapUtil.removeAny(request.getParameterMap(),
+ ArrayUtil.toArray(logProperties.getExcludeFields(), String.class));
+ sysLog.setParams(HttpUtil.toParams(paramsMap));
return sysLog;
}
- /**
- * 获取客户端
- * @return clientId
- */
- private String getClientId() {
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
- if (authentication == null) {
- return null;
- }
-
- Object principal = authentication.getPrincipal();
- if (principal instanceof OAuth2AuthenticatedPrincipal) {
- OAuth2AuthenticatedPrincipal auth2Authentication = (OAuth2AuthenticatedPrincipal) principal;
- return MapUtil.getStr(auth2Authentication.getAttributes(), SecurityConstants.CLIENT_ID);
- }
- return null;
- }
-
/**
* 获取用户名称
* @return username
@@ -126,4 +115,22 @@ public class SysLogUtils {
return context;
}
+ /**
+ * 获取客户端
+ * @return clientId
+ */
+ private String getClientId() {
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ if (authentication == null) {
+ return null;
+ }
+
+ Object principal = authentication.getPrincipal();
+ if (principal instanceof OAuth2AuthenticatedPrincipal) {
+ OAuth2AuthenticatedPrincipal auth2Authentication = (OAuth2AuthenticatedPrincipal) principal;
+ return MapUtil.getStr(auth2Authentication.getAttributes(), SecurityConstants.CLIENT_ID);
+ }
+ return null;
+ }
+
}
diff --git a/pigx-common/pigx-common-log/src/main/resources/META-INF/spring.factories b/pigx-common/pigx-common-log/src/main/resources/META-INF/spring.factories
deleted file mode 100644
index 83eb42f33..000000000
--- a/pigx-common/pigx-common-log/src/main/resources/META-INF/spring.factories
+++ /dev/null
@@ -1,2 +0,0 @@
-org.springframework.boot.env.EnvironmentPostProcessor=\
- com.pig4cloud.pigx.common.log.init.ApplicationLoggerInitializer
diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/SysLogDTO.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/SysLogDTO.java
index a512eeb34..275a81b0e 100644
--- a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/SysLogDTO.java
+++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/dto/SysLogDTO.java
@@ -68,6 +68,11 @@ public class SysLogDTO {
*/
private String params;
+ /**
+ * 参数重写成object
+ */
+ private Object body;
+
/**
* 执行时间
*/