Skip to content

Commit cb35f81

Browse files
committed
feat: also add metadata to receivedEvent, javadoc
1 parent dba05d8 commit cb35f81

File tree

4 files changed

+151
-14
lines changed

4 files changed

+151
-14
lines changed

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

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,18 @@ public <T> T timeControllerExecution(ControllerExecution<T> execution) {
3030
final var execName = PREFIX + "controllers.execution." + execution.name();
3131
final var resourceID = execution.resourceID();
3232
final var metadata = execution.metadata();
33+
final var tags = new ArrayList<String>(metadata.size() + 4);
34+
tags.addAll(List.of(
35+
"controller", name,
36+
"resource.name", resourceID.getName(),
37+
"resource.namespace", resourceID.getNamespace().orElse(""),
38+
"resource.scope", resourceID.getNamespace().isPresent() ? "namespace" : "cluster"));
39+
addReservedMetadataToTags(metadata, tags, "resource.group", Constants.RESOURCE_GROUP_KEY);
40+
addReservedMetadataToTags(metadata, tags, "resource.version", Constants.RESOURCE_VERSION_KEY);
41+
addReservedMetadataToTags(metadata, tags, "resource.kind", Constants.RESOURCE_KIND_KEY);
3342
final var timer =
3443
Timer.builder(execName)
35-
.tags(
36-
"controller", name,
37-
"resource.name", resourceID.getName(),
38-
"resource.namespace", resourceID.getNamespace().orElse(""),
39-
"resource.scope", resourceID.getNamespace().isPresent() ? "namespace" : "cluster",
40-
"resource.group", metadata.get(Constants.RESOURCE_GROUP_KEY).toString(),
41-
"resource.version", metadata.get(Constants.RESOURCE_VERSION_KEY).toString(),
42-
"resource.kind", metadata.get(Constants.RESOURCE_KIND_KEY).toString())
44+
.tags(tags.toArray(new String[0]))
4345
.publishPercentiles(0.3, 0.5, 0.95)
4446
.publishPercentileHistogram()
4547
.register(registry);
@@ -65,9 +67,9 @@ public <T> T timeControllerExecution(ControllerExecution<T> execution) {
6567
}
6668
}
6769

68-
public void receivedEvent(Event event) {
70+
public void receivedEvent(Event event, Map<String, Object> metadata) {
6971
incrementCounter(event.getRelatedCustomResourceID(), "events.received",
70-
Collections.emptyMap(),
72+
metadata,
7173
"event", event.getClass().getSimpleName());
7274
}
7375

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

Lines changed: 136 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,41 @@
33
import java.util.Collections;
44
import java.util.Map;
55

6+
import io.fabric8.kubernetes.api.model.HasMetadata;
7+
import io.javaoperatorsdk.operator.api.reconciler.Context;
68
import io.javaoperatorsdk.operator.api.reconciler.RetryInfo;
79
import io.javaoperatorsdk.operator.processing.event.Event;
810
import io.javaoperatorsdk.operator.processing.event.ResourceID;
911

12+
/**
13+
* An interface that metrics providers can implement and that the SDK will call at different times
14+
* of its execution cycle.
15+
*/
1016
public interface Metrics {
17+
18+
/**
19+
* The default Metrics provider: a no-operation implementation.
20+
*/
1121
Metrics NOOP = new Metrics() {};
1222

13-
default void receivedEvent(Event event) {}
23+
/**
24+
* Called when an event has been accepted by the SDK from an event source, which would result in
25+
* potentially triggering the associated Reconciler.
26+
*
27+
* @param event the event
28+
* @param metadata metadata associated with the resource being processed
29+
* @see io.javaoperatorsdk.operator.api.reconciler.Context#metadataFor(HasMetadata)
30+
*/
31+
default void receivedEvent(Event event, Map<String, Object> metadata) {}
32+
33+
/**
34+
*
35+
* @deprecated Use (and implement) {@link #receivedEvent(Event, Map)} instead
36+
*/
37+
@Deprecated
38+
default void receivedEvent(Event event) {
39+
receivedEvent(event, Collections.emptyMap());
40+
}
1441

1542
/**
1643
*
@@ -22,6 +49,14 @@ default void reconcileCustomResource(ResourceID resourceID, RetryInfo retryInfo)
2249
reconcileCustomResource(resourceID, retryInfo, Collections.emptyMap());
2350
}
2451

52+
/**
53+
* Called right before a resource is dispatched to the ExecutorService for reconciliation.
54+
*
55+
* @param resourceID the {@link ResourceID} associated with the resource
56+
* @param retryInfo the current retry state information for the reconciliation request
57+
* @param metadata metadata associated with the resource being processed
58+
* @see io.javaoperatorsdk.operator.api.reconciler.Context#metadataFor(HasMetadata)
59+
*/
2560
default void reconcileCustomResource(ResourceID resourceID, RetryInfo retryInfo,
2661
Map<String, Object> metadata) {}
2762

@@ -35,6 +70,16 @@ default void failedReconciliation(ResourceID resourceID, Exception exception) {
3570
failedReconciliation(resourceID, exception, Collections.emptyMap());
3671
}
3772

73+
/**
74+
* Called when a precedent reconciliation for the resource associated with the specified
75+
* {@link ResourceID} resulted in the provided exception, resulting in a retry of the
76+
* reconciliation.
77+
*
78+
* @param resourceID the {@link ResourceID} associated with the resource being processed
79+
* @param exception the exception that caused the failed reconciliation resulting in a retry
80+
* @param metadata metadata associated with the resource being processed
81+
* @see io.javaoperatorsdk.operator.api.reconciler.Context#metadataFor(HasMetadata)
82+
*/
3883
default void failedReconciliation(ResourceID resourceID, Exception exception,
3984
Map<String, Object> metadata) {}
4085

@@ -47,6 +92,14 @@ default void cleanupDoneFor(ResourceID resourceID) {
4792
cleanupDoneFor(resourceID, Collections.emptyMap());
4893
}
4994

95+
/**
96+
* Called when the resource associated with the specified {@link ResourceID} has been successfully
97+
* deleted and the clean-up performed by the associated reconciler is finished.
98+
*
99+
* @param resourceID the {@link ResourceID} associated with the resource being processed
100+
* @param metadata metadata associated with the resource being processed
101+
* @see io.javaoperatorsdk.operator.api.reconciler.Context#metadataFor(HasMetadata)
102+
*/
50103
default void cleanupDoneFor(ResourceID resourceID, Map<String, Object> metadata) {}
51104

52105
/**
@@ -58,27 +111,108 @@ default void finishedReconciliation(ResourceID resourceID) {
58111
finishedReconciliation(resourceID, Collections.emptyMap());
59112
}
60113

114+
/**
115+
* Called when the
116+
* {@link io.javaoperatorsdk.operator.api.reconciler.Reconciler#reconcile(HasMetadata, Context)}
117+
* method of the Reconciler associated with the resource associated with the specified
118+
* {@link ResourceID} has sucessfully finished.
119+
*
120+
* @param resourceID the {@link ResourceID} associated with the resource being processed
121+
* @param metadata metadata associated with the resource being processed
122+
* @see io.javaoperatorsdk.operator.api.reconciler.Context#metadataFor(HasMetadata)
123+
*/
61124
default void finishedReconciliation(ResourceID resourceID, Map<String, Object> metadata) {}
62125

63-
126+
/**
127+
* Encapsulates the information about a controller execution i.e. a call to either
128+
* {@link io.javaoperatorsdk.operator.api.reconciler.Reconciler#reconcile(HasMetadata, Context)}
129+
* or {@link io.javaoperatorsdk.operator.api.reconciler.Cleaner#cleanup(HasMetadata, Context)}.
130+
* Note that instances are automatically created for you by the SDK and passed to your Metrics
131+
* implementation at the appropriate time to the
132+
* {@link #timeControllerExecution(ControllerExecution)} method.
133+
*
134+
* @param <T> the outcome type associated with the controller execution. Currently, one of
135+
* {@link io.javaoperatorsdk.operator.api.reconciler.UpdateControl} or
136+
* {@link io.javaoperatorsdk.operator.api.reconciler.DeleteControl}
137+
*/
64138
interface ControllerExecution<T> {
139+
140+
/**
141+
* Retrieves the name of type of reconciliation being performed: either {@code reconcile} or
142+
* {@code cleanup}.
143+
*
144+
* @return the name of type of reconciliation being performed
145+
*/
65146
String name();
66147

148+
/**
149+
* Retrieves the name of the controller executing the reconciliation.
150+
*
151+
* @return the associated controller name
152+
*/
67153
String controllerName();
68154

155+
/**
156+
* Retrieves the name of the successful result when the reconciliation ended positively.
157+
* Possible values comes from the different outcomes provided by
158+
* {@link io.javaoperatorsdk.operator.api.reconciler.UpdateControl} or
159+
* {@link io.javaoperatorsdk.operator.api.reconciler.DeleteControl}.
160+
*
161+
* @param result the reconciliation result
162+
* @return a name associated with the specified outcome
163+
*/
69164
String successTypeName(T result);
70165

166+
/**
167+
* Retrieves the {@link ResourceID} of the resource associated with the controller execution
168+
* being considered
169+
*
170+
* @return the {@link ResourceID} of the resource being reconciled
171+
*/
71172
ResourceID resourceID();
72173

174+
/**
175+
* Retrieves metadata associated with the current reconciliation, typically additional
176+
* information (such as kind) about the resource being reconciled
177+
*
178+
* @return metadata associated with the current reconciliation
179+
*/
73180
Map<String, Object> metadata();
74181

182+
/**
183+
* Performs the controller execution.
184+
*
185+
* @return the result of the controller execution
186+
* @throws Exception if an error occurred during the controller's execution
187+
*/
75188
T execute() throws Exception;
76189
}
77190

191+
/**
192+
* Times the execution of the controller operation encapsulated by the provided
193+
* {@link ControllerExecution}.
194+
*
195+
* @param execution the controller operation to be timed
196+
* @return the result of the controller's execution if successful
197+
* @param <T> the type of the outcome/result of the controller's execution
198+
* @throws Exception if an error occurred during the controller's execution, usually this should
199+
* just be a pass-through of whatever the controller returned
200+
*/
78201
default <T> T timeControllerExecution(ControllerExecution<T> execution) throws Exception {
79202
return execution.execute();
80203
}
81204

205+
/**
206+
* Monitors the size of the specified map. This currently isn't used directly by the SDK but could
207+
* be used by operators to monitor some of their structures, such as cache size.
208+
*
209+
* @param map the Map which size is to be monitored
210+
* @param name the name of the provided Map to be used in metrics data
211+
* @return the Map that was passed in so the registration can be done as part of an assignment
212+
* statement.
213+
* @param <T> the type of the Map being monitored
214+
*/
215+
@SuppressWarnings("unused")
82216
default <T extends Map<?, ?>> T monitorSizeOf(T map, String name) {
83217
return map;
84218
}

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/api/reconciler/DefaultContext.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.javaoperatorsdk.operator.api.reconciler;
22

3+
import java.util.Collections;
34
import java.util.Map;
45
import java.util.Optional;
56
import java.util.Set;
@@ -28,7 +29,7 @@ public DefaultContext(RetryInfo retryInfo, Controller<P> controller, P primaryRe
2829
this.primaryResource = primaryResource;
2930
this.controllerConfiguration = controller.getConfiguration();
3031
this.defaultManagedDependentResourceContext = new DefaultManagedDependentResourceContext();
31-
this.metadata = metadata;
32+
this.metadata = metadata != null ? metadata : Collections.emptyMap();
3233
}
3334

3435
@Override

operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/event/EventProcessor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public synchronized void handleEvent(Event event) {
108108
final var resourceID = event.getRelatedCustomResourceID();
109109
final var state = resourceStateManager.getOrCreate(event.getRelatedCustomResourceID());
110110
MDCUtils.addResourceIDInfo(resourceID);
111-
metrics.receivedEvent(event);
111+
metrics.receivedEvent(event, state.immutableMetadata());
112112
handleEventMarking(event, state);
113113
if (!this.running) {
114114
// events are received and marked, but will be processed when started, see start() method.

0 commit comments

Comments
 (0)