This is an automated email from the ASF dual-hosted git repository.

amaechler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new 9733020550c fix: Stop task count metrics from leaking dimensions 
across rows (#20726)
9733020550c is described below

commit 9733020550c22999e00f0d1920f634e5f6b1ba02
Author: Andreas Maechler <[email protected]>
AuthorDate: Mon Oct 26 10:01:31 2026 -0600

    fix: Stop task count metrics from leaking dimensions across rows (#20726)
    
    * Fix dimensions leaking across rows in TaskCountStatsMonitor
    
    TaskCountStatsMonitor reused one ServiceMetricEvent.Builder for every row 
of a
    task count metric. Builder dimensions accumulate, so a row without 
supervisorId
    inherited the previous row's value, and an empty row key inherited the 
previous
    row's dataSource and taskType. Create a new builder per row.
    
    * Simplify TaskCountStatsMonitor regression test setup
---
 .../server/metrics/TaskCountStatsMonitor.java      |  2 +-
 .../server/metrics/TaskCountStatsMonitorTest.java  | 30 ++++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git 
a/server/src/main/java/org/apache/druid/server/metrics/TaskCountStatsMonitor.java
 
b/server/src/main/java/org/apache/druid/server/metrics/TaskCountStatsMonitor.java
index f6598c0e115..beafbb4d62b 100644
--- 
a/server/src/main/java/org/apache/druid/server/metrics/TaskCountStatsMonitor.java
+++ 
b/server/src/main/java/org/apache/druid/server/metrics/TaskCountStatsMonitor.java
@@ -67,9 +67,9 @@ public class TaskCountStatsMonitor extends AbstractMonitor
 
   private void emit(ServiceEmitter emitter, String key, Map<RowKey, Long> 
counts)
   {
-    final ServiceMetricEvent.Builder builder = new 
ServiceMetricEvent.Builder();
     if (counts != null) {
       counts.forEach((k, v) -> {
+        final ServiceMetricEvent.Builder builder = new 
ServiceMetricEvent.Builder();
         k.getValues().forEach((dim, value) -> 
builder.setDimension(dim.reportedName(), value));
         emitter.emit(builder.setMetric(key, v));
       });
diff --git 
a/server/src/test/java/org/apache/druid/server/metrics/TaskCountStatsMonitorTest.java
 
b/server/src/test/java/org/apache/druid/server/metrics/TaskCountStatsMonitorTest.java
index 03b8cef7007..33600b2bd60 100644
--- 
a/server/src/test/java/org/apache/druid/server/metrics/TaskCountStatsMonitorTest.java
+++ 
b/server/src/test/java/org/apache/druid/server/metrics/TaskCountStatsMonitorTest.java
@@ -20,6 +20,7 @@
 package org.apache.druid.server.metrics;
 
 import com.google.common.collect.ImmutableMap;
+import org.apache.druid.java.util.emitter.service.ServiceMetricEvent;
 import org.apache.druid.java.util.metrics.StubServiceEmitter;
 import org.apache.druid.server.coordinator.stats.CoordinatorRunStats;
 import org.apache.druid.server.coordinator.stats.CoordinatorStat;
@@ -28,7 +29,9 @@ import org.apache.druid.server.coordinator.stats.RowKey;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
 
+import java.util.List;
 import java.util.Map;
 
 public class TaskCountStatsMonitorTest
@@ -108,6 +111,33 @@ public class TaskCountStatsMonitorTest
     emitter.verifyValue(Stat.DEBUG_1.getMetricName(), Map.of("tier", "hot", 
"dataSource", "wiki"), 20L);
   }
 
+  @Test
+  public void testDimensionsDoNotLeakAcrossRows()
+  {
+    final RowKey streamingKey = RowKey.with(Dimension.DATASOURCE, "d1")
+                                      .with(Dimension.TASK_TYPE, "index_kafka")
+                                      .with(Dimension.SUPERVISOR_ID, "s1")
+                                      .build();
+    final TaskCountStatsProvider provider = 
Mockito.mock(TaskCountStatsProvider.class);
+    Mockito.when(provider.getRunningTaskCount())
+           .thenReturn(ImmutableMap.of(streamingKey, 3L, TASK_METRIC_KEY2, 1L, 
RowKey.empty(), 1L));
+
+    final StubServiceEmitter emitter = new StubServiceEmitter("service", 
"host");
+    new TaskCountStatsMonitor(provider).doMonitor(emitter);
+
+    Assertions.assertEquals(
+        List.of(
+            Map.of("dataSource", "d1", "taskType", "index_kafka", 
"supervisorId", "s1"),
+            Map.of("dataSource", "d1", "taskType", "kill"),
+            Map.of()
+        ),
+        emitter.getMetricEvents("task/running/count")
+               .stream()
+               .map(ServiceMetricEvent::getUserDims)
+               .toList()
+    );
+  }
+
   private static class Stat
   {
     static final CoordinatorStat INFO_1 = CoordinatorStat.toLogAndEmit("i1", 
"info/1", CoordinatorStat.Level.INFO);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to