ask-opentelemetry 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 725e08edb09468eeddf352695a9683197d245f385783aa6b527f52bd29243ec3
4
- data.tar.gz: 875068867c33e9d45a1e442875dcc3d7e487e345b74fe9f15104ab564813475a
3
+ metadata.gz: 8a559471a836955c42ed5be1518e1170dcb328aaac0de21500f40154e9df885c
4
+ data.tar.gz: 63d774f21be7b6cc3db2ab8030e68869ffa4ef93c8d91899000009a4bcceeb93
5
5
  SHA512:
6
- metadata.gz: 2b0d3a3c347fd6301e1f5e8b6c61da18fe78cd925eadd32bd3a060aea02099d84c91a8ccb4bdc64aee8aae7570b63c712e5ffdbc5c83b69acb6ca7970f3c6e06
7
- data.tar.gz: 2ff2cceaa569cfc8e70f7d5f03589ffdb3f97c8593d77e11ccd3616d3481cbf493fa3db03ef802ed5bb16675090c536d6fb229adc69669c2b6d1f9658ee43dd7
6
+ metadata.gz: de08a12ab4339fd888dee358fc38def836e44037d8530489ab041829976df25ef96fa60881c4023cafd82545ac84671ce9105a225075fb04117e04f963ada3fd
7
+ data.tar.gz: 89f1e1816a5cc13df01f77ecfb740d6d0c0687818e61873c582c37a7e2879398e4f3c4d3e6ea13982eb868688e9bbc093a5fad317eb20824fa714993a92b13a3
data/CHANGELOG.md CHANGED
@@ -1,6 +1,19 @@
1
+ ## [0.1.2] - 2026-08-06
2
+
3
+ ### Fixed
4
+ - `llm.input_tokens`/`llm.output_tokens` span attributes read from the nested
5
+ `usage` payload hash (ask-agent enriches it after the call returns; the
6
+ instrumenter shallow-copies the top-level payload). Top-level keys still
7
+ work for other emitters. `llm.duration_ms` now reflects the real LLM call
8
+ duration thanks to the ask-agent event fix.
9
+
10
+ ## [0.1.1] - 2026-06-25
11
+
12
+ ### Changed
13
+ - Railtie test (3 tests), subscriber install idempotency. Infrastructure: rubocop, overcommit, bin/setup, CI matrix, gemspec test.
1
14
  # Changelog
2
15
 
3
- ## [0.1.0] - Unreleased
16
+ ## [0.1.0] - 2026-06-21
4
17
 
5
18
  ### Added
6
19
  - Initial release
data/README.md CHANGED
@@ -5,10 +5,10 @@
5
5
 
6
6
  OpenTelemetry tracing for the ask-rb ecosystem. Subscribes to
7
7
  `ask-instrumentation` events and creates OpenTelemetry spans for chat
8
- completions, tool calls, embeddings, and image generation.
9
-
10
- Works with any OpenTelemetry-compatible backend: Langfuse, Datadog, Honeycomb,
11
- Jaeger, Arize Phoenix, and more.
8
+ completions, tool calls, embeddings, and image generation. Backend-agnostic:
9
+ the exporter is configured with the standard OpenTelemetry SDK, so spans go
10
+ to any OpenTelemetry-compatible backend (Langfuse, Datadog, Honeycomb, Jaeger,
11
+ Arize Phoenix, and more).
12
12
 
13
13
  ## Installation
14
14
 
@@ -22,66 +22,37 @@ gem "ask-instrumentation"
22
22
  ```ruby
23
23
  require "ask/open_telemetry"
24
24
 
25
- # Subscribe to all ask events and create OpenTelemetry spans
26
25
  Ask::OpenTelemetry.install
27
26
  ```
28
27
 
29
- ### In Rails
28
+ That's it. Every `Ask::Instrumentation` event is now wrapped in a span. The
29
+ call is idempotent; subsequent calls are no-ops.
30
30
 
31
- The Railtie auto-installs no manual setup required:
32
-
33
- ```ruby
34
- # Gemfile
35
- gem "ask-opentelemetry"
36
- gem "ask-instrumentation"
37
- ```
38
-
39
- That's it. Spans are created automatically for every LLM operation.
31
+ In a Rails app, the Railtie calls `Ask::OpenTelemetry.install` automatically:
32
+ no manual setup required.
40
33
 
41
34
  ## Spans Created
42
35
 
43
- | Event | Span Name | Key Attributes |
44
- |---|---|---|
45
- | `chat.ask` | `llm.chat` | provider, model, input_tokens, output_tokens, duration_ms |
46
- | `chat.stream.ask` | `llm.chat` | provider, model, input_tokens, output_tokens, duration_ms |
47
- | `tool.ask` | `llm.tool` | provider, tool, tool_args |
48
- | `embedding.ask` | `llm.embedding` | provider, model, input_tokens |
49
- | `image.ask` | `llm.image` | provider, model, image.size, duration_ms |
50
-
51
- ### Standard Attributes
52
-
53
- All spans include:
36
+ | Event | Span |
37
+ |---|---|
38
+ | `chat.ask`, `chat.stream.ask` | `llm.chat` |
39
+ | `tool.ask` | `llm.tool` |
40
+ | `embedding.ask` | `llm.embedding` |
41
+ | `image.ask` | `llm.image` |
54
42
 
55
- - `llm.provider` The LLM provider (e.g., `openai`, `anthropic`)
56
- - `llm.model` — The model identifier (e.g., `gpt-4`, `claude-3`)
57
- - `llm.duration_ms` The duration of the LLM operation in milliseconds
58
- - `llm.input_tokens` Input token count (when available)
59
- - `llm.output_tokens` — Output token count (when available)
43
+ Span attributes use the `llm.*` namespace: `llm.provider`, `llm.model`,
44
+ `llm.input_tokens`, `llm.output_tokens`, `llm.duration_ms`, `llm.tool`,
45
+ `llm.tool_args`, and `llm.image.size` when present. Any context set via
46
+ `Ask::Instrumentation.with_metadata` is forwarded as `llm.metadata.*`
47
+ attributes.
60
48
 
61
- ### Metadata Attributes
49
+ ## Configuration
62
50
 
63
- Any context set via `Ask::Instrumentation.with_metadata` is forwarded as
64
- `llm.metadata.*` attributes:
51
+ `Ask::OpenTelemetry.install` is the entire public API; there is no exporter
52
+ configuration on the gem itself. Configure the exporter once with the standard
53
+ OpenTelemetry SDK before calling `install`:
65
54
 
66
55
  ```ruby
67
- Ask::Instrumentation.with_metadata(user_id: 42, session_id: "abc") do
68
- # The resulting span has:
69
- # llm.metadata.user_id = 42
70
- # llm.metadata.session_id = "abc"
71
- end
72
- ```
73
-
74
- ## Backend Examples
75
-
76
- ### Langfuse
77
-
78
- [Langfuse](https://langfuse.com) provides LLM observability (cost tracking,
79
- evaluations, prompt management) via OpenTelemetry.
80
-
81
- **Using Langfuse Cloud:**
82
-
83
- ```ruby
84
- require "ask/open_telemetry"
85
56
  require "opentelemetry-sdk"
86
57
  require "opentelemetry-exporter-otlp"
87
58
 
@@ -89,12 +60,7 @@ OpenTelemetry::SDK.configure do |c|
89
60
  c.service_name = "my-app"
90
61
  c.add_span_processor(
91
62
  OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
92
- OpenTelemetry::Exporter::OTLP::Exporter.new(
93
- endpoint: "https://cloud.langfuse.com/api/public/otel/v1/traces",
94
- headers: {
95
- "Authorization" => "Basic #{Base64.strict_encode64("#{LANGFUSE_PUBLIC_KEY}:#{LANGFUSE_SECRET_KEY}")}"
96
- }
97
- )
63
+ OpenTelemetry::Exporter::OTLP::Exporter.new(endpoint: "https://otlp.example.com")
98
64
  )
99
65
  )
100
66
  end
@@ -102,87 +68,17 @@ end
102
68
  Ask::OpenTelemetry.install
103
69
  ```
104
70
 
105
- **Using Langfuse Self-Hosted:**
71
+ ## Full documentation
106
72
 
107
- ```ruby
108
- OpenTelemetry::SDK.configure do |c|
109
- c.service_name = "my-app"
110
- c.add_span_processor(
111
- OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
112
- OpenTelemetry::Exporter::OTLP::Exporter.new(
113
- endpoint: "https://your-instance.langfuse.com/api/public/otel/v1/traces",
114
- headers: {
115
- "Authorization" => "Basic #{Base64.strict_encode64("#{LANGFUSE_PUBLIC_KEY}:#{LANGFUSE_SECRET_KEY}")}"
116
- }
117
- )
118
- )
119
- )
120
- end
121
- ```
122
-
123
- ### Datadog
124
-
125
- ```ruby
126
- require "ask/open_telemetry"
127
- require "opentelemetry-sdk"
128
- require "opentelemetry-exporter-otlp"
129
-
130
- OpenTelemetry::SDK.configure do |c|
131
- c.service_name = "my-app"
132
- c.add_span_processor(
133
- OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
134
- OpenTelemetry::Exporter::OTLP::Exporter.new(
135
- endpoint: "https://otlp.datadoghq.com",
136
- headers: { "DD-API-KEY" => ENV["DD_API_KEY"] }
137
- )
138
- )
139
- )
140
- end
141
-
142
- Ask::OpenTelemetry.install
143
- ```
144
-
145
- ### Honeycomb
146
-
147
- ```ruby
148
- require "ask/open_telemetry"
149
- require "opentelemetry-sdk"
150
- require "opentelemetry-exporter-otlp"
151
-
152
- OpenTelemetry::SDK.configure do |c|
153
- c.service_name = "my-app"
154
- c.add_span_processor(
155
- OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
156
- OpenTelemetry::Exporter::OTLP::Exporter.new(
157
- endpoint: "https://api.honeycomb.io:443",
158
- headers: { "x-honeycomb-team" => ENV["HONEYCOMB_API_KEY"] }
159
- )
160
- )
161
- )
162
- end
163
-
164
- Ask::OpenTelemetry.install
165
- ```
166
-
167
- ## API
168
-
169
- ### `.install`
170
-
171
- Subscribe to all `.ask` events and start creating spans. Idempotent — calling
172
- multiple times only subscribes once.
173
-
174
- ```ruby
175
- Ask::OpenTelemetry.install
176
- ```
73
+ The full ask-rb documentation lives at https://ask-rb.github.io/ask-docs.
74
+ https://ask-rb.github.io/ask-docs/production/opentelemetry covers
75
+ ask-opentelemetry in depth, including per-backend setup examples. API
76
+ reference: https://ask-rb.github.io/ask-docs/reference/api.
177
77
 
178
78
  ## Development
179
79
 
180
- ```bash
181
- git clone https://github.com/ask-rb/ask-opentelemetry.git
182
- cd ask-opentelemetry
183
80
  bundle install
184
81
  bundle exec rake test
185
- ```
186
82
 
187
83
  ## License
188
84
 
@@ -44,9 +44,12 @@ module Ask
44
44
  attrs["llm.provider"] = payload[:provider] if payload[:provider]
45
45
  attrs["llm.model"] = payload[:model] if payload[:model]
46
46
 
47
- # Token tracking (when available)
48
- attrs["llm.input_tokens"] = payload[:input_tokens] if payload[:input_tokens]
49
- attrs["llm.output_tokens"] = payload[:output_tokens] if payload[:output_tokens]
47
+ # Token tracking (when available). Chat events emitted by ask-agent
48
+ # enrich a shared nested +usage+ hash after the call returns (tokens
49
+ # are only known then); other emitters pass them at the top level.
50
+ usage = payload[:usage] || payload
51
+ attrs["llm.input_tokens"] = usage[:input_tokens] if usage[:input_tokens]
52
+ attrs["llm.output_tokens"] = usage[:output_tokens] if usage[:output_tokens]
50
53
 
51
54
  # Tool-specific
52
55
  attrs["llm.tool"] = payload[:tool_name] if payload[:tool_name]
@@ -1,5 +1,5 @@
1
1
  module Ask
2
2
  module OpenTelemetry
3
- VERSION = "0.1.0"
3
+ VERSION = "0.1.2"
4
4
  end
5
5
  end
@@ -2,6 +2,11 @@ require "ask/instrumentation"
2
2
  require "opentelemetry-api"
3
3
  require_relative "open_telemetry/version"
4
4
 
5
+ # Rails discovers gem railties only when they are required, so load the
6
+ # railtie from the entry file once Rails itself is on the stack (the
7
+ # documented pattern: "require my_gem/railtie if defined?(Rails::Railtie)").
8
+ require_relative "open_telemetry/railtie" if defined?(Rails::Railtie)
9
+
5
10
  module Ask
6
11
  # OpenTelemetry tracing for the ask-rb ecosystem.
7
12
  #
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-opentelemetry
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaka Ruto
@@ -13,14 +13,14 @@ dependencies:
13
13
  name: ask-instrumentation
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - "~>"
16
+ - - ">="
17
17
  - !ruby/object:Gem::Version
18
18
  version: '0.1'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
- - - "~>"
23
+ - - ">="
24
24
  - !ruby/object:Gem::Version
25
25
  version: '0.1'
26
26
  - !ruby/object:Gem::Dependency