Skip to content

Commit 28f5b3a

Browse files
committed
wip
Signed-off-by: Attila Mészáros <[email protected]>
1 parent 42ae61e commit 28f5b3a

File tree

3 files changed

+136
-70
lines changed
  • micrometer-support/src/main/java/io/javaoperatorsdk/operator/monitoring/micrometer
  • open-telemetry-support/src/main/java/io/javaoperatorsdk/operator/monitoring/opentelemetry
  • operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/monitoring

3 files changed

+136
-70
lines changed

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

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -26,34 +26,6 @@
2626

2727
public class MicrometerMetrics implements Metrics {
2828

29-
private static final String PREFIX = "operator.sdk.";
30-
private static final String RECONCILIATIONS = "reconciliations.";
31-
private static final String RECONCILIATIONS_FAILED = RECONCILIATIONS + "failed";
32-
private static final String RECONCILIATIONS_SUCCESS = RECONCILIATIONS + "success";
33-
private static final String RECONCILIATIONS_RETRIES_LAST = RECONCILIATIONS + "retries.last";
34-
private static final String RECONCILIATIONS_RETRIES_NUMBER = RECONCILIATIONS + "retries.number";
35-
private static final String RECONCILIATIONS_STARTED = RECONCILIATIONS + "started";
36-
private static final String RECONCILIATIONS_EXECUTIONS = PREFIX + RECONCILIATIONS + "executions.";
37-
private static final String RECONCILIATIONS_QUEUE_SIZE = PREFIX + RECONCILIATIONS + "queue.size.";
38-
private static final String NAME = "name";
39-
private static final String NAMESPACE = "namespace";
40-
private static final String GROUP = "group";
41-
private static final String VERSION = "version";
42-
private static final String KIND = "kind";
43-
private static final String SCOPE = "scope";
44-
private static final String METADATA_PREFIX = "resource.";
45-
private static final String CONTROLLERS_EXECUTION = "controllers.execution.";
46-
private static final String CONTROLLER = "controller";
47-
private static final String SUCCESS_SUFFIX = ".success";
48-
private static final String FAILURE_SUFFIX = ".failure";
49-
private static final String TYPE = "type";
50-
private static final String EXCEPTION = "exception";
51-
private static final String EVENT = "event";
52-
private static final String ACTION = "action";
53-
private static final String EVENTS_RECEIVED = "events.received";
54-
private static final String EVENTS_DELETE = "events.delete";
55-
private static final String CLUSTER = "cluster";
56-
private static final String SIZE_SUFFIX = ".size";
5729
private final boolean collectPerResourceMetrics;
5830
private final MeterRegistry registry;
5931
private final Map<String, AtomicInteger> gauges = new ConcurrentHashMap<>();
@@ -167,13 +139,13 @@ public <T> T timeControllerExecution(ControllerExecution<T> execution) {
167139

168140
@Override
169141
public void receivedEvent(Event event, Map<String, Object> metadata) {
170-
if (event instanceof ResourceEvent) {
142+
if (event instanceof ResourceEvent resourceEvent) {
171143
incrementCounter(
172144
event.getRelatedCustomResourceID(),
173145
EVENTS_RECEIVED,
174146
metadata,
175147
Tag.of(EVENT, event.getClass().getSimpleName()),
176-
Tag.of(ACTION, ((ResourceEvent) event).getAction().toString()));
148+
Tag.of(ACTION, resourceEvent.getAction().toString()));
177149
} else {
178150
incrementCounter(
179151
event.getRelatedCustomResourceID(),
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,128 @@
11
package io.javaoperatorsdk.operator.monitoring.opentelemetry;
22

3+
import java.util.HashMap;
4+
import java.util.Map;
5+
36
import io.fabric8.kubernetes.api.model.HasMetadata;
47
import io.javaoperatorsdk.operator.api.monitoring.Metrics;
8+
import io.javaoperatorsdk.operator.api.reconciler.Constants;
59
import io.javaoperatorsdk.operator.api.reconciler.RetryInfo;
610
import io.javaoperatorsdk.operator.processing.Controller;
11+
import io.javaoperatorsdk.operator.processing.GroupVersionKind;
712
import io.javaoperatorsdk.operator.processing.event.Event;
813
import io.javaoperatorsdk.operator.processing.event.ResourceID;
9-
10-
import java.util.Map;
14+
import io.javaoperatorsdk.operator.processing.event.source.controller.ResourceEvent;
15+
import io.opentelemetry.api.common.Attributes;
16+
import io.opentelemetry.api.metrics.Meter;
1117

1218
public class OpenTelemetryMetrics implements Metrics {
13-
14-
@Override
15-
public void controllerRegistered(Controller<? extends HasMetadata> controller) {
16-
Metrics.super.controllerRegistered(controller);
17-
}
1819

19-
@Override
20-
public void receivedEvent(Event event, Map<String, Object> metadata) {
21-
Metrics.super.receivedEvent(event, metadata);
22-
}
20+
private Meter meter;
21+
private final boolean collectPerResourceMetrics;
2322

24-
@Override
25-
public void reconcileCustomResource(HasMetadata resource, RetryInfo retryInfo, Map<String, Object> metadata) {
26-
Metrics.super.reconcileCustomResource(resource, retryInfo, metadata);
27-
}
23+
public OpenTelemetryMetrics(Meter meter, boolean collectPerResourceMetrics) {
24+
this.meter = meter;
25+
this.collectPerResourceMetrics = collectPerResourceMetrics;
26+
}
2827

29-
@Override
30-
public void failedReconciliation(HasMetadata resource, Exception exception, Map<String, Object> metadata) {
31-
Metrics.super.failedReconciliation(resource, exception, metadata);
32-
}
28+
@Override
29+
public void controllerRegistered(Controller<? extends HasMetadata> controller) {}
3330

34-
@Override
35-
public void reconciliationExecutionStarted(HasMetadata resource, Map<String, Object> metadata) {
36-
Metrics.super.reconciliationExecutionStarted(resource, metadata);
37-
}
31+
@Override
32+
public void receivedEvent(Event event, Map<String, Object> metadata) {
33+
if (event instanceof ResourceEvent) {
3834

39-
@Override
40-
public void reconciliationExecutionFinished(HasMetadata resource, Map<String, Object> metadata) {
41-
Metrics.super.reconciliationExecutionFinished(resource, metadata);
42-
}
35+
} else {
4336

44-
@Override
45-
public void cleanupDoneFor(ResourceID resourceID, Map<String, Object> metadata) {
46-
Metrics.super.cleanupDoneFor(resourceID, metadata);
4737
}
38+
}
4839

49-
@Override
50-
public void finishedReconciliation(HasMetadata resource, Map<String, Object> metadata) {
51-
Metrics.super.finishedReconciliation(resource, metadata);
52-
}
40+
@Override
41+
public void reconcileCustomResource(
42+
HasMetadata resource, RetryInfo retryInfo, Map<String, Object> metadata) {}
43+
44+
@Override
45+
public void failedReconciliation(
46+
HasMetadata resource, Exception exception, Map<String, Object> metadata) {}
47+
48+
@Override
49+
public void reconciliationExecutionStarted(HasMetadata resource, Map<String, Object> metadata) {}
50+
51+
@Override
52+
public void reconciliationExecutionFinished(HasMetadata resource, Map<String, Object> metadata) {}
5353

54-
@Override
55-
public <T> T timeControllerExecution(ControllerExecution<T> execution) throws Exception {
56-
return Metrics.super.timeControllerExecution(execution);
54+
@Override
55+
public void cleanupDoneFor(ResourceID resourceID, Map<String, Object> metadata) {}
56+
57+
@Override
58+
public void finishedReconciliation(HasMetadata resource, Map<String, Object> metadata) {}
59+
60+
@Override
61+
public <T> T timeControllerExecution(ControllerExecution<T> execution) throws Exception {
62+
return null;
63+
}
64+
65+
@Override
66+
public <T extends Map<?, ?>> T monitorSizeOf(T map, String name) {
67+
return null;
68+
}
69+
70+
private void incrementCounter(
71+
ResourceID id,
72+
String counterName,
73+
Map<String, Object> metadata,
74+
Map<String, String> additionalTags) {
75+
76+
meter.counterBuilder("").buildWithCallback(m -> {}).close();
77+
78+
Map<String, String> tags = new HashMap<>(additionalTags);
79+
addMetadataTags(id, metadata, tags, false);
80+
81+
var counter = meter.counterBuilder(PREFIX + counterName).build();
82+
var attributes = Attributes.builder();
83+
additionalTags.forEach(attributes::put);
84+
counter.add(1, attributes.build());
85+
}
86+
87+
private void addMetadataTags(
88+
ResourceID resourceID,
89+
Map<String, Object> metadata,
90+
Map<String, String> tags,
91+
boolean prefixed) {
92+
if (collectPerResourceMetrics) {
93+
addTag(NAME, resourceID.getName(), tags, prefixed);
94+
addTagOmittingOnEmptyValue(NAMESPACE, resourceID.getNamespace().orElse(null), tags, prefixed);
95+
}
96+
addTag(SCOPE, getScope(resourceID), tags, prefixed);
97+
final var gvk = (GroupVersionKind) metadata.get(Constants.RESOURCE_GVK_KEY);
98+
if (gvk != null) {
99+
addGVKTags(gvk, tags, prefixed);
57100
}
101+
}
102+
103+
private static void addTag(
104+
String name, String value, Map<String, String> tags, boolean prefixed) {
105+
tags.put(getPrefixedMetadataTag(name, prefixed), value);
106+
}
58107

59-
@Override
60-
public <T extends Map<?, ?>> T monitorSizeOf(T map, String name) {
61-
return Metrics.super.monitorSizeOf(map, name);
108+
private static void addGVKTags(GroupVersionKind gvk, Map<String, String> tags, boolean prefixed) {
109+
addTagOmittingOnEmptyValue(GROUP, gvk.getGroup(), tags, prefixed);
110+
addTag(VERSION, gvk.getVersion(), tags, prefixed);
111+
addTag(KIND, gvk.getKind(), tags, prefixed);
112+
}
113+
114+
private static String getPrefixedMetadataTag(String tagName, boolean prefixed) {
115+
return prefixed ? METADATA_PREFIX + tagName : tagName;
116+
}
117+
118+
private static void addTagOmittingOnEmptyValue(
119+
String name, String value, Map<String, String> tags, boolean prefixed) {
120+
if (value != null && !value.isBlank()) {
121+
addTag(name, value, tags, prefixed);
62122
}
123+
}
124+
125+
private static String getScope(ResourceID resourceID) {
126+
return resourceID.getNamespace().isPresent() ? NAMESPACE : CLUSTER;
127+
}
63128
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/monitoring/Metrics.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,35 @@
1515
*/
1616
public interface Metrics {
1717

18+
String PREFIX = "operator.sdk.";
19+
String RECONCILIATIONS = "reconciliations.";
20+
String RECONCILIATIONS_FAILED = RECONCILIATIONS + "failed";
21+
String RECONCILIATIONS_SUCCESS = RECONCILIATIONS + "success";
22+
String RECONCILIATIONS_RETRIES_LAST = RECONCILIATIONS + "retries.last";
23+
String RECONCILIATIONS_RETRIES_NUMBER = RECONCILIATIONS + "retries.number";
24+
String RECONCILIATIONS_STARTED = RECONCILIATIONS + "started";
25+
String RECONCILIATIONS_EXECUTIONS = PREFIX + RECONCILIATIONS + "executions.";
26+
String RECONCILIATIONS_QUEUE_SIZE = PREFIX + RECONCILIATIONS + "queue.size.";
27+
String NAME = "name";
28+
String NAMESPACE = "namespace";
29+
String GROUP = "group";
30+
String VERSION = "version";
31+
String KIND = "kind";
32+
String SCOPE = "scope";
33+
String METADATA_PREFIX = "resource.";
34+
String CONTROLLERS_EXECUTION = "controllers.execution.";
35+
String CONTROLLER = "controller";
36+
String SUCCESS_SUFFIX = ".success";
37+
String FAILURE_SUFFIX = ".failure";
38+
String TYPE = "type";
39+
String EXCEPTION = "exception";
40+
String EVENT = "event";
41+
String ACTION = "action";
42+
String EVENTS_RECEIVED = "events.received";
43+
String EVENTS_DELETE = "events.delete";
44+
String CLUSTER = "cluster";
45+
String SIZE_SUFFIX = ".size";
46+
1847
/** The default Metrics provider: a no-operation implementation. */
1948
Metrics NOOP = new Metrics() {};
2049

0 commit comments

Comments
 (0)