@autter/runtime-node 1.4.0 → 1.5.0
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 +106 -16
- package/dist/chunk-3TJHUCZ6.js +1680 -0
- package/dist/chunk-GI47WGRR.cjs +779 -0
- package/dist/chunk-L6SRL65J.cjs +202 -0
- package/dist/chunk-L7HWKMCZ.js +779 -0
- package/dist/chunk-P4VRTFAV.cjs +1680 -0
- package/dist/chunk-ZS4WQJQR.js +202 -0
- package/dist/cli.cjs +40 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +40 -0
- package/dist/index.cjs +1272 -1141
- package/dist/index.d.cts +420 -42
- package/dist/index.d.ts +420 -42
- package/dist/index.js +1083 -917
- package/dist/sinks-RFV76lF1.d.cts +313 -0
- package/dist/sinks-RFV76lF1.d.ts +313 -0
- package/dist/testing.cjs +121 -0
- package/dist/testing.d.cts +57 -0
- package/dist/testing.d.ts +57 -0
- package/dist/testing.js +121 -0
- package/package.json +16 -5
package/README.md
CHANGED
|
@@ -5,6 +5,49 @@ application context to logs and completed operations. See the full
|
|
|
5
5
|
[operation logging guide](../../docs/OPERATION-LOGGING.md) for initialization,
|
|
6
6
|
steps, outcomes, redaction, export lifecycle, and release requirements.
|
|
7
7
|
|
|
8
|
+
# Requests and coded errors (1.5.0)
|
|
9
|
+
|
|
10
|
+
Requires ingester 1.5.0. One summary per request (always kept), request ids
|
|
11
|
+
echoed to clients, one issue per error code:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import {
|
|
15
|
+
autterRequests, autterErrorResponse, defineRuntimeErrors, runtimeContext,
|
|
16
|
+
} from "@autter/runtime-node";
|
|
17
|
+
|
|
18
|
+
export const billingErrors = defineRuntimeErrors("billing", {
|
|
19
|
+
declined: { status: 402, message: "Payment declined", expected: true,
|
|
20
|
+
why: "The card issuer rejected the charge", fix: "Ask for another card" },
|
|
21
|
+
limit: ({ plan }: { plan: string }) => ({ status: 429, message: `Plan ${plan} limit reached` }),
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
app.use(autterRequests({ ignore: ["/healthz", "/metrics"] }));
|
|
25
|
+
app.post("/checkout", async (req, res) => {
|
|
26
|
+
runtimeContext.set({ cart: { items: req.body.items.length } });
|
|
27
|
+
runtimeContext.info("Applied coupon", { coupon: "SPRING" }); // folded into the summary
|
|
28
|
+
if (overLimit) throw billingErrors.limit({ plan: "free" }); // Express 5 (next(err) on 4)
|
|
29
|
+
res.json({ ok: true, requestId: runtimeContext.requestId });
|
|
30
|
+
});
|
|
31
|
+
app.use(autterErrorResponse()); // { error: { message, code, why?, fix?, link?, requestId } }
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Also: `autterFastify`, `withRuntimeRequest` (fetch-style handlers),
|
|
35
|
+
`runtimeContext.fork` / `runInBackground` / `carrier()` for background work and
|
|
36
|
+
queues, the per-operation AI usage rollup, `waitUntil`, `initAutterLogging`
|
|
37
|
+
(no NodeSDK — for apps with their own OTel), enrichers (`enrichUserAgent`,
|
|
38
|
+
`enrichRequestSize`, `enrichEdgeGeo`, `enrichDeployment`), sinks (`otlpSink`,
|
|
39
|
+
`consoleSink`, `fileSink` → `.autter/runtime/*.jsonl` in development) and test
|
|
40
|
+
helpers:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { captureRuntime, expectOperation } from "@autter/runtime-node/testing";
|
|
44
|
+
const runtime = captureRuntime();
|
|
45
|
+
// … exercise the app …
|
|
46
|
+
expectOperation(runtime, "POST /checkout").toHaveOutcome("degraded").toHaveErrorCode("billing.declined");
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Full guide: [Requests, coded errors and background work](../../docs/REQUESTS-AND-ERRORS.md).
|
|
50
|
+
|
|
8
51
|
# @autter/runtime-node
|
|
9
52
|
|
|
10
53
|
The server tracker exports per-instance RSS, heap, memory limit, and GC
|
|
@@ -124,6 +167,35 @@ import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
|
|
|
124
167
|
initAutterServer({ ..., instrumentations: [new ExpressInstrumentation()] });
|
|
125
168
|
```
|
|
126
169
|
|
|
170
|
+
### Version compatibility: checked for you
|
|
171
|
+
|
|
172
|
+
Some features need a minimum ingester version: operation logging needs
|
|
173
|
+
1.4.0, memory metrics 1.3.3, endpoint latency 1.3.1. After
|
|
174
|
+
`initAutterServer`, the SDK checks the ingester once in the background
|
|
175
|
+
(`GET /v1/compat`, unref'd, 3 s timeout). For each feature in use that the
|
|
176
|
+
ingester can't store, it prints one warning:
|
|
177
|
+
|
|
178
|
+
```text
|
|
179
|
+
[autter-runtime] Operation logging needs ingester >= 1.4.0; yours is 1.3.4. Upgrade the ingester: docker pull ghcr.io/autter-dev/otlp-ingester:latest and restart it (ClickHouse migrations run at boot). See …/docs/COMPATIBILITY.md
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
The check never throws, never delays startup or exit, and is silent when
|
|
183
|
+
versions match or are unknown. `debug: true` logs the result. Turn it off
|
|
184
|
+
with `compatCheck: false` or `AUTTER_COMPAT_CHECK=0`. The browser relay does
|
|
185
|
+
the same for browser features such as CSP violation capture. The SDK reports
|
|
186
|
+
itself through the OTLP resource attributes `telemetry.distro.name` and
|
|
187
|
+
`telemetry.distro.version`, so the Autter dashboard shows the SDK version
|
|
188
|
+
each service runs.
|
|
189
|
+
|
|
190
|
+
For a full report (for example in CI or after a deploy):
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
npx @autter/runtime-node doctor --endpoint https://ingest.example.com [--key "$AUTTER_RUNTIME_KEY"] [--json]
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Exit codes: 0 compatible, 1 mismatch or rejected key, 2 ingester unreachable.
|
|
197
|
+
See [docs/COMPATIBILITY.md](../../docs/COMPATIBILITY.md).
|
|
198
|
+
|
|
127
199
|
### Lifecycle: never lose telemetry to a forgotten shutdown()
|
|
128
200
|
|
|
129
201
|
Telemetry is batched (errors every ~2 s, healthy traces every ~5 s, metrics
|
|
@@ -155,23 +227,39 @@ default 1% sampling the span contribution is negligible; if you set
|
|
|
155
227
|
Tail-retained error traces don't distort this: their spans carry
|
|
156
228
|
`autter.tail_retained` and the ingester keeps them out of span-fed rollups.
|
|
157
229
|
|
|
158
|
-
### Privacy:
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
default
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
230
|
+
### Privacy: secrets and PII are scrubbed before they leave the process
|
|
231
|
+
|
|
232
|
+
Error context is where secrets leak: `connect ECONNREFUSED
|
|
233
|
+
postgres://admin:hunter2@db…` in an exception message, a provider error
|
|
234
|
+
echoing an API key, a `?token=` in a request URL, a stray
|
|
235
|
+
`captureException(err, { "user.email": … })`. Everything the SDK exports is
|
|
236
|
+
therefore scrubbed by default — custom attributes, exception messages and
|
|
237
|
+
stack traces, span status messages, LLM call attributes and errors,
|
|
238
|
+
structured logs, and the browser events the relay forwards. A final pass at
|
|
239
|
+
export time scrubs every span regardless of who created it (HTTP
|
|
240
|
+
instrumentation URLs, third-party instrumentations, `recordException` in
|
|
241
|
+
your own code).
|
|
242
|
+
|
|
243
|
+
- secrets inside any string are masked in place, keeping the rest of the
|
|
244
|
+
message/stack readable: JWTs, `Bearer`/`Basic` credentials,
|
|
245
|
+
`Authorization:`/`Cookie:`/`Set-Cookie:` header text,
|
|
246
|
+
`scheme://user:pass@host` connection strings (postgres, mysql,
|
|
247
|
+
mongodb+srv, redis, …), vendor keys (`sk-…`, `sk_live_…`, `ghp_…`,
|
|
248
|
+
`github_pat_…`, `xox?-…`, `AIza…`, `AKIA…`, …), PEM private keys,
|
|
249
|
+
`password=`/`?token=`/`?api_key=`-style assignments, emails, and
|
|
250
|
+
Luhn-valid card numbers;
|
|
168
251
|
- attributes whose **key** looks sensitive (`password`, `token`, `secret`,
|
|
169
|
-
`api_key`, `authorization`, `cookie`, `ssn`, `card_number`, …)
|
|
170
|
-
wholesale;
|
|
171
|
-
- non-sensitive keys
|
|
172
|
-
dashboards keep working.
|
|
252
|
+
`api_key`, `authorization`, `cookie`, `session`, `ssn`, `card_number`, …)
|
|
253
|
+
are masked wholesale, at any nesting depth;
|
|
254
|
+
- non-sensitive keys, numbers (including LLM token counts) and booleans pass
|
|
255
|
+
through untouched, so grouping, dashboards and cost tracking keep working.
|
|
256
|
+
|
|
257
|
+
The same patterns run in the browser SDK, the relay, the Python adapter,
|
|
258
|
+
and again in the ingester before storage (shared test vectors in
|
|
259
|
+
`test-vectors/redaction.json`).
|
|
173
260
|
|
|
174
|
-
|
|
261
|
+
Extend it (applies to messages, stacks and URLs too) or disable it per
|
|
262
|
+
service:
|
|
175
263
|
|
|
176
264
|
```ts
|
|
177
265
|
initAutterServer({
|
|
@@ -193,7 +281,9 @@ const safe = makeSafeCapture();
|
|
|
193
281
|
safe.captureException(err, { "user.email": email }); // masked before export
|
|
194
282
|
```
|
|
195
283
|
|
|
196
|
-
The raw
|
|
284
|
+
The raw primitives are exported too (`redactAttributes(attrs, options)`,
|
|
285
|
+
`redactText(text, options)`). The browser relay takes the same options as
|
|
286
|
+
`createBrowserRelayHandler({ ..., redact })`.
|
|
197
287
|
This closes the server-side gap to match the browser relay's payload
|
|
198
288
|
whitelist; it is best-effort scrubbing of obvious PII shapes, not a DLP
|
|
199
289
|
engine — keep secrets out of attributes in the first place.
|