Skip to content

Commit 46a674a

Browse files
committed
feat: remove CR meters when they are deleted (after a delay)
Fixes #1803
1 parent 51a1c37 commit 46a674a

File tree

1 file changed

+30
-12
lines changed

1 file changed

+30
-12
lines changed

micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer/MicrometerMetrics.java

+30-12
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
package io.javaoperatorsdk.operator.monitoring.micrometer;
22

3-
import java.util.ArrayList;
4-
import java.util.Collections;
5-
import java.util.List;
6-
import java.util.Map;
7-
import java.util.Optional;
3+
import java.util.*;
84
import java.util.concurrent.ConcurrentHashMap;
5+
import java.util.concurrent.Executors;
6+
import java.util.concurrent.ScheduledExecutorService;
7+
import java.util.concurrent.TimeUnit;
98
import java.util.concurrent.atomic.AtomicInteger;
109

1110
import io.fabric8.kubernetes.api.model.HasMetadata;
@@ -17,6 +16,7 @@
1716
import io.javaoperatorsdk.operator.processing.GroupVersionKind;
1817
import io.javaoperatorsdk.operator.processing.event.Event;
1918
import io.javaoperatorsdk.operator.processing.event.ResourceID;
19+
import io.micrometer.core.instrument.Meter;
2020
import io.micrometer.core.instrument.MeterRegistry;
2121
import io.micrometer.core.instrument.Tag;
2222
import io.micrometer.core.instrument.Timer;
@@ -31,9 +31,17 @@ public class MicrometerMetrics implements Metrics {
3131
private static final String RECONCILIATIONS_QUEUE_SIZE = PREFIX + RECONCILIATIONS + "queue.size.";
3232
private final MeterRegistry registry;
3333
private final Map<String, AtomicInteger> gauges = new ConcurrentHashMap<>();
34+
private final Map<ResourceID, Set<Meter.Id>> metersPerResource = new ConcurrentHashMap<>();
35+
private final ScheduledExecutorService metersCleaner = Executors.newScheduledThreadPool(10);
36+
private final int cleanUpDelayInSeconds;
3437

3538
public MicrometerMetrics(MeterRegistry registry) {
39+
this(registry, 300);
40+
}
41+
42+
public MicrometerMetrics(MeterRegistry registry, int cleanUpDelayInSeconds) {
3643
this.registry = registry;
44+
this.cleanUpDelayInSeconds = cleanUpDelayInSeconds;
3745
}
3846

3947
@Override
@@ -116,6 +124,14 @@ public void receivedEvent(Event event, Map<String, Object> metadata) {
116124
@Override
117125
public void cleanupDoneFor(ResourceID resourceID, Map<String, Object> metadata) {
118126
incrementCounter(resourceID, "events.delete", metadata);
127+
128+
// schedule deletion of meters associated with ResourceID
129+
metersCleaner.schedule(() -> {
130+
final var toClean = metersPerResource.get(resourceID);
131+
if (toClean != null) {
132+
toClean.forEach(registry::remove);
133+
}
134+
}, cleanUpDelayInSeconds, TimeUnit.SECONDS);
119135
}
120136

121137
@Override
@@ -125,11 +141,11 @@ public void reconcileCustomResource(HasMetadata resource, RetryInfo retryInfoNul
125141
incrementCounter(ResourceID.fromResource(resource), RECONCILIATIONS + "started",
126142
metadata,
127143
RECONCILIATIONS + "retries.number",
128-
"" + retryInfo.map(RetryInfo::getAttemptCount).orElse(0),
144+
String.valueOf(retryInfo.map(RetryInfo::getAttemptCount).orElse(0)),
129145
RECONCILIATIONS + "retries.last",
130-
"" + retryInfo.map(RetryInfo::isLastAttempt).orElse(true));
146+
String.valueOf(retryInfo.map(RetryInfo::isLastAttempt).orElse(true)));
131147

132-
AtomicInteger controllerQueueSize =
148+
var controllerQueueSize =
133149
gauges.get(RECONCILIATIONS_QUEUE_SIZE + metadata.get(CONTROLLER_NAME));
134150
controllerQueueSize.incrementAndGet();
135151
}
@@ -141,18 +157,18 @@ public void finishedReconciliation(HasMetadata resource, Map<String, Object> met
141157

142158
@Override
143159
public void reconciliationExecutionStarted(HasMetadata resource, Map<String, Object> metadata) {
144-
AtomicInteger reconcilerExecutions =
160+
var reconcilerExecutions =
145161
gauges.get(RECONCILIATIONS_EXECUTIONS + metadata.get(CONTROLLER_NAME));
146162
reconcilerExecutions.incrementAndGet();
147163
}
148164

149165
@Override
150166
public void reconciliationExecutionFinished(HasMetadata resource, Map<String, Object> metadata) {
151-
AtomicInteger reconcilerExecutions =
167+
var reconcilerExecutions =
152168
gauges.get(RECONCILIATIONS_EXECUTIONS + metadata.get(CONTROLLER_NAME));
153169
reconcilerExecutions.decrementAndGet();
154170

155-
AtomicInteger controllerQueueSize =
171+
var controllerQueueSize =
156172
gauges.get(RECONCILIATIONS_QUEUE_SIZE + metadata.get(CONTROLLER_NAME));
157173
controllerQueueSize.decrementAndGet();
158174
}
@@ -202,6 +218,8 @@ private void incrementCounter(ResourceID id, String counterName, Map<String, Obj
202218
"version", gvk.version,
203219
"kind", gvk.kind));
204220
}
205-
registry.counter(PREFIX + counterName, tags.toArray(new String[0])).increment();
221+
final var counter = registry.counter(PREFIX + counterName, tags.toArray(new String[0]));
222+
metersPerResource.computeIfAbsent(id, resourceID -> new HashSet<>()).add(counter.getId());
223+
counter.increment();
206224
}
207225
}

0 commit comments

Comments
 (0)