fix: add span attributes for input messages in ChatModelPromptContentObservationHandler#6057
Conversation
|
@EvanYao826 Thanks for the PR. Looks like we may have crossed paths — I posted an analysis comment on the issue itself around the same time (my earlier issue comment: #6051 (comment)), so it seems we were working in parallel without seeing each other's work. Looking at that analysis side by side with this PR's diff, I'd like to share four things — three are concerns I think should be addressed before merge, and the last one is a scope question for the maintainers. 1. JSON escaping defectIn joiner.add("{\"role\":\"" + role + "\",\"content\":\"" + content + "\"}");When user input contains OTel-native backends could fail to parse this attribute as valid JSON. Since user input is essentially arbitrary text, this isn't a rare edge case but a predictable input pattern.
2. Optional
|
|
@jewoodev Thanks for the detailed analysis! You're right on all four points. Here's what I've changed: 1. JSON escaping — Replaced manual string concatenation with Jackson 2. micrometer-tracing classpath — Moved span tagging into a new 3. OTel content-capture opt-in — The span tagging now only activates when 4. Constants — Moved Regarding scope: I agree Pushed the updated commits. Looking forward to your feedback! |
|
@EvanYao826 Thanks for the update — the four fixes all look right from the commit message. Heads up that the new commit isn't reflected on this PR yet. The PR's head ref If you push (or cherry-pick) |
jewoodev
left a comment
There was a problem hiding this comment.
Was the output constant added intentionally for something here? I ask because I just opened #6193, the output-side counterpart, which actually consumes gen_ai.output.messages. If it indeed isn't used here, would you mind dropping OUTPUT_MESSAGES so it lives in the PR that consumes it? That keeps each constant added by the PR that uses it and avoids both PRs adding the same enum member.
| * The output messages received from the model, serialized as a JSON array following | ||
| * the OpenTelemetry GenAI semantic conventions. | ||
| */ | ||
| OUTPUT_MESSAGES("gen_ai.output.messages"), |
There was a problem hiding this comment.
Adds OUTPUT_MESSAGES to AiObservationAttributes but only uses INPUT_MESSAGES.
There was a problem hiding this comment.
Good catch — I've removed the unused OUTPUT_MESSAGES constant. Only INPUT_MESSAGES is referenced in this handler. Updated the PR accordingly.
…ObservationHandler The onStop() method only emitted prompt content to logs but did not set span attributes. This meant tracing systems had no visibility into the actual prompt content sent to the chat model. Add gen_ai.input.messages span tag in onStop() following OpenTelemetry GenAI semantic conventions. The tag is only set when a TracingContext with a non-null Span is present and the prompt is non-empty. Fixes spring-projects#6051 --- *AI-agent involvement: This contribution was assisted by an AI coding agent.* Signed-off-by: EvanYao826 <2869018789@qq.com> Signed-off-by: EvanYao826 <155432245+EvanYao826@users.noreply.github.com>
- Use Jackson ObjectMapper for JSON serialization instead of manual string concat - Move span tagging to separate ChatModelPromptSpanContentObservationHandler guarded by @ConditionalOnClass(Tracer.class) to avoid NoClassDefFoundError - Only capture gen_ai.input.messages when content-capture is explicitly opted in - Move INPUT_MESSAGES/OUTPUT_MESSAGES constants to AiObservationAttributes Signed-off-by: EvanYao826 <155432245+EvanYao826@users.noreply.github.com>
OUTPUT_MESSAGES was defined but never used in the codebase. Remove it to keep the API clean. Signed-off-by: EvanYao826 <155432245+EvanYao826@users.noreply.github.com>
dec47d3 to
838ea32
Compare
Remove accidentally committed local Maven repository path. Refs: spring-projects#6057
Fixes #6051
Problem
ChatModelPromptContentObservationHandler.onStop()emits prompt content to logs but does not set span attributes. Tracing systems have no visibility into the actual prompt content sent to the chat model.Fix
Add
gen_ai.input.messagesspan tag inonStop()following OpenTelemetry GenAI semantic conventions. The tag is only set when:TracingContextwith a non-nullSpanis presentChanges
ChatModelPromptContentObservationHandler.java: AddedsampleSpanTag()method that serializes messages as JSON array and sets span tagChatModelPromptContentObservationHandlerTests.java: Added 5 tests covering: span tag set with tracing context, no tag without tracing context, no tag with empty prompt, no tag with null span, single message tagAI-agent involvement: This contribution was assisted by an AI coding agent.