Skip to content

Commit dc71187

Browse files
committed
Clean up OTel instrumentation
1 parent 4ec913b commit dc71187

File tree

8 files changed

+192
-203
lines changed

8 files changed

+192
-203
lines changed

src/api/Elastic.Documentation.Api.Core/AskAi/AskAiUsecase.cs

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,41 +16,26 @@ public class AskAiUsecase(
1616

1717
public async Task<Stream> AskAi(AskAiRequest askAiRequest, Cancel ctx)
1818
{
19-
// Start activity for the chat request - DO NOT use 'using' because the stream is consumed later
20-
// The activity will be passed to the transformer which will dispose it when the stream completes
21-
var activity = AskAiActivitySource.StartActivity("chat", ActivityKind.Client);
22-
23-
// Generate a correlation ID for tracking if this is a new conversation
24-
// For first messages (no ThreadId), generate a temporary ID that will be updated when the provider responds
25-
var correlationId = askAiRequest.ThreadId ?? $"temp-{Guid.NewGuid()}";
26-
27-
// Set GenAI semantic convention attributes
28-
_ = (activity?.SetTag("gen_ai.operation.name", "chat"));
29-
_ = (activity?.SetTag("gen_ai.conversation.id", correlationId)); // Will be updated when we receive ConversationStart with actual ID
30-
_ = (activity?.SetTag("gen_ai.usage.input_tokens", askAiRequest.Message.Length)); // Approximate token count
31-
32-
// Custom attributes for tracking our abstraction layer
33-
// We use custom attributes because we don't know the actual GenAI provider (OpenAI, Anthropic, etc.)
34-
// or model (gpt-4, claude, etc.) - those are abstracted by AgentBuilder/LlmGateway
35-
_ = (activity?.SetTag("docs.ai.gateway", streamTransformer.AgentProvider)); // agent-builder or llm-gateway
36-
_ = (activity?.SetTag("docs.ai.agent_name", streamTransformer.AgentId)); // docs-agent or docs_assistant
37-
38-
// Add GenAI prompt event
39-
_ = (activity?.AddEvent(new ActivityEvent("gen_ai.content.prompt",
40-
timestamp: DateTimeOffset.UtcNow,
41-
tags:
42-
[
43-
new KeyValuePair<string, object?>("gen_ai.prompt", askAiRequest.Message),
44-
new KeyValuePair<string, object?>("gen_ai.system_instructions", AskAiRequest.SystemPrompt)
45-
])));
46-
47-
logger.LogDebug("Processing AskAiRequest: {Request}", askAiRequest);
48-
19+
var activity = AskAiActivitySource.StartActivity($"chat", ActivityKind.Client);
20+
_ = activity?.SetTag("gen_ai.operation.name", "chat");
21+
_ = activity?.SetTag("gen_ai.provider.name", streamTransformer.AgentProvider); // agent-builder or llm-gateway
22+
_ = activity?.SetTag("gen_ai.agent.id", streamTransformer.AgentId); // docs-agent or docs_assistant
23+
var inputMessages = new object[]
24+
{
25+
new
26+
{
27+
role = "user",
28+
parts = new object[]
29+
{
30+
new { type = "text", content = askAiRequest.Message }
31+
}
32+
}
33+
};
34+
var inputMessagesJson = System.Text.Json.JsonSerializer.Serialize(inputMessages);
35+
_ = activity?.SetTag("gen_ai.input.messages", inputMessagesJson);
4936
var rawStream = await askAiGateway.AskAi(askAiRequest, ctx);
50-
5137
// The stream transformer will handle disposing the activity when streaming completes
5238
var transformedStream = await streamTransformer.TransformAsync(rawStream, activity, ctx);
53-
5439
return transformedStream;
5540
}
5641
}

src/api/Elastic.Documentation.Api.Infrastructure/Adapters/AskAi/LlmGatewayStreamTransformer.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ public class LlmGatewayStreamTransformer(ILogger<LlmGatewayStreamTransformer> lo
5656
"agent_end" =>
5757
new AskAiEvent.ConversationEnd(id, timestamp),
5858

59+
"error" => ParseErrorEvent(id, timestamp, messageData),
60+
5961
"chat_model_start" or "chat_model_end" =>
6062
null, // Skip model lifecycle events
6163

@@ -110,4 +112,18 @@ public class LlmGatewayStreamTransformer(ILogger<LlmGatewayStreamTransformer> lo
110112
Logger.LogWarning("Unknown LLM Gateway event type: {Type}", type);
111113
return null;
112114
}
115+
116+
private AskAiEvent.ErrorEvent ParseErrorEvent(string id, long timestamp, JsonElement messageData)
117+
{
118+
// LLM Gateway error format: {error: "...", message: "..."}
119+
var errorMessage = messageData.TryGetProperty("message", out var msgProp)
120+
? msgProp.GetString()
121+
: messageData.TryGetProperty("error", out var errProp)
122+
? errProp.GetString()
123+
: null;
124+
125+
Logger.LogError("Error event received from LLM Gateway: {ErrorMessage}", errorMessage ?? "Unknown error");
126+
127+
return new AskAiEvent.ErrorEvent(id, timestamp, errorMessage ?? "Unknown error occurred");
128+
}
113129
}

0 commit comments

Comments
 (0)