Class: ClaudeAgentSDK::Instrumentation::OTelObserver
- Inherits:
-
Object
- Object
- ClaudeAgentSDK::Instrumentation::OTelObserver
- Includes:
- Observer
- Defined in:
- lib/claude_agent_sdk/instrumentation/otel.rb
Overview
OpenTelemetry observer that emits spans for Claude Agent SDK messages.
Uses standard gen_ai.* semantic conventions recognized by Langfuse, Datadog, Jaeger, and other OTel-compatible backends.
Requires the ‘opentelemetry-api` gem at runtime. Users must configure `opentelemetry-sdk` and an exporter (e.g., `opentelemetry-exporter-otlp`) themselves before creating this observer.
Constant Summary collapse
- TRACER_NAME =
'claude_agent_sdk'- MAX_ATTRIBUTE_LENGTH =
4096
Instance Method Summary collapse
-
#initialize(tracer_name: TRACER_NAME, **default_attributes) ⇒ OTelObserver
constructor
A new instance of OTelObserver.
- #on_close ⇒ Object
- #on_error(error) ⇒ Object
- #on_message(message) ⇒ Object
- #on_user_prompt(prompt) ⇒ Object
Constructor Details
#initialize(tracer_name: TRACER_NAME, **default_attributes) ⇒ OTelObserver
Returns a new instance of OTelObserver.
43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/claude_agent_sdk/instrumentation/otel.rb', line 43 def initialize(tracer_name: TRACER_NAME, **default_attributes) require 'opentelemetry' @tracer = OpenTelemetry.tracer_provider.tracer( tracer_name, defined?(ClaudeAgentSDK::VERSION) ? ClaudeAgentSDK::VERSION : '0.0.0' ) @default_attributes = default_attributes @root_span = nil @root_context = nil @tool_spans = {} # tool_use_id => span @first_user_input = nil # capture first user prompt for trace input @last_assistant_text = nil # capture last assistant text for trace output end |
Instance Method Details
#on_close ⇒ Object
91 92 93 94 95 96 97 |
# File 'lib/claude_agent_sdk/instrumentation/otel.rb', line 91 def on_close @tool_spans.each_value(&:finish) @tool_spans.clear @root_span&.finish @root_span = nil @root_context = nil end |
#on_error(error) ⇒ Object
84 85 86 87 88 89 |
# File 'lib/claude_agent_sdk/instrumentation/otel.rb', line 84 def on_error(error) return unless @root_span @root_span.record_exception(error) @root_span.status = OpenTelemetry::Trace::Status.error(error.) end |
#on_message(message) ⇒ Object
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/claude_agent_sdk/instrumentation/otel.rb', line 65 def () case when ClaudeAgentSDK::InitMessage start_trace() when ClaudeAgentSDK::AssistantMessage handle_assistant() when ClaudeAgentSDK::UserMessage handle_user() when ClaudeAgentSDK::ResultMessage end_trace() when ClaudeAgentSDK::APIRetryMessage record_retry_event() when ClaudeAgentSDK::RateLimitEvent record_rate_limit_event() when ClaudeAgentSDK::ToolProgressMessage record_tool_progress_event() end end |
#on_user_prompt(prompt) ⇒ Object
57 58 59 60 61 62 63 |
# File 'lib/claude_agent_sdk/instrumentation/otel.rb', line 57 def on_user_prompt(prompt) return if @first_user_input # only capture the first prompt @first_user_input = prompt.to_s # If root span already exists, set immediately; otherwise start_trace will apply it @root_span&.set_attribute('input.value', truncate(@first_user_input)) unless @first_user_input.empty? end |