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 5e7612d9d8 fix: remove raw request path label from
shenyu_request_type_total (#6671) (#7056)
5e7612d9d8 is described below
commit 5e7612d9d8dc03f93d8ed80491bfab0797b54d4f
Author: wy471x <[email protected]>
AuthorDate: Mon Sep 21 08:40:39 2026 +0800
fix: remove raw request path label from shenyu_request_type_total (#6671)
(#7056)
shenyu_request_type_total was labelled with the raw request path, so every
distinct path (for example /api/user/123 and /api/order/456) created a new
Counter.Child inside the Prometheus client's internal children map, which is
never evicted. On a gateway serving parameterised routes that map grows with
the number of distinct paths and eventually exhausts the heap.
Drop the path label and keep only rpcType, which is a bounded dimension, and
add a regression test asserting that the raw path is no longer forwarded as
a
label value.
Co-authored-by: aias00 <[email protected]>
---
.../shenyu/plugin/metrics/MetricsPlugin.java | 2 +-
.../plugin/metrics/reporter/MetricsReporter.java | 2 +-
.../shenyu/plugin/metrics/MetricsPluginTest.java | 32 ++++++++++++++++++++++
3 files changed, 34 insertions(+), 2 deletions(-)
diff --git
a/shenyu-plugin/shenyu-plugin-metrics/src/main/java/org/apache/shenyu/plugin/metrics/MetricsPlugin.java
b/shenyu-plugin/shenyu-plugin-metrics/src/main/java/org/apache/shenyu/plugin/metrics/MetricsPlugin.java
index 0eda902b3d..66c2f9f850 100644
---
a/shenyu-plugin/shenyu-plugin-metrics/src/main/java/org/apache/shenyu/plugin/metrics/MetricsPlugin.java
+++
b/shenyu-plugin/shenyu-plugin-metrics/src/main/java/org/apache/shenyu/plugin/metrics/MetricsPlugin.java
@@ -46,7 +46,7 @@ public class MetricsPlugin implements ShenyuPlugin {
ShenyuContext shenyuContext = exchange.getAttribute(Constants.CONTEXT);
Objects.requireNonNull(shenyuContext);
setMetricsCallbacks(exchange);
- MetricsReporter.counterIncrement(LabelNames.REQUEST_TYPE_TOTAL, new
String[]{exchange.getRequest().getURI().getRawPath(),
shenyuContext.getRpcType()});
+ MetricsReporter.counterIncrement(LabelNames.REQUEST_TYPE_TOTAL, new
String[]{shenyuContext.getRpcType()});
LocalDateTime startDateTime =
Optional.of(shenyuContext).map(ShenyuContext::getStartDateTime).orElseGet(LocalDateTime::now);
return chain.execute(exchange).doOnSuccess(e ->
responseCommitted(exchange, startDateTime))
.doOnError(throwable -> {
diff --git
a/shenyu-plugin/shenyu-plugin-metrics/src/main/java/org/apache/shenyu/plugin/metrics/reporter/MetricsReporter.java
b/shenyu-plugin/shenyu-plugin-metrics/src/main/java/org/apache/shenyu/plugin/metrics/reporter/MetricsReporter.java
index 5c926ed98e..38096fa29b 100644
---
a/shenyu-plugin/shenyu-plugin-metrics/src/main/java/org/apache/shenyu/plugin/metrics/reporter/MetricsReporter.java
+++
b/shenyu-plugin/shenyu-plugin-metrics/src/main/java/org/apache/shenyu/plugin/metrics/reporter/MetricsReporter.java
@@ -40,7 +40,7 @@ public final class MetricsReporter {
public static void register(final MetricsRegister metricsRegister) {
MetricsReporter.metricsRegister = metricsRegister;
MetricsReporter.registerCounter(LabelNames.REQUEST_TOTAL, "shenyu
request total count");
- MetricsReporter.registerCounter(LabelNames.REQUEST_TYPE_TOTAL, new
String[]{"path", "type"}, "shenyu http request type total count");
+ MetricsReporter.registerCounter(LabelNames.REQUEST_TYPE_TOTAL, new
String[]{"type"}, "shenyu http request type total count");
MetricsReporter.registerCounter(LabelNames.REQUEST_THROW_TOTAL,
"shenyu request error total count");
MetricsReporter.registerHistogram(LabelNames.EXECUTE_LATENCY_NAME,
"the shenyu executor latency millis");
MetricsReporter.registerCounter(LabelNames.SENTINEL_REQUEST_RESTRICT_TOTAL,
"shenyu sentinel request restrict total count");
diff --git
a/shenyu-plugin/shenyu-plugin-metrics/src/test/java/org/apache/shenyu/plugin/metrics/MetricsPluginTest.java
b/shenyu-plugin/shenyu-plugin-metrics/src/test/java/org/apache/shenyu/plugin/metrics/MetricsPluginTest.java
index c987ecc10b..1b07081afb 100644
---
a/shenyu-plugin/shenyu-plugin-metrics/src/test/java/org/apache/shenyu/plugin/metrics/MetricsPluginTest.java
+++
b/shenyu-plugin/shenyu-plugin-metrics/src/test/java/org/apache/shenyu/plugin/metrics/MetricsPluginTest.java
@@ -19,10 +19,14 @@ package org.apache.shenyu.plugin.metrics;
import org.apache.shenyu.common.constant.Constants;
import org.apache.shenyu.common.enums.PluginEnum;
+import org.apache.shenyu.common.enums.RpcTypeEnum;
import org.apache.shenyu.plugin.api.RemoteAddressResolver;
import org.apache.shenyu.plugin.api.ShenyuPluginChain;
import org.apache.shenyu.plugin.api.context.ShenyuContext;
import org.apache.shenyu.plugin.api.utils.SpringBeanUtils;
+import org.apache.shenyu.plugin.metrics.constant.LabelNames;
+import org.apache.shenyu.plugin.metrics.reporter.MetricsReporter;
+import org.apache.shenyu.plugin.metrics.spi.MetricsRegister;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -84,4 +88,32 @@ public class MetricsPluginTest {
public void testNamed() {
Assertions.assertEquals(metricsPlugin.named(),
PluginEnum.METRICS.getName());
}
+
+ @Test
+ public void testRequestTypeTotalIsNotLabelledByRawPath() {
+ MetricsRegister metricsRegister = Mockito.mock(MetricsRegister.class);
+ MetricsReporter.register(metricsRegister);
+ try {
+
Mockito.when(chain.execute(ArgumentMatchers.any())).thenReturn(Mono.empty());
+ String rpcType = RpcTypeEnum.HTTP.getName();
+ ShenyuContext shenyuContext = Mockito.mock(ShenyuContext.class);
+
Mockito.lenient().when(shenyuContext.getRpcType()).thenReturn(rpcType);
+
StepVerifier.create(metricsPlugin.execute(createExchange("/api/user/123",
shenyuContext), chain))
+ .expectSubscription().verifyComplete();
+
StepVerifier.create(metricsPlugin.execute(createExchange("/api/order/456",
shenyuContext), chain))
+ .expectSubscription().verifyComplete();
+ // the raw path must not be used as label value, otherwise the
prometheus client keeps
+ // one child series per distinct path and its children map grows
without bound.
+ Mockito.verify(metricsRegister, Mockito.times(2))
+ .counterIncrement(LabelNames.REQUEST_TYPE_TOTAL, new
String[]{rpcType}, 1L);
+ } finally {
+ MetricsReporter.clean();
+ }
+ }
+
+ private ServerWebExchange createExchange(final String path, final
ShenyuContext shenyuContext) {
+ ServerWebExchange result =
MockServerWebExchange.from(MockServerHttpRequest.get("http://localhost" +
path).build());
+ result.getAttributes().put(Constants.CONTEXT, shenyuContext);
+ return result;
+ }
}