Class: ActiveAgent::TelemetryTrace
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- ActiveAgent::TelemetryTrace
- Defined in:
- lib/active_agent/dashboard/app/models/active_agent/telemetry_trace.rb
Overview
Stores telemetry traces from ActiveAgent clients.
Each trace represents a complete generation lifecycle, including prompt preparation, LLM calls, tool invocations, and error handling.
This model supports two modes:
-
Local mode: No account association (single-tenant, self-hosted)
-
Multi-tenant mode: With account association (for activeagents.ai platform)
Constant Summary collapse
- STATUS_OK =
Status values for traces
"OK"- STATUS_ERROR =
"ERROR"- STATUS_UNSET =
"UNSET"
Class Method Summary collapse
-
.create_from_payload(trace, sdk_info = {}, account: nil) ⇒ TelemetryTrace
Creates a TelemetryTrace from an ingested trace payload.
Instance Method Summary collapse
-
#display_name ⇒ String
Returns display name for the trace.
-
#error? ⇒ Boolean
Returns whether this trace had an error.
-
#formatted_duration ⇒ String
Returns formatted duration.
-
#formatted_tokens ⇒ String
Returns formatted token count.
-
#llm_spans ⇒ Array<Hash>
Returns all LLM spans in this trace.
-
#model ⇒ String?
Returns the model used (from LLM spans).
-
#provider ⇒ String?
Returns the provider used (from LLM spans).
-
#root_span ⇒ Hash?
Returns the root span of this trace.
-
#tool_spans ⇒ Array<Hash>
Returns all tool call spans in this trace.
-
#total_tokens ⇒ Integer
Returns total token count.
Class Method Details
.create_from_payload(trace, sdk_info = {}, account: nil) ⇒ TelemetryTrace
Creates a TelemetryTrace from an ingested trace payload.
Extracts relevant data from the trace payload and stores it in a normalized format for querying and analysis.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/active_agent/dashboard/app/models/active_agent/telemetry_trace.rb', line 53 def self.create_from_payload(trace, sdk_info = {}, account: nil) spans = trace["spans"] || [] root_span = spans.find { |s| s["parent_span_id"].nil? } || spans.first || {} # Calculate totals from all spans total_duration = root_span["duration_ms"] total_input = 0 total_output = 0 total_thinking = 0 spans.each do |span| tokens = span["tokens"] || {} total_input += (tokens["input"] || 0) total_output += (tokens["output"] || 0) total_thinking += (tokens["thinking"] || 0) end # Extract agent info from root span attributes attributes = root_span["attributes"] || {} agent_class = attributes["agent.class"] agent_action = attributes["agent.action"] # Find any error message error_span = spans.find { |s| s["status"] == STATUS_ERROR } = error_span&.dig("attributes", "error.message") attrs = { trace_id: trace["trace_id"], service_name: trace["service_name"], environment: trace["environment"], timestamp: Time.parse(trace["timestamp"]), spans: spans, resource_attributes: trace["resource_attributes"], sdk_info: sdk_info, total_duration_ms: total_duration, total_input_tokens: total_input, total_output_tokens: total_output, total_thinking_tokens: total_thinking, status: root_span["status"] || STATUS_UNSET, agent_class: agent_class, agent_action: agent_action, error_message: } # Add account if in multi-tenant mode attrs[:account] = account if ActiveAgent::Dashboard.multi_tenant? && account create!(attrs) end |
Instance Method Details
#display_name ⇒ String
Returns display name for the trace.
141 142 143 144 145 146 147 148 149 |
# File 'lib/active_agent/dashboard/app/models/active_agent/telemetry_trace.rb', line 141 def display_name if agent_class && agent_action "#{agent_class}.#{agent_action}" elsif agent_class agent_class else trace_id&.first(8) end end |
#error? ⇒ Boolean
Returns whether this trace had an error.
134 135 136 |
# File 'lib/active_agent/dashboard/app/models/active_agent/telemetry_trace.rb', line 134 def error? status == STATUS_ERROR end |
#formatted_duration ⇒ String
Returns formatted duration.
154 155 156 157 158 159 160 161 162 |
# File 'lib/active_agent/dashboard/app/models/active_agent/telemetry_trace.rb', line 154 def formatted_duration return "—" unless total_duration_ms if total_duration_ms >= 1000 "#{(total_duration_ms / 1000.0).round(2)}s" else "#{total_duration_ms.round(0)}ms" end end |
#formatted_tokens ⇒ String
Returns formatted token count.
167 168 169 170 171 172 173 174 175 176 |
# File 'lib/active_agent/dashboard/app/models/active_agent/telemetry_trace.rb', line 167 def formatted_tokens count = total_tokens return "0" if count.zero? if count >= 1000 "#{(count / 1000.0).round(1)}K" else count.to_s end end |
#llm_spans ⇒ Array<Hash>
Returns all LLM spans in this trace.
113 114 115 |
# File 'lib/active_agent/dashboard/app/models/active_agent/telemetry_trace.rb', line 113 def llm_spans spans&.select { |s| s["type"] == "llm" } || [] end |
#model ⇒ String?
Returns the model used (from LLM spans).
191 192 193 194 195 196 |
# File 'lib/active_agent/dashboard/app/models/active_agent/telemetry_trace.rb', line 191 def model llm_span = llm_spans.first return nil unless llm_span llm_span.dig("attributes", "llm.model") end |
#provider ⇒ String?
Returns the provider used (from LLM spans).
181 182 183 184 185 186 |
# File 'lib/active_agent/dashboard/app/models/active_agent/telemetry_trace.rb', line 181 def provider llm_span = llm_spans.first return nil unless llm_span llm_span.dig("attributes", "llm.provider") end |
#root_span ⇒ Hash?
Returns the root span of this trace.
106 107 108 |
# File 'lib/active_agent/dashboard/app/models/active_agent/telemetry_trace.rb', line 106 def root_span spans&.find { |s| s["parent_span_id"].nil? } end |
#tool_spans ⇒ Array<Hash>
Returns all tool call spans in this trace.
120 121 122 |
# File 'lib/active_agent/dashboard/app/models/active_agent/telemetry_trace.rb', line 120 def tool_spans spans&.select { |s| s["type"] == "tool" } || [] end |
#total_tokens ⇒ Integer
Returns total token count.
127 128 129 |
# File 'lib/active_agent/dashboard/app/models/active_agent/telemetry_trace.rb', line 127 def total_tokens (total_input_tokens || 0) + (total_output_tokens || 0) + (total_thinking_tokens || 0) end |