autotel 3.0.0 → 3.0.3
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.
- package/README.md +21 -4
- package/dist/attribute-redacting-processor.cjs +8 -8
- package/dist/attribute-redacting-processor.d.cts +10 -1
- package/dist/attribute-redacting-processor.d.ts +10 -1
- package/dist/attribute-redacting-processor.js +1 -1
- package/dist/attributes.cjs +21 -21
- package/dist/attributes.js +2 -2
- package/dist/auto.cjs +3 -3
- package/dist/auto.js +2 -2
- package/dist/{chunk-7HNQYHK4.js → chunk-52PUSFC2.js} +3 -3
- package/dist/{chunk-7HNQYHK4.js.map → chunk-52PUSFC2.js.map} +1 -1
- package/dist/{chunk-L7JDUDJD.cjs → chunk-7SMNC4LS.cjs} +7 -7
- package/dist/{chunk-L7JDUDJD.cjs.map → chunk-7SMNC4LS.cjs.map} +1 -1
- package/dist/{chunk-563EL6O6.cjs → chunk-BPO2PQ3T.cjs} +12 -8
- package/dist/chunk-BPO2PQ3T.cjs.map +1 -0
- package/dist/{chunk-ZSABTI3C.cjs → chunk-DAZ7EGR4.cjs} +17 -17
- package/dist/{chunk-ZSABTI3C.cjs.map → chunk-DAZ7EGR4.cjs.map} +1 -1
- package/dist/{chunk-ER43K7ES.js → chunk-DDXIUZEG.js} +3 -3
- package/dist/{chunk-ER43K7ES.js.map → chunk-DDXIUZEG.js.map} +1 -1
- package/dist/{chunk-JKIMEPI2.cjs → chunk-DQ2SUROF.cjs} +4 -4
- package/dist/{chunk-JKIMEPI2.cjs.map → chunk-DQ2SUROF.cjs.map} +1 -1
- package/dist/{chunk-KHGA4OST.cjs → chunk-HKZHUGGN.cjs} +5 -5
- package/dist/{chunk-KHGA4OST.cjs.map → chunk-HKZHUGGN.cjs.map} +1 -1
- package/dist/{chunk-TDNKIHKT.js → chunk-JVWJDHDB.js} +13 -4
- package/dist/chunk-JVWJDHDB.js.map +1 -0
- package/dist/{chunk-3QMFLJHJ.js → chunk-K7HSRLP5.js} +3 -3
- package/dist/{chunk-3QMFLJHJ.js.map → chunk-K7HSRLP5.js.map} +1 -1
- package/dist/{chunk-CJ4PD2TZ.cjs → chunk-KKGM42RQ.cjs} +13 -13
- package/dist/{chunk-CJ4PD2TZ.cjs.map → chunk-KKGM42RQ.cjs.map} +1 -1
- package/dist/{chunk-DWOBIBLY.cjs → chunk-MOO75VE4.cjs} +5 -5
- package/dist/{chunk-DWOBIBLY.cjs.map → chunk-MOO75VE4.cjs.map} +1 -1
- package/dist/{chunk-CMNGGTQL.cjs → chunk-NXLRY2CE.cjs} +13 -4
- package/dist/chunk-NXLRY2CE.cjs.map +1 -0
- package/dist/{chunk-4DAG3RFS.js → chunk-OM4OSBOP.js} +4 -4
- package/dist/{chunk-4DAG3RFS.js.map → chunk-OM4OSBOP.js.map} +1 -1
- package/dist/{chunk-DAAJLUTO.js → chunk-PMRWMRXY.js} +4 -4
- package/dist/{chunk-DAAJLUTO.js.map → chunk-PMRWMRXY.js.map} +1 -1
- package/dist/{chunk-MOK3E54E.cjs → chunk-QPH5ZKP5.cjs} +32 -32
- package/dist/{chunk-MOK3E54E.cjs.map → chunk-QPH5ZKP5.cjs.map} +1 -1
- package/dist/{chunk-IUDXKLS4.js → chunk-TFRZOUTV.js} +3 -3
- package/dist/{chunk-IUDXKLS4.js.map → chunk-TFRZOUTV.js.map} +1 -1
- package/dist/{chunk-QG3U5ONP.js → chunk-Z7VAOK5X.js} +3 -3
- package/dist/{chunk-QG3U5ONP.js.map → chunk-Z7VAOK5X.js.map} +1 -1
- package/dist/{chunk-W35FVJBC.js → chunk-ZDPIWKWD.js} +9 -5
- package/dist/chunk-ZDPIWKWD.js.map +1 -0
- package/dist/correlation-id.cjs +11 -11
- package/dist/correlation-id.js +3 -3
- package/dist/decorators.cjs +5 -5
- package/dist/decorators.js +4 -4
- package/dist/event.cjs +7 -7
- package/dist/event.js +4 -4
- package/dist/functional.cjs +11 -11
- package/dist/functional.js +4 -4
- package/dist/http.cjs +4 -4
- package/dist/http.js +3 -3
- package/dist/index.cjs +226 -92
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +67 -3
- package/dist/index.d.ts +67 -3
- package/dist/index.js +138 -15
- package/dist/index.js.map +1 -1
- package/dist/instrumentation.cjs +9 -9
- package/dist/instrumentation.js +2 -2
- package/dist/messaging.cjs +8 -8
- package/dist/messaging.js +5 -5
- package/dist/semantic-helpers.cjs +9 -9
- package/dist/semantic-helpers.js +5 -5
- package/dist/webhook.cjs +6 -6
- package/dist/webhook.js +4 -4
- package/dist/workflow-distributed.cjs +6 -6
- package/dist/workflow-distributed.js +4 -4
- package/dist/workflow.cjs +9 -9
- package/dist/workflow.js +5 -5
- package/package.json +43 -45
- package/skills/analyze-traces/SKILL.md +178 -0
- package/skills/autotel-core/SKILL.md +0 -7
- package/skills/autotel-events/SKILL.md +0 -6
- package/skills/autotel-frameworks/SKILL.md +0 -9
- package/skills/autotel-instrumentation/SKILL.md +0 -7
- package/skills/autotel-request-logging/SKILL.md +0 -8
- package/skills/autotel-structured-errors/SKILL.md +0 -7
- package/skills/build-audit-trails/SKILL.md +302 -0
- package/skills/debug-missing-spans/SKILL.md +248 -0
- package/skills/migrate-to-autotel/SKILL.md +268 -0
- package/skills/review-otel-patterns/SKILL.md +488 -0
- package/skills/review-otel-patterns/references/code-review.md +75 -0
- package/skills/review-otel-patterns/references/processor-pipeline.md +205 -0
- package/skills/review-otel-patterns/references/structured-errors.md +102 -0
- package/skills/review-otel-patterns/references/wide-spans.md +85 -0
- package/skills/tune-sampling/SKILL.md +210 -0
- package/src/attribute-redacting-processor.test.ts +6 -4
- package/src/attribute-redacting-processor.ts +11 -2
- package/src/drain-toolkit.test.ts +113 -0
- package/src/drain-toolkit.ts +129 -0
- package/src/enricher-toolkit.test.ts +67 -0
- package/src/enricher-toolkit.ts +79 -0
- package/src/index.ts +19 -0
- package/src/redact-values.test.ts +24 -10
- package/src/redact-values.ts +9 -2
- package/src/request-logger.test.ts +91 -0
- package/src/request-logger.ts +36 -2
- package/src/structured-error.test.ts +4 -1
- package/bin/intent.js +0 -6
- package/dist/chunk-563EL6O6.cjs.map +0 -1
- package/dist/chunk-CMNGGTQL.cjs.map +0 -1
- package/dist/chunk-TDNKIHKT.js.map +0 -1
- package/dist/chunk-W35FVJBC.js.map +0 -1
- package/src/package-manifest.test.ts +0 -24
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: migrate-to-autotel
|
|
3
|
+
description: >
|
|
4
|
+
Migrate an existing observability setup to autotel. Handles raw
|
|
5
|
+
@opentelemetry/sdk-node, Sentry tracer (`@sentry/node`), Datadog APM
|
|
6
|
+
(`dd-trace`), New Relic agent (`newrelic`), Honeycomb Beelines, and
|
|
7
|
+
OpenTracing / OpenCensus. Preserves trace fidelity (no gap in dashboards
|
|
8
|
+
during cutover), maps vendor-specific span attributes to OTel semantic
|
|
9
|
+
conventions, and runs both stacks side-by-side during the cutover window.
|
|
10
|
+
license: MIT
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Migrate to autotel
|
|
14
|
+
|
|
15
|
+
Replacing tracing in a live service is risky — you can lose data, change span shapes, or break dashboards your on-call team relies on. This skill covers the safe paths from each major source, what to change in your code, and how to verify the cutover before turning the old stack off.
|
|
16
|
+
|
|
17
|
+
## Choose your starting point
|
|
18
|
+
|
|
19
|
+
| You're using | Section |
|
|
20
|
+
| ------------------------------------------- | -------------------------------------------------------------- |
|
|
21
|
+
| Raw `@opentelemetry/sdk-node` | [From raw OTel SDK](#from-raw-opentelemetry-sdk-node) |
|
|
22
|
+
| Sentry `@sentry/node` performance / tracing | [From Sentry](#from-sentry-performance-tracing) |
|
|
23
|
+
| Datadog APM (`dd-trace`) | [From Datadog APM](#from-datadog-apm) |
|
|
24
|
+
| New Relic agent (`newrelic`) | [From New Relic Node agent](#from-new-relic-node-agent) |
|
|
25
|
+
| Honeycomb Beelines | [From Honeycomb Beelines](#from-honeycomb-beelines) |
|
|
26
|
+
| OpenTracing / OpenCensus | [From OpenTracing / OpenCensus](#from-opentracing--opencensus) |
|
|
27
|
+
| `console.log` everything | [From unstructured logging](#from-unstructured-logging) |
|
|
28
|
+
|
|
29
|
+
## Universal cutover plan
|
|
30
|
+
|
|
31
|
+
1. **Pin metrics.** Snapshot p50 / p95 / p99 / error-rate / span-count for the top 5 endpoints. You'll diff post-cutover.
|
|
32
|
+
2. **Run both side-by-side for 24–48 h.** Both old and new exporters wired in parallel. Use distinct backends (or distinct datasets) so you can compare like for like.
|
|
33
|
+
3. **Cutover dashboards & alerts.** Re-author critical dashboards on the autotel data; keep both alert sets armed.
|
|
34
|
+
4. **Disable the old stack.** Remove old SDK imports + processors; redeploy.
|
|
35
|
+
5. **Decommission.** Remove old packages from `package.json` and lock files; archive old dashboards.
|
|
36
|
+
|
|
37
|
+
Don't compress this into a single PR. The riskiest step is "disable old stack" — keep it last.
|
|
38
|
+
|
|
39
|
+
## From raw `@opentelemetry/sdk-node`
|
|
40
|
+
|
|
41
|
+
The smoothest migration. autotel layers on top of OTel — your span attributes, propagators, and exporters can stay.
|
|
42
|
+
|
|
43
|
+
### Drop-in init
|
|
44
|
+
|
|
45
|
+
Before:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
49
|
+
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
|
|
50
|
+
import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
51
|
+
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
|
|
52
|
+
|
|
53
|
+
const sdk = new NodeSDK({
|
|
54
|
+
resource: resourceFromAttributes({ 'service.name': 'my-app' }),
|
|
55
|
+
spanProcessors: [
|
|
56
|
+
new BatchSpanProcessor(
|
|
57
|
+
new OTLPTraceExporter({ url: process.env.OTEL_ENDPOINT }),
|
|
58
|
+
),
|
|
59
|
+
],
|
|
60
|
+
});
|
|
61
|
+
sdk.start();
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
After:
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
import { init } from 'autotel';
|
|
68
|
+
|
|
69
|
+
init({
|
|
70
|
+
service: 'my-app',
|
|
71
|
+
exporter: { url: process.env.OTEL_ENDPOINT! },
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`init()` builds the same provider + exporter, plus turns on the global fetch instrumentation, sets up the W3C propagator, and primes the redactor.
|
|
76
|
+
|
|
77
|
+
### What you gain immediately
|
|
78
|
+
|
|
79
|
+
- `useLogger().set({ … })` flattens onto the active span — no more `span.setAttribute('user.id', id)` boilerplate.
|
|
80
|
+
- `attributeRedactor: 'default'` — PII masking for free in production.
|
|
81
|
+
- `composeSpanProcessors([…])` for multi-backend tee.
|
|
82
|
+
- Cloudflare Workers + Edge support out of the box (`defineWorkerFetch`).
|
|
83
|
+
|
|
84
|
+
### What stays the same
|
|
85
|
+
|
|
86
|
+
- Your propagator (`W3CTraceContextPropagator` is the default).
|
|
87
|
+
- Your exporters — pass them via `spanProcessors` if you want to keep custom ones.
|
|
88
|
+
- Your resource attributes.
|
|
89
|
+
|
|
90
|
+
## From Sentry performance tracing
|
|
91
|
+
|
|
92
|
+
Sentry's tracing is OTel-compatible since v7+, but their span shapes have non-standard names (`http.server`, `db.query`).
|
|
93
|
+
|
|
94
|
+
### Step 1: Use `autotel-sentry` to keep sending to Sentry
|
|
95
|
+
|
|
96
|
+
If you want the dashboards to stay in Sentry, autotel can export OTLP to Sentry's OTLP intake:
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { init } from 'autotel';
|
|
100
|
+
import { SentrySpanExporter } from 'autotel-sentry';
|
|
101
|
+
|
|
102
|
+
init({
|
|
103
|
+
service: 'my-app',
|
|
104
|
+
spanProcessors: [
|
|
105
|
+
new BatchSpanProcessor(
|
|
106
|
+
new SentrySpanExporter({ dsn: process.env.SENTRY_DSN! }),
|
|
107
|
+
),
|
|
108
|
+
],
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Step 2: Replace Sentry-specific helpers
|
|
113
|
+
|
|
114
|
+
| Sentry | autotel |
|
|
115
|
+
| ---------------------------------------------------------- | ----------------------------------------------------- |
|
|
116
|
+
| `Sentry.startSpan({ op: 'fn', name: 'process' }, () => …)` | `trace({ name: 'process' }, () => …)` |
|
|
117
|
+
| `Sentry.captureException(err)` | `createStructuredError({ … })` (auto-records on span) |
|
|
118
|
+
| `Sentry.setUser({ id })` | `useLogger().set({ user: { id } })` |
|
|
119
|
+
| `Sentry.setContext('cart', { … })` | `useLogger().set({ cart: { … } })` |
|
|
120
|
+
| `Sentry.startTransaction({ name })` | `trace({ name }, fn)` |
|
|
121
|
+
|
|
122
|
+
### Step 3: Decide on errors-only vs full tracing
|
|
123
|
+
|
|
124
|
+
Sentry shines at errors; for tracing you may want to fan out to Honeycomb or Grafana Tempo. Use `composeSpanProcessors`:
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
spanProcessors: composeSpanProcessors([
|
|
128
|
+
new BatchSpanProcessor(new SentrySpanExporter({ dsn })),
|
|
129
|
+
new BatchSpanProcessor(
|
|
130
|
+
new OTLPHttpJsonExporter({
|
|
131
|
+
url: honeycombUrl,
|
|
132
|
+
headers: { 'x-honeycomb-team': key },
|
|
133
|
+
}),
|
|
134
|
+
),
|
|
135
|
+
]);
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## From Datadog APM
|
|
139
|
+
|
|
140
|
+
Datadog APM uses its own format and proprietary tracer. The migration path is OTLP → Datadog OTLP intake, then sunset `dd-trace`.
|
|
141
|
+
|
|
142
|
+
### Step 1: Stop importing `dd-trace`
|
|
143
|
+
|
|
144
|
+
`dd-trace` patches every supported library on import — keeping it in the bundle while autotel runs causes double-instrumentation. Remove `import 'dd-trace'` (or the `--require dd-trace/init` arg).
|
|
145
|
+
|
|
146
|
+
### Step 2: Point autotel at Datadog OTLP intake
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import { init } from 'autotel';
|
|
150
|
+
|
|
151
|
+
init({
|
|
152
|
+
service: 'my-app',
|
|
153
|
+
exporter: {
|
|
154
|
+
url: 'https://trace.agent.datadoghq.com/api/v0.4/traces',
|
|
155
|
+
headers: { 'dd-api-key': process.env.DD_API_KEY! },
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
For the EU site use `datadoghq.eu`; for US3 / US5 see Datadog's region matrix.
|
|
161
|
+
|
|
162
|
+
### Step 3: Map Datadog span tags
|
|
163
|
+
|
|
164
|
+
Datadog uses `service`, `resource`, `operation` — OTel uses `service.name`, `http.route`, span name. autotel handles the conversion automatically when exporting via `dd-api-key`. If you have custom Datadog tags in dashboards, rename them in code:
|
|
165
|
+
|
|
166
|
+
| Datadog tag | OTel attribute |
|
|
167
|
+
| ----------- | --------------------------- |
|
|
168
|
+
| `env` | `deployment.environment` |
|
|
169
|
+
| `version` | `service.version` |
|
|
170
|
+
| `pod_name` | `k8s.pod.name` |
|
|
171
|
+
| `host.name` | (resource attr) `host.name` |
|
|
172
|
+
|
|
173
|
+
### Step 4: Replace `dd-trace`-specific APIs
|
|
174
|
+
|
|
175
|
+
| `dd-trace` | autotel |
|
|
176
|
+
| -------------------------------------- | --------------------------------------------------------------------------------------------------- |
|
|
177
|
+
| `tracer.trace('op', { resource }, fn)` | `trace({ name: 'op' }, fn)` (set `http.route` via `useLogger().set({ http: { route } })` if needed) |
|
|
178
|
+
| `tracer.scope().active()` | `trace.getActiveSpan()` (from `@opentelemetry/api`) |
|
|
179
|
+
| `tracer.wrap('op', fn)` | `trace(fn)` |
|
|
180
|
+
|
|
181
|
+
## From New Relic Node agent
|
|
182
|
+
|
|
183
|
+
New Relic's agent is invasive — it patches Node internals. Plan a maintenance window for the cutover.
|
|
184
|
+
|
|
185
|
+
### Step 1: Remove `--require newrelic`
|
|
186
|
+
|
|
187
|
+
Drop it from `start` script and `NODE_OPTIONS`.
|
|
188
|
+
|
|
189
|
+
### Step 2: Point at New Relic OTLP
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
init({
|
|
193
|
+
service: 'my-app',
|
|
194
|
+
exporter: {
|
|
195
|
+
url: 'https://otlp.nr-data.net/v1/traces',
|
|
196
|
+
headers: { 'api-key': process.env.NEW_RELIC_LICENSE_KEY! },
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
For EU: `https://otlp.eu01.nr-data.net/v1/traces`.
|
|
202
|
+
|
|
203
|
+
### Step 3: Replace agent APIs
|
|
204
|
+
|
|
205
|
+
| `newrelic` | autotel |
|
|
206
|
+
| ----------------------------------------- | ----------------------------------- |
|
|
207
|
+
| `newrelic.startSegment('name', true, fn)` | `trace({ name }, fn)` |
|
|
208
|
+
| `newrelic.addCustomAttribute(key, value)` | `useLogger().set({ [key]: value })` |
|
|
209
|
+
| `newrelic.noticeError(err)` | `createStructuredError({ … })` |
|
|
210
|
+
| `newrelic.recordMetric(name, value)` | OTel meter API |
|
|
211
|
+
|
|
212
|
+
## From Honeycomb Beelines
|
|
213
|
+
|
|
214
|
+
Beelines for Node was Honeycomb's pre-OTel SDK. Migration is straightforward — Honeycomb supports OTLP natively.
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
init({
|
|
218
|
+
service: 'my-app',
|
|
219
|
+
exporter: {
|
|
220
|
+
url: 'https://api.honeycomb.io/v1/traces',
|
|
221
|
+
headers: { 'x-honeycomb-team': process.env.HONEYCOMB_API_KEY! },
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
| Beeline | autotel |
|
|
227
|
+
| --------------------------------------- | --------------------------------------------------------------------------- |
|
|
228
|
+
| `beeline.withTrace(meta, fn)` | `trace({ name: meta.task }, fn)` |
|
|
229
|
+
| `beeline.customContext.add(key, value)` | `useLogger().set({ [key]: value })` |
|
|
230
|
+
| `beeline.flush()` | `await provider.forceFlush()` (autotel does this on shutdown automatically) |
|
|
231
|
+
|
|
232
|
+
## From OpenTracing / OpenCensus
|
|
233
|
+
|
|
234
|
+
Both are deprecated; the migration is "rewrite the tracer setup, leave call sites alone." OpenTracing's `Tracer.startSpan` and OpenCensus's `tracer.startRootSpan` shapes are similar enough that a script can replace them with `trace()` calls in most files.
|
|
235
|
+
|
|
236
|
+
For libraries you don't control that still use OpenTracing, the OTel project ships a [shim](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-shim-opentracing) — wire it once, then migrate at your own pace.
|
|
237
|
+
|
|
238
|
+
## From unstructured logging
|
|
239
|
+
|
|
240
|
+
If you're starting from `console.log` everywhere:
|
|
241
|
+
|
|
242
|
+
1. Add `init({ service: 'my-app', debug: 'pretty' })` so spans are visible locally.
|
|
243
|
+
2. Replace `console.log` in handlers with `useLogger().set({ … })`.
|
|
244
|
+
3. Wrap throw sites with `createStructuredError({ message, status, why, fix })`.
|
|
245
|
+
4. Add a real OTLP exporter when you're ready to ship to a backend.
|
|
246
|
+
|
|
247
|
+
See [`review-otel-patterns`](../review-otel-patterns/SKILL.md) for the framework setup steps.
|
|
248
|
+
|
|
249
|
+
## Verifying the cutover
|
|
250
|
+
|
|
251
|
+
| Check | How |
|
|
252
|
+
| --------------------------- | --------------------------------------------------------------------------------------------- |
|
|
253
|
+
| **Span volume matches** | Compare `count(spans)` per route over 24h; should be within ±5 % |
|
|
254
|
+
| **p99 latency unchanged** | Histograms on both backends |
|
|
255
|
+
| **Error rate unchanged** | `count(spans where status=error)` |
|
|
256
|
+
| **Trace correlation works** | Pick 10 random `traceId`s; confirm cross-service spans resolve |
|
|
257
|
+
| **Bundle size acceptable** | `pnpm bundle-size` — moving from heavy agents (New Relic, Datadog) often _shrinks_ the bundle |
|
|
258
|
+
|
|
259
|
+
## Anti-patterns
|
|
260
|
+
|
|
261
|
+
| Anti-pattern | Fix |
|
|
262
|
+
| --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
|
263
|
+
| Both old SDK and autotel running on the same library | Pick one — double-instrumentation duplicates spans |
|
|
264
|
+
| Removing the old SDK in the same PR as adding autotel | Run both side-by-side for 24–48 h first |
|
|
265
|
+
| Changing span names during migration | Preserve names; rename in a separate PR after dashboards re-pointed |
|
|
266
|
+
| No metric snapshot before cutover | Take p50/p95/p99 + error-rate baselines first |
|
|
267
|
+
| Migrating prod before staging | Always staging first — at least 24 h |
|
|
268
|
+
| Trusting the old vendor agent's auto-instrumentation list | autotel's targeted instrumentations (`autotel-drizzle`, `autotel-mongoose`, …) are faster and tighter; expect to add a couple |
|