Skip to content

Commit 57f1059

Browse files
committed
Added percentiles and pool name to default micrometer metrics
1 parent b4a2d55 commit 57f1059

2 files changed

Lines changed: 38 additions & 18 deletions

File tree

src/main/java/com/uid2/operator/Main.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ private static Vertx createVertx() {
492492

493493
MicrometerMetricsOptions metricOptions = new MicrometerMetricsOptions()
494494
.setPrometheusOptions(prometheusOptions)
495-
.setLabels(EnumSet.of(Label.HTTP_METHOD, Label.HTTP_CODE, Label.HTTP_PATH))
495+
.setLabels(EnumSet.of(Label.HTTP_METHOD, Label.HTTP_CODE, Label.HTTP_PATH, Label.POOL_NAME))
496496
.setJvmMetricsEnabled(true)
497497
.setEnabled(true);
498498
setupMetrics(metricOptions);
@@ -529,6 +529,7 @@ private static void setupMetrics(MicrometerMetricsOptions metricOptions) {
529529
Objects.equals(id.getTag(Label.HTTP_CODE.toString()), "404")))
530530
.meterFilter(new MeterFilter() {
531531
private final String httpServerResponseTime = MetricsDomain.HTTP_SERVER.getPrefix() + MetricsNaming.v4Names().getHttpResponseTime();
532+
private final String poolQueueTime = MetricsDomain.HTTP_SERVER.getPrefix() + MetricsNaming.v4Names().getPoolQueueTime();
532533

533534
@Override
534535
public DistributionStatisticConfig configure(Meter.Id id, DistributionStatisticConfig config) {
@@ -538,6 +539,12 @@ public DistributionStatisticConfig configure(Meter.Id id, DistributionStatisticC
538539
.build()
539540
.merge(config);
540541
}
542+
if (id.getName().equals(poolQueueTime)) {
543+
return DistributionStatisticConfig.builder()
544+
.percentiles(0.50, 0.90, 0.95, 0.99)
545+
.build()
546+
.merge(config);
547+
}
541548
return config;
542549
}
543550
})

src/main/java/com/uid2/operator/service/ComputePoolService.java

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.time.Duration;
1313
import java.util.concurrent.Callable;
1414
import java.util.concurrent.TimeUnit;
15+
import java.util.concurrent.atomic.AtomicBoolean;
1516
import java.util.concurrent.atomic.AtomicLong;
1617

1718
public class ComputePoolService {
@@ -22,15 +23,15 @@ public class ComputePoolService {
2223

2324
private final WorkerExecutor workerExecutor;
2425

25-
// Queue length: incremented on queue, decremented on completion
26-
// since Vert.x worker executor doesn't expose queue length
27-
private final AtomicLong queueLength = new AtomicLong(0);
26+
// Queue pending: incremented on queue, decremented on dispatch
27+
// Tracks tasks waiting in queue but not yet started
28+
private final AtomicLong queuePending = new AtomicLong(0);
2829

2930
// Prometheus histogram for queue wait time (time between queued and dispatched)
3031
private final Timer queueWaitTimer;
3132

32-
// Prometheus gauge for queue length
33-
private final Gauge queueLengthGauge;
33+
// Prometheus gauge for queue pending
34+
private final Gauge queuePendingGauge;
3435

3536
/**
3637
* Creates a ComputePoolService with default pool size (available processors - 2, minimum 1).
@@ -58,8 +59,8 @@ public ComputePoolService(Vertx vertx, int poolSize) {
5859
.maximumExpectedValue(Duration.ofMillis(500)) // 500ms
5960
.register(Metrics.globalRegistry);
6061

61-
this.queueLengthGauge = Gauge.builder(METRIC_PREFIX + "queue_length", queueLength::get)
62-
.description("Number of tasks queued but not yet completed")
62+
this.queuePendingGauge = Gauge.builder(METRIC_PREFIX + "queue_pending", queuePending::get)
63+
.description("Number of tasks waiting in queue but not yet dispatched to a worker")
6364
.register(Metrics.globalRegistry);
6465

6566
LOGGER.info("ComputePoolService initialized with pool size: {}", poolSize);
@@ -76,18 +77,30 @@ public ComputePoolService(Vertx vertx, int poolSize) {
7677
*/
7778
public <T> Future<T> executeBlocking(Callable<T> callable) {
7879
final long queuedAt = System.nanoTime();
79-
queueLength.incrementAndGet();
80+
final AtomicBoolean dispatched = new AtomicBoolean(false);
81+
82+
queuePending.incrementAndGet();
83+
84+
try {
85+
return workerExecutor.<T>executeBlocking(() -> {
86+
dispatched.set(true);
87+
queuePending.decrementAndGet();
8088

81-
return workerExecutor.<T>executeBlocking(() -> {
82-
try {
8389
final long dispatchedAt = System.nanoTime();
8490
queueWaitTimer.record(dispatchedAt - queuedAt, TimeUnit.NANOSECONDS);
8591

8692
return callable.call();
87-
} finally {
88-
queueLength.decrementAndGet();
89-
}
90-
});
93+
}).onComplete(ar -> {
94+
// If task was never dispatched, clean up
95+
if (!dispatched.get()) {
96+
queuePending.decrementAndGet();
97+
}
98+
});
99+
} catch (Exception e) {
100+
// executeBlocking threw before returning a Future
101+
queuePending.decrementAndGet();
102+
return Future.failedFuture(e);
103+
}
91104
}
92105

93106
/**
@@ -105,10 +118,10 @@ public Future<Void> executeBlocking(Runnable runnable) {
105118

106119

107120
/**
108-
* Returns the current queue length (tasks queued but not yet completed).
121+
* Returns the number of tasks waiting in queue but not yet dispatched to a worker.
109122
*/
110-
public long getQueueLength() {
111-
return queueLength.get();
123+
public long getQueuePending() {
124+
return queuePending.get();
112125
}
113126

114127
public void close() {

0 commit comments

Comments
 (0)