diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/observation/AdvisorObservationDocumentation.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/observation/AdvisorObservationDocumentation.java index 310cd546558..3249304b415 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/observation/AdvisorObservationDocumentation.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/observation/AdvisorObservationDocumentation.java @@ -21,6 +21,8 @@ import io.micrometer.observation.ObservationConvention; import io.micrometer.observation.docs.ObservationDocumentation; +import org.springframework.ai.observation.conventions.AiObservationAttributes; + /** * AI Advisor observation documentation. * @@ -55,6 +57,26 @@ public KeyName[] getHighCardinalityKeyNames() { */ public enum LowCardinalityKeyNames implements KeyName { + /** + * The name of the operation being performed. + */ + AI_OPERATION_TYPE { + @Override + public String asString() { + return AiObservationAttributes.AI_OPERATION_TYPE.value(); + } + }, + + /** + * The model provider as identified by the client instrumentation. + */ + AI_PROVIDER { + @Override + public String asString() { + return AiObservationAttributes.AI_PROVIDER.value(); + } + }, + /** * Spring AI kind. */ diff --git a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/observation/DefaultAdvisorObservationConvention.java b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/observation/DefaultAdvisorObservationConvention.java index 9d8fd554983..edf07976d43 100644 --- a/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/observation/DefaultAdvisorObservationConvention.java +++ b/spring-ai-core/src/main/java/org/springframework/ai/chat/client/advisor/observation/DefaultAdvisorObservationConvention.java @@ -21,6 +21,8 @@ import org.springframework.ai.chat.client.advisor.observation.AdvisorObservationDocumentation.HighCardinalityKeyNames; import org.springframework.ai.chat.client.advisor.observation.AdvisorObservationDocumentation.LowCardinalityKeyNames; +import org.springframework.ai.observation.conventions.AiOperationType; +import org.springframework.ai.observation.conventions.AiProvider; import org.springframework.ai.observation.conventions.SpringAiKind; import org.springframework.ai.util.ParsingUtils; import org.springframework.lang.Nullable; @@ -64,7 +66,16 @@ public String getContextualName(AdvisorObservationContext context) { @Override public KeyValues getLowCardinalityKeyValues(AdvisorObservationContext context) { - return KeyValues.of(springAiKind(), advisorType(context), advisorName(context)); + return KeyValues.of(aiOperationType(context), aiProvider(context), springAiKind(), advisorType(context), + advisorName(context)); + } + + protected KeyValue aiOperationType(AdvisorObservationContext context) { + return KeyValue.of(LowCardinalityKeyNames.AI_OPERATION_TYPE, AiOperationType.FRAMEWORK.value()); + } + + protected KeyValue aiProvider(AdvisorObservationContext context) { + return KeyValue.of(LowCardinalityKeyNames.AI_PROVIDER, AiProvider.SPRING_AI.value()); } protected KeyValue advisorType(AdvisorObservationContext context) { diff --git a/spring-ai-core/src/test/java/org/springframework/ai/chat/client/advisor/observation/DefaultAdvisorObservationConventionTests.java b/spring-ai-core/src/test/java/org/springframework/ai/chat/client/advisor/observation/DefaultAdvisorObservationConventionTests.java index d1fe2c291bc..ee311d3df6e 100644 --- a/spring-ai-core/src/test/java/org/springframework/ai/chat/client/advisor/observation/DefaultAdvisorObservationConventionTests.java +++ b/spring-ai-core/src/test/java/org/springframework/ai/chat/client/advisor/observation/DefaultAdvisorObservationConventionTests.java @@ -22,6 +22,8 @@ import org.springframework.ai.chat.client.advisor.observation.AdvisorObservationDocumentation.HighCardinalityKeyNames; import org.springframework.ai.chat.client.advisor.observation.AdvisorObservationDocumentation.LowCardinalityKeyNames; +import org.springframework.ai.observation.conventions.AiOperationType; +import org.springframework.ai.observation.conventions.AiProvider; import org.springframework.ai.observation.conventions.SpringAiKind; import static org.assertj.core.api.Assertions.assertThat; @@ -69,6 +71,8 @@ void shouldHaveLowCardinalityKeyValuesWhenDefined() { assertThat(this.observationConvention.getLowCardinalityKeyValues(observationContext)).contains( KeyValue.of(LowCardinalityKeyNames.ADVISOR_TYPE.asString(), AdvisorObservationContext.Type.AROUND.name()), + KeyValue.of(LowCardinalityKeyNames.AI_OPERATION_TYPE.asString(), AiOperationType.FRAMEWORK.value()), + KeyValue.of(LowCardinalityKeyNames.AI_PROVIDER.asString(), AiProvider.SPRING_AI.value()), KeyValue.of(LowCardinalityKeyNames.ADVISOR_NAME.asString(), "MyName"), KeyValue.of(LowCardinalityKeyNames.SPRING_AI_KIND.asString(), SpringAiKind.ADVISOR.value())); }