@spree/docs 0.1.158 → 0.1.159

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.
@@ -0,0 +1,218 @@
1
+ ---
2
+ title: Telemetry
3
+ description: Distributed tracing with OpenTelemetry — one gem, standard OTEL_* environment variables, and every checkout becomes a trace from HTTP request to gateway call to webhook delivery.
4
+ ---
5
+
6
+ Spree supports [OpenTelemetry](https://opentelemetry.io), the open standard for
7
+ distributed tracing. Install the optional `spree_opentelemetry` gem, point it
8
+ at your collector with the same environment variables every other
9
+ OpenTelemetry service uses, and Spree exports traces — no code changes, no
10
+ vendor lock-in. Traces flow to any OpenTelemetry-compatible backend: Grafana
11
+ Tempo, Jaeger, Datadog, Honeycomb, New Relic, Dynatrace, and others.
12
+
13
+ ## Setup
14
+
15
+ Add the gem to your application's Gemfile:
16
+
17
+ ```ruby
18
+ gem 'spree_opentelemetry'
19
+ ```
20
+
21
+ Then configure the exporter through the standard OpenTelemetry environment
22
+ variables:
23
+
24
+ ```bash
25
+ OTEL_SERVICE_NAME=spree
26
+ OTEL_EXPORTER_OTLP_ENDPOINT=http://collector:4318
27
+ ```
28
+
29
+ That is the entire setup. Without an exporter configured, the gem stays
30
+ dormant and adds no overhead. `OTEL_SDK_DISABLED=true` turns telemetry off
31
+ regardless of any other setting.
32
+
33
+ Other standard variables work as documented in the
34
+ [OpenTelemetry SDK configuration reference](https://opentelemetry.io/docs/languages/sdk-configuration/),
35
+ including sampling:
36
+
37
+ ```bash
38
+ # Sample 10% of traces (children follow their parent's decision)
39
+ OTEL_TRACES_SAMPLER=parentbased_traceidratio
40
+ OTEL_TRACES_SAMPLER_ARG=0.1
41
+ ```
42
+
43
+ ## What gets traced
44
+
45
+ Two layers combine into one trace per request or job.
46
+
47
+ **Framework spans** come from the official Rails auto-instrumentation: HTTP
48
+ requests, controller actions, database queries, background job enqueues and
49
+ executions, mail deliveries, and outbound HTTP calls. Trace context carries
50
+ across the job boundary, so work that happens in a background job stays
51
+ connected to the request that caused it.
52
+
53
+ **Commerce spans** come from Spree itself:
54
+
55
+ | Span | Kind | What it covers |
56
+ |---|---|---|
57
+ | `carts.complete` (any workflow key) | internal | One span per workflow run, with its outcome |
58
+ | `carts.complete process_payments` (any step) | internal / client | One span per workflow step; steps declared as external I/O become client spans |
59
+ | `carts.add_item hooks validate` | internal | Extension hook dispatch, only when handlers are registered |
60
+ | `order.placed dispatch` | internal | Event delivery to each subscriber, showing whether it ran inline or was enqueued |
61
+ | `spree.webhook.deliver order.placed` | client | Each webhook POST, with the destination host and response code |
62
+ | `spree.gateway.purchase` (any gateway action) | client | Each payment gateway call — authorize, purchase, capture, void, credit, and payment session operations |
63
+
64
+ A completed checkout, for example, produces one trace containing the HTTP
65
+ request, the `carts.complete` workflow and its steps, the payment gateway
66
+ call, the database work, and — linked from it — the background jobs and
67
+ webhook deliveries the order triggered.
68
+
69
+ Spree also propagates
70
+ [W3C Trace Context](https://www.w3.org/TR/trace-context/) headers on outbound
71
+ webhooks, so a system receiving your webhooks can join its own spans to the
72
+ trace that produced the event.
73
+
74
+ ## Span attributes and personal data
75
+
76
+ Span attributes never contain personal or sensitive data. They are limited to
77
+ workflow and step names, gateway action names, payment method class names,
78
+ event names, webhook destination hosts, and HTTP status codes. Order contents,
79
+ customer emails, addresses, payment details, and webhook payloads are never
80
+ attached to spans.
81
+
82
+ ## Metrics
83
+
84
+ Spree exports the trace signal. Request rates, error rates, and latency
85
+ percentiles per endpoint, workflow, or gateway are derived from spans in the
86
+ OpenTelemetry Collector with the
87
+ [span metrics connector](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/spanmetricsconnector):
88
+
89
+ ```yaml
90
+ # otel-collector config
91
+ connectors:
92
+ spanmetrics:
93
+ dimensions:
94
+ - name: spree.workflow
95
+ - name: spree.gateway.action
96
+
97
+ service:
98
+ pipelines:
99
+ traces:
100
+ receivers: [otlp]
101
+ exporters: [spanmetrics, otlp]
102
+ metrics:
103
+ receivers: [spanmetrics]
104
+ exporters: [prometheusremotewrite]
105
+ ```
106
+
107
+ ## Using with Sentry
108
+
109
+ Sentry and OpenTelemetry are complementary — Sentry's error capture works
110
+ independently of tracing, so having both installed (as spree-starter does)
111
+ requires no special setup. For traces there are three arrangements:
112
+
113
+ **Sentry for errors, OpenTelemetry for traces (default).** Nothing to
114
+ configure. Just don't *also* enable Sentry's own performance tracing
115
+ (`traces_sample_rate`) — that would instrument every request twice and
116
+ produce two disconnected trace systems.
117
+
118
+ **Sentry as the trace backend.** Sentry ingests OpenTelemetry spans directly
119
+ through its [OTLP integration](https://docs.sentry.io/platforms/ruby/guides/rails/integrations/otlp/).
120
+ Order matters here: Sentry registers its span processor inside `Sentry.init`,
121
+ which only works if the OpenTelemetry SDK is already installed — so install
122
+ Spree's telemetry explicitly at the top of the same initializer:
123
+
124
+ ```ruby
125
+ # Gemfile
126
+ gem 'sentry-opentelemetry'
127
+
128
+ # config/initializers/sentry.rb
129
+ SpreeOpenTelemetry.configure { |config| config.enabled = true }
130
+ SpreeOpenTelemetry.install!
131
+
132
+ Sentry.init do |config|
133
+ config.dsn = ENV['SENTRY_DSN']
134
+ config.otlp.enabled = true
135
+ # Do not set traces_sample_rate or instrumenter — OpenTelemetry owns tracing.
136
+ end
137
+ ```
138
+
139
+ ```bash
140
+ # Sentry provides the exporter (derived from the DSN) — tell the SDK not to
141
+ # wire its own default OTLP exporter alongside it.
142
+ OTEL_TRACES_EXPORTER=none
143
+ ```
144
+
145
+ A DSN alone does **not** enable tracing; `config.otlp.enabled` is the
146
+ explicit opt-in (Sentry bills for ingested spans, so error capture never
147
+ silently becomes span ingestion).
148
+
149
+ Spree's commerce spans — workflows, gateway calls, webhook deliveries — show
150
+ up in Sentry's trace view, and Sentry errors are linked automatically to the
151
+ span that was active when they were captured.
152
+
153
+ **Both, via the collector.** Point Spree at an OpenTelemetry Collector and
154
+ fan out from there — one pipeline exporting to your tracing backend and
155
+ another to Sentry's OTLP endpoint. This is the most flexible arrangement for
156
+ teams that want Grafana/Jaeger for latency work and Sentry for error triage
157
+ over the same traces.
158
+
159
+ ## Correlating logs
160
+
161
+ To connect log lines to traces, tag your Rails logs with the current trace:
162
+
163
+ ```ruby
164
+ # config/environments/production.rb
165
+ config.log_tags = [
166
+ ->(_request) { "trace_id=#{OpenTelemetry::Trace.current_span.context.hex_trace_id}" }
167
+ ]
168
+ ```
169
+
170
+ ## Trying it locally
171
+
172
+ Run Jaeger with an OTLP receiver and point Spree at it:
173
+
174
+ ```bash
175
+ docker run --rm -p 16686:16686 -p 4318:4318 jaegertracing/jaeger:latest
176
+ ```
177
+
178
+ ```bash
179
+ OTEL_SERVICE_NAME=spree \
180
+ OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
181
+ bin/rails server
182
+ ```
183
+
184
+ Place a test order and open [http://localhost:16686](http://localhost:16686)
185
+ to see the trace.
186
+
187
+ ## Code-level configuration
188
+
189
+ Everything routine is controlled by environment variables. A
190
+ `SpreeOpenTelemetry.configure` block exists for the rest — adding
191
+ instrumentation for libraries your app uses, removing a default, or advanced
192
+ SDK tuning:
193
+
194
+ ```ruby
195
+ # config/initializers/opentelemetry.rb
196
+ SpreeOpenTelemetry.configure do |config|
197
+ config.use 'OpenTelemetry::Instrumentation::Redis' # add an instrumentation
198
+ config.skip 'OpenTelemetry::Instrumentation::ActionMailer' # remove a default
199
+ config.with_sdk { |otel| otel.add_span_processor(my_processor) }
200
+ end
201
+ ```
202
+
203
+ ## Instrumenting your own code
204
+
205
+ Spree's spans are built on `ActiveSupport::Notifications`, and yours can be
206
+ too — or use the OpenTelemetry API directly:
207
+
208
+ ```ruby
209
+ tracer = OpenTelemetry.tracer_provider.tracer('my_app')
210
+
211
+ tracer.in_span('loyalty.award_points', attributes: { 'loyalty.points' => 50 }) do
212
+ # your code
213
+ end
214
+ ```
215
+
216
+ Custom workflows get traced automatically: every `Spree::Workflow` run, step,
217
+ and hook dispatch is instrumented by the framework, including workflows your
218
+ application or extensions define.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spree/docs",
3
- "version": "0.1.158",
3
+ "version": "0.1.159",
4
4
  "description": "Spree Commerce developer documentation for AI agents and local reference",
5
5
  "type": "module",
6
6
  "license": "CC-BY-4.0",