Skip to content

Commit 600c911

Browse files
committed
add observation
1 parent 6ac2231 commit 600c911

20 files changed

Lines changed: 415 additions & 10 deletions

File tree

core/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
<artifactId>jspecify</artifactId>
2929
<version>1.0.0</version>
3030
</dependency>
31+
<dependency>
32+
<groupId>io.micrometer</groupId>
33+
<artifactId>micrometer-observation</artifactId>
34+
</dependency>
3135
</dependencies>
3236

3337
</project>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
package com.javaaidev.agenticpatterns.core;
22

3+
import io.micrometer.observation.ObservationRegistry;
4+
import org.jspecify.annotations.Nullable;
35
import org.springframework.ai.chat.client.ChatClient;
46

57
public abstract class Agent {
68

79
protected final ChatClient chatClient;
10+
@Nullable
11+
protected final ObservationRegistry observationRegistry;
812

913
protected Agent(ChatClient chatClient) {
1014
this.chatClient = chatClient;
15+
this.observationRegistry = null;
16+
}
17+
18+
protected Agent(ChatClient chatClient, @Nullable ObservationRegistry observationRegistry) {
19+
this.chatClient = chatClient;
20+
this.observationRegistry = observationRegistry;
21+
}
22+
23+
protected String getName() {
24+
return this.getClass().getSimpleName();
1125
}
1226
}

core/src/main/java/com/javaaidev/agenticpatterns/core/AgentUtils.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.javaaidev.agenticpatterns.core;
22

3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import com.fasterxml.jackson.databind.SerializationFeature;
36
import java.io.IOException;
47
import java.nio.charset.StandardCharsets;
58
import java.util.HashMap;
@@ -11,6 +14,9 @@
1114

1215
public class AgentUtils {
1316

17+
private static final ObjectMapper objectMapper = new ObjectMapper().enable(
18+
SerializationFeature.INDENT_OUTPUT);
19+
1420
public static String loadPromptTemplateFromClasspath(String resource) {
1521
try {
1622
return new ClassPathResource(resource).getContentAsString(StandardCharsets.UTF_8);
@@ -34,4 +40,12 @@ public static Map<String, Object> mergeMap(@Nullable Map<String, Object> map1,
3440
public static <T, R> R safeGet(@Nullable T obj, Function<T, R> extractor, R defaultValue) {
3541
return Optional.ofNullable(obj).map(extractor).orElse(defaultValue);
3642
}
43+
44+
public static String toJson(Object input) {
45+
try {
46+
return objectMapper.writeValueAsString(input);
47+
} catch (JsonProcessingException e) {
48+
return "{}";
49+
}
50+
}
3751
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.javaaidev.agenticpatterns.core.observation;
2+
3+
import io.micrometer.observation.transport.RequestReplySenderContext;
4+
5+
public class AgentExecutionObservationContext extends RequestReplySenderContext<Object, Object> {
6+
7+
private final String agentName;
8+
9+
public AgentExecutionObservationContext(
10+
String agentName, Object input) {
11+
super((carrier, key, value) -> {
12+
13+
});
14+
this.agentName = agentName;
15+
setCarrier(input);
16+
}
17+
18+
public String getAgentName() {
19+
return agentName;
20+
}
21+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.javaaidev.agenticpatterns.core.observation;
2+
3+
import io.micrometer.observation.Observation.Context;
4+
import io.micrometer.observation.ObservationConvention;
5+
6+
public interface AgentExecutionObservationConvention extends
7+
ObservationConvention<AgentExecutionObservationContext> {
8+
9+
@Override
10+
default boolean supportsContext(Context context) {
11+
return context instanceof AgentExecutionObservationContext;
12+
}
13+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.javaaidev.agenticpatterns.core.observation;
2+
3+
import io.micrometer.common.docs.KeyName;
4+
import io.micrometer.observation.Observation.Context;
5+
import io.micrometer.observation.ObservationConvention;
6+
import io.micrometer.observation.docs.ObservationDocumentation;
7+
8+
public enum AgentExecutionObservationDocumentation implements ObservationDocumentation {
9+
AGENT_EXECUTION {
10+
@Override
11+
public Class<? extends ObservationConvention<? extends Context>> getDefaultConvention() {
12+
return DefaultAgentExecutionObservationConvention.class;
13+
}
14+
15+
@Override
16+
public KeyName[] getLowCardinalityKeyNames() {
17+
return LowCardinalityKeyNames.values();
18+
}
19+
20+
@Override
21+
public KeyName[] getHighCardinalityKeyNames() {
22+
return HighCardinalityKeyNames.values();
23+
}
24+
};
25+
26+
public enum LowCardinalityKeyNames implements KeyName {
27+
AGENT_NAME {
28+
@Override
29+
public String asString() {
30+
return "agent.name";
31+
}
32+
}
33+
}
34+
35+
public enum HighCardinalityKeyNames implements KeyName {
36+
AGENT_EXECUTION_INPUT {
37+
@Override
38+
public String asString() {
39+
return "agent.execution.input";
40+
}
41+
},
42+
43+
AGENT_EXECUTION_OUTPUT {
44+
@Override
45+
public String asString() {
46+
return "agent.execution.output";
47+
}
48+
}
49+
}
50+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.javaaidev.agenticpatterns.core.observation;
2+
3+
import com.javaaidev.agenticpatterns.core.AgentUtils;
4+
import com.javaaidev.agenticpatterns.core.observation.AgentExecutionObservationDocumentation.HighCardinalityKeyNames;
5+
import com.javaaidev.agenticpatterns.core.observation.AgentExecutionObservationDocumentation.LowCardinalityKeyNames;
6+
import io.micrometer.common.KeyValue;
7+
import io.micrometer.common.KeyValues;
8+
9+
public class DefaultAgentExecutionObservationConvention implements
10+
AgentExecutionObservationConvention {
11+
12+
private String defaultName = "agent.execute";
13+
14+
15+
@Override
16+
public String getName() {
17+
return defaultName;
18+
}
19+
20+
@Override
21+
public KeyValues getLowCardinalityKeyValues(AgentExecutionObservationContext context) {
22+
return KeyValues.of(agentName(context));
23+
}
24+
25+
@Override
26+
public KeyValues getHighCardinalityKeyValues(AgentExecutionObservationContext context) {
27+
return KeyValues.of(
28+
agentExecutionInput(context),
29+
agentExecutionOutput(context)
30+
);
31+
}
32+
33+
private KeyValue agentName(AgentExecutionObservationContext context) {
34+
return KeyValue.of(
35+
LowCardinalityKeyNames.AGENT_NAME, context.getAgentName()
36+
);
37+
}
38+
39+
private KeyValue agentExecutionInput(AgentExecutionObservationContext context) {
40+
return KeyValue.of(
41+
HighCardinalityKeyNames.AGENT_EXECUTION_INPUT,
42+
context.getCarrier() != null ? AgentUtils.toJson(context.getCarrier()) : KeyValue.NONE_VALUE
43+
);
44+
}
45+
46+
private KeyValue agentExecutionOutput(AgentExecutionObservationContext context) {
47+
return KeyValue.of(
48+
HighCardinalityKeyNames.AGENT_EXECUTION_OUTPUT,
49+
context.getResponse() != null ? AgentUtils.toJson(context.getResponse())
50+
: KeyValue.NONE_VALUE
51+
);
52+
}
53+
54+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
tempo-data/
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
apiVersion: 1
2+
3+
datasources:
4+
- name: Prometheus
5+
type: prometheus
6+
uid: prometheus
7+
access: proxy
8+
orgId: 1
9+
url: http://prometheus:9090
10+
basicAuth: false
11+
isDefault: false
12+
version: 1
13+
editable: false
14+
jsonData:
15+
httpMethod: GET
16+
- name: Tempo
17+
type: tempo
18+
access: proxy
19+
orgId: 1
20+
url: http://tempo:3200
21+
basicAuth: false
22+
isDefault: true
23+
version: 1
24+
editable: false
25+
apiVersion: 1
26+
uid: tempo
27+
jsonData:
28+
httpMethod: GET
29+
serviceMap:
30+
datasourceUid: prometheus
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
receivers:
2+
otlp:
3+
protocols:
4+
grpc:
5+
http:
6+
exporters:
7+
otlp:
8+
endpoint: tempo:4317
9+
tls:
10+
insecure: true
11+
service:
12+
pipelines:
13+
traces:
14+
receivers: [ otlp ]
15+
exporters: [ otlp ]

0 commit comments

Comments
 (0)