This is an automated email from the ASF dual-hosted git repository.
Aias00 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git
The following commit(s) were added to refs/heads/master by this push:
new 6a3ea9ee96 perf(logging): reuse compiled keyword matcher (#7074)
6a3ea9ee96 is described below
commit 6a3ea9ee96a3392a6d075b1baea0d388b1b2d853
Author: Liming Deng <[email protected]>
AuthorDate: Thu Oct 1 06:30:44 2026 +0800
perf(logging): reuse compiled keyword matcher (#7074)
---
.../logging/common/AbstractLoggingPlugin.java | 11 ++++----
.../common/body/LoggingServerHttpResponse.java | 20 +++++++++++--
.../common/entity/CommonLoggingRuleHandle.java | 33 ++++++++++++++++++++++
.../body/LoggingServerHttpResponseStatusTest.java | 2 +-
.../common/body/LoggingServerHttpResponseTest.java | 7 ++---
.../common/entity/CommonLoggingRuleHandleTest.java | 33 ++++++++++++++++------
6 files changed, 85 insertions(+), 21 deletions(-)
diff --git
a/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/main/java/org/apache/shenyu/plugin/logging/common/AbstractLoggingPlugin.java
b/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/main/java/org/apache/shenyu/plugin/logging/common/AbstractLoggingPlugin.java
index ae704e5cd2..75411631fa 100644
---
a/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/main/java/org/apache/shenyu/plugin/logging/common/AbstractLoggingPlugin.java
+++
b/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/main/java/org/apache/shenyu/plugin/logging/common/AbstractLoggingPlugin.java
@@ -17,7 +17,6 @@
package org.apache.shenyu.plugin.logging.common;
-import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.apache.shenyu.common.dto.RuleData;
import org.apache.shenyu.common.dto.SelectorData;
@@ -36,6 +35,7 @@ import
org.apache.shenyu.plugin.logging.common.handler.AbstractLogPluginDataHand
import org.apache.shenyu.plugin.logging.common.utils.LogCollectConfigUtils;
import org.apache.shenyu.plugin.logging.common.utils.LogCollectUtils;
import
org.apache.shenyu.plugin.logging.desensitize.api.enums.DataDesensitizeEnum;
+import org.apache.shenyu.plugin.logging.desensitize.api.matcher.KeyWordMatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
@@ -45,7 +45,6 @@ import reactor.core.publisher.Mono;
import java.util.Collections;
import java.util.Objects;
import java.util.Optional;
-import java.util.Set;
/**
@@ -55,6 +54,8 @@ public abstract class AbstractLoggingPlugin<L extends
ShenyuRequestLog> extends
private static final Logger LOG =
LoggerFactory.getLogger(AbstractLoggingPlugin.class);
+ private static final KeyWordMatch EMPTY_KEY_WORD_MATCH = new
KeyWordMatch(Collections.emptySet());
+
/**
* LogCollector.
*
@@ -84,13 +85,13 @@ public abstract class AbstractLoggingPlugin<L extends
ShenyuRequestLog> extends
final SelectorData selector, final RuleData
rule) {
CommonLoggingRuleHandle commonLoggingRuleHandle =
AbstractLogPluginDataHandler.CACHED_HANDLE.get().obtainHandle(CacheKeyUtils.INST.getKey(rule));
boolean desensitized = Boolean.FALSE;
- Set<String> keywordSets = Sets.newHashSet();
+ KeyWordMatch keyWordMatch = EMPTY_KEY_WORD_MATCH;
String dataDesensitizeAlg =
DataDesensitizeEnum.MD5_ENCRYPT.getDataDesensitizeAlg();
if (Objects.nonNull(commonLoggingRuleHandle)) {
String keywords = commonLoggingRuleHandle.getKeyword();
desensitized = StringUtils.isNotBlank(keywords) &&
commonLoggingRuleHandle.getMaskStatus();
if (desensitized) {
- Collections.addAll(keywordSets, keywords.split(";"));
+ keyWordMatch = commonLoggingRuleHandle.getKeyWordMatch();
dataDesensitizeAlg =
Optional.ofNullable(commonLoggingRuleHandle.getMaskType()).orElse(DataDesensitizeEnum.MD5_ENCRYPT.getDataDesensitizeAlg());
LOG.info("current plugin:{}, keyword:{},
dataDesensitizeAlg:{}", pluginEnum().getName(), keywords, dataDesensitizeAlg);
}
@@ -116,7 +117,7 @@ public abstract class AbstractLoggingPlugin<L extends
ShenyuRequestLog> extends
requestInfo.setNamespaceId(rule.getNamespaceId());
LoggingServerHttpRequest<L> loggingServerHttpRequest = new
LoggingServerHttpRequest<>(request, requestInfo);
LoggingServerHttpResponse<L> loggingServerHttpResponse = new
LoggingServerHttpResponse<>(exchange.getResponse(),
- requestInfo, this.logCollector(), desensitized, keywordSets,
dataDesensitizeAlg);
+ requestInfo, this.logCollector(), desensitized, keyWordMatch,
dataDesensitizeAlg);
ServerWebExchange webExchange =
exchange.mutate().request(loggingServerHttpRequest)
.response(loggingServerHttpResponse).build();
loggingServerHttpResponse.setExchange(webExchange);
diff --git
a/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/main/java/org/apache/shenyu/plugin/logging/common/body/LoggingServerHttpResponse.java
b/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/main/java/org/apache/shenyu/plugin/logging/common/body/LoggingServerHttpResponse.java
index 8c488727ee..28faf12c91 100644
---
a/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/main/java/org/apache/shenyu/plugin/logging/common/body/LoggingServerHttpResponse.java
+++
b/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/main/java/org/apache/shenyu/plugin/logging/common/body/LoggingServerHttpResponse.java
@@ -83,18 +83,34 @@ public class LoggingServerHttpResponse<L extends
ShenyuRequestLog> extends Serve
* @param logInfo access log
* @param logCollector LogCollector instance
* @param desensitized desensitize flag
- * @param keyWordSet user keyWord set
+ * @param keyWordSet user keyword set
* @param dataDesensitizeAlg desensitize function
*/
public LoggingServerHttpResponse(final ServerHttpResponse delegate, final
L logInfo,
final LogCollector<L> logCollector, final
boolean desensitized,
final Set<String> keyWordSet, final
String dataDesensitizeAlg) {
+ this(delegate, logInfo, logCollector, desensitized, new
KeyWordMatch(keyWordSet), dataDesensitizeAlg);
+ }
+
+ /**
+ * Constructor LoggingServerHttpResponse.
+ *
+ * @param delegate delegate ServerHttpResponse
+ * @param logInfo access log
+ * @param logCollector LogCollector instance
+ * @param desensitized desensitize flag
+ * @param keyWordMatch compiled keyword matcher
+ * @param dataDesensitizeAlg desensitize function
+ */
+ public LoggingServerHttpResponse(final ServerHttpResponse delegate, final
L logInfo,
+ final LogCollector<L> logCollector, final
boolean desensitized,
+ final KeyWordMatch keyWordMatch, final
String dataDesensitizeAlg) {
super(delegate);
this.logInfo = logInfo;
this.logCollector = logCollector;
this.desensitized = desensitized;
this.dataDesensitizeAlg = dataDesensitizeAlg;
- this.keyWordMatch = new KeyWordMatch(keyWordSet);
+ this.keyWordMatch = keyWordMatch;
}
/**
diff --git
a/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/main/java/org/apache/shenyu/plugin/logging/common/entity/CommonLoggingRuleHandle.java
b/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/main/java/org/apache/shenyu/plugin/logging/common/entity/CommonLoggingRuleHandle.java
index 7570824f40..ba2610845d 100644
---
a/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/main/java/org/apache/shenyu/plugin/logging/common/entity/CommonLoggingRuleHandle.java
+++
b/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/main/java/org/apache/shenyu/plugin/logging/common/entity/CommonLoggingRuleHandle.java
@@ -17,7 +17,15 @@
package org.apache.shenyu.plugin.logging.common.entity;
+import org.apache.commons.lang3.StringUtils;
import org.apache.shenyu.common.dto.convert.rule.RuleHandle;
+import org.apache.shenyu.plugin.logging.desensitize.api.matcher.KeyWordMatch;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
/**
* common logging rule handle.
@@ -39,6 +47,8 @@ public class CommonLoggingRuleHandle implements RuleHandle {
*/
private Boolean maskStatus;
+ private transient volatile KeyWordMatch keyWordMatch;
+
/**
* get keyword.
*
@@ -54,6 +64,29 @@ public class CommonLoggingRuleHandle implements RuleHandle {
*/
public void setKeyword(final String keyword) {
this.keyword = keyword;
+ this.keyWordMatch = null;
+ }
+
+ /**
+ * Get the compiled keyword matcher.
+ *
+ * @return keyword matcher
+ */
+ public KeyWordMatch getKeyWordMatch() {
+ KeyWordMatch result = keyWordMatch;
+ if (Objects.isNull(result)) {
+ synchronized (this) {
+ result = keyWordMatch;
+ if (Objects.isNull(result)) {
+ Set<String> keywords = StringUtils.isBlank(keyword)
+ ? Collections.emptySet()
+ : new HashSet<>(Arrays.asList(keyword.split(";")));
+ result = new KeyWordMatch(keywords);
+ keyWordMatch = result;
+ }
+ }
+ }
+ return result;
}
/**
diff --git
a/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/test/java/org/apache/shenyu/plugin/logging/common/body/LoggingServerHttpResponseStatusTest.java
b/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/test/java/org/apache/shenyu/plugin/logging/common/body/LoggingServerHttpResponseStatusTest.java
index 26dd9f48be..123292baff 100644
---
a/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/test/java/org/apache/shenyu/plugin/logging/common/body/LoggingServerHttpResponseStatusTest.java
+++
b/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/test/java/org/apache/shenyu/plugin/logging/common/body/LoggingServerHttpResponseStatusTest.java
@@ -62,7 +62,7 @@ public final class LoggingServerHttpResponseStatusTest {
AtomicReference<ShenyuRequestLog> collectedLog = new
AtomicReference<>();
LogCollector<ShenyuRequestLog> logCollector = new
RecordingLogCollector(collectedLog);
LoggingServerHttpResponse<ShenyuRequestLog> response = new
LoggingServerHttpResponse<>(exchange.getResponse(),
- new ShenyuRequestLog(), logCollector, false,
Collections.emptySet(), "dataMaskByCharReplace");
+ new ShenyuRequestLog(), logCollector, false, new
KeyWordMatch(Collections.emptySet()), "dataMaskByCharReplace");
response.setExchange(exchange);
response.logError(new
ResponseStatusException(HttpStatusCode.valueOf(599), "error"));
diff --git
a/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/test/java/org/apache/shenyu/plugin/logging/common/body/LoggingServerHttpResponseTest.java
b/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/test/java/org/apache/shenyu/plugin/logging/common/body/LoggingServerHttpResponseTest.java
index 61579c3046..d3a6035ad4 100644
---
a/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/test/java/org/apache/shenyu/plugin/logging/common/body/LoggingServerHttpResponseTest.java
+++
b/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/test/java/org/apache/shenyu/plugin/logging/common/body/LoggingServerHttpResponseTest.java
@@ -27,6 +27,7 @@ import
org.apache.shenyu.plugin.logging.common.collector.LogCollector;
import org.apache.shenyu.plugin.logging.common.constant.GenericLoggingConstant;
import org.apache.shenyu.plugin.logging.common.entity.ShenyuRequestLog;
import org.apache.shenyu.plugin.logging.common.utils.LogCollectUtils;
+import org.apache.shenyu.plugin.logging.desensitize.api.matcher.KeyWordMatch;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -44,8 +45,7 @@ import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
-import java.util.HashSet;
-import java.util.Set;
+import java.util.Collections;
import static org.mockito.Mockito.mock;
@@ -96,9 +96,8 @@ public class LoggingServerHttpResponseTest {
requestInfo.setUserAgent(serverHttpRequest.getHeaders().getFirst(GenericLoggingConstant.USER_AGENT));
requestInfo.setHost(serverHttpRequest.getHeaders().getFirst(GenericLoggingConstant.HOST));
requestInfo.setPath(serverHttpRequest.getURI().getRawPath());
- Set<String> keyWordSet = new HashSet<>();
this.loggingServerHttpResponse = new
LoggingServerHttpResponse(exchange.getResponse(), requestInfo,
- logCollector, false, keyWordSet, "dataMaskByCharReplace");
+ logCollector, false, new KeyWordMatch(Collections.emptySet()),
"dataMaskByCharReplace");
}
@Test
diff --git
a/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/test/java/org/apache/shenyu/plugin/logging/common/entity/CommonLoggingRuleHandleTest.java
b/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/test/java/org/apache/shenyu/plugin/logging/common/entity/CommonLoggingRuleHandleTest.java
index 3680f4664b..4436a91c88 100644
---
a/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/test/java/org/apache/shenyu/plugin/logging/common/entity/CommonLoggingRuleHandleTest.java
+++
b/shenyu-plugin/shenyu-plugin-logging/shenyu-plugin-logging-common/src/test/java/org/apache/shenyu/plugin/logging/common/entity/CommonLoggingRuleHandleTest.java
@@ -17,25 +17,40 @@
package org.apache.shenyu.plugin.logging.common.entity;
+import org.apache.shenyu.plugin.logging.desensitize.api.matcher.KeyWordMatch;
import org.junit.jupiter.api.Test;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.Is.is;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertTrue;
/**
- * Test case for CommonLoggingRuleHandle.
+ * Test cases for {@link CommonLoggingRuleHandle}.
*/
-public class CommonLoggingRuleHandleTest {
+public final class CommonLoggingRuleHandleTest {
@Test
- public void testSetMaskTypeRoundTrip() {
+ public void testKeyWordMatchIsCachedUntilKeywordChanges() {
CommonLoggingRuleHandle handle = new CommonLoggingRuleHandle();
+ handle.setKeyword("requestBody;responseBody");
- // setMaskType used to assign the field to itself and silently drop
the value
- handle.setMaskType("mask");
- assertThat(handle.getMaskType(), is("mask"));
+ KeyWordMatch first = handle.getKeyWordMatch();
+ assertSame(first, handle.getKeyWordMatch());
+ assertTrue(first.matches("requestBody"));
+
+ handle.setKeyword("clientIp");
+ KeyWordMatch updated = handle.getKeyWordMatch();
+ assertNotSame(first, updated);
+ assertTrue(updated.matches("clientIp"));
+ }
+ @Test
+ public void testSetMaskTypeRoundTrip() {
+ CommonLoggingRuleHandle handle = new CommonLoggingRuleHandle();
+ handle.setMaskType("mask");
+ assertEquals("mask", handle.getMaskType());
handle.setMaskType(null);
- assertThat(handle.getMaskType(), is((String) null));
+ assertEquals(null, handle.getMaskType());
}
}