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;
+    }
 }

Reply via email to