@autter/runtime-node 1.6.1 → 1.8.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/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { IncomingMessage, ServerResponse } from 'node:http';
2
- import { b as RedactOptions, c as Redactor$1, d as RuntimeLogLevel, e as RuntimeOperationKind, f as RuntimeSink, F as FileSinkOptions, g as RuntimeLogContext, a as RuntimeOutcome, h as RuntimeCarrier, B as BreadcrumbInput } from './sinks-CPGDyfU8.cjs';
3
- export { i as Breadcrumb, j as BreadcrumbLevel, k as BreadcrumbType, l as CODE_PATTERN, n as ClientErrorBody, o as ConsoleSinkOptions, O as OtlpSinkOptions, p as RuntimeError, q as RuntimeErrorCatalog, r as RuntimeErrorDefinition, s as RuntimeErrorExtras, t as RuntimeErrorFactory, u as RuntimeErrorLike, v as RuntimeErrorOptions, R as RuntimeEvent, w as RuntimeLogContextValue, x as RuntimeSinkContext, y as consoleSink, z as defineRuntimeErrors, A as errorAttributes, D as fileSink, E as isRuntimeErrorLike, G as otlpSink, H as redactAttributes, I as redactText, J as toClientError } from './sinks-CPGDyfU8.cjs';
2
+ import { b as RedactOptions, c as Redactor$1, d as RuntimeLogLevel, e as RuntimeOperationKind, f as RuntimeSink, F as FileSinkOptions, g as RuntimeLogContext, a as RuntimeOutcome, h as RuntimeCarrier, I as IgnoreErrorPattern, B as BreadcrumbInput } from './sinks-CIdlmYwy.cjs';
3
+ export { i as Breadcrumb, j as BreadcrumbLevel, k as BreadcrumbType, l as CODE_PATTERN, n as ClientErrorBody, o as ConsoleSinkOptions, O as OtlpSinkOptions, p as RuntimeError, q as RuntimeErrorCatalog, r as RuntimeErrorDefinition, s as RuntimeErrorExtras, t as RuntimeErrorFactory, u as RuntimeErrorLike, v as RuntimeErrorOptions, R as RuntimeEvent, w as RuntimeLogContextValue, x as RuntimeSinkContext, y as consoleSink, z as defineRuntimeErrors, A as errorAttributes, D as fileSink, E as isRuntimeErrorLike, G as otlpSink, H as redactAttributes, J as redactText, K as toClientError } from './sinks-CIdlmYwy.cjs';
4
4
  import { Attributes } from '@opentelemetry/api';
5
5
 
6
6
  /**
@@ -198,8 +198,9 @@ type RuntimeContextHandle = typeof runtimeContext;
198
198
  * call)
199
199
  * successful traces : 1% (head sampling, configurable)
200
200
  * request metrics : aggregated every 60 s, keyed by route
201
- * template (Express routes detected
202
- * out of the box — see captureExpressRoute)
201
+ * template (Express and Next.js routes
202
+ * detected out of the box — see
203
+ * captureRequestRoute, route-label.ts)
203
204
  * operation / request summaries: 100% (withRuntimeOperation,
204
205
  * autterRequests, … — one wide
205
206
  * record per unit of work, never
@@ -226,6 +227,25 @@ interface AutterServerOptions {
226
227
  release?: string;
227
228
  /** Head-sampling ratio for regular traces. Default 0.01 (1%). */
228
229
  traceSampleRate?: number;
230
+ /**
231
+ * Share of captured errors reported, 0..1 (default 1: all). Applies to
232
+ * `captureException`, error-severity `captureMessage` and `reportOutcome`.
233
+ * Never samples out a fatal message, a crash (uncaught exception) or an
234
+ * unhandled rejection; warnings and info are never sampled. One thrown
235
+ * value is decided once, however many hooks report it. What is sampled
236
+ * out is not counted anywhere: for counted volume control use
237
+ * suppression rules in Autter (ingester 1.9.0). Not `traceSampleRate`,
238
+ * which samples healthy traces.
239
+ */
240
+ sampleRate?: number;
241
+ /**
242
+ * Errors never reported: strings match when the error's type or message
243
+ * contains them (case-sensitive), RegExps are tested against the type,
244
+ * the message and `"<type>: <message>"`. Applies to every capture path,
245
+ * crashes included. A request that failed still records its failed
246
+ * span and summary: leave those out with a suppression rule in Autter.
247
+ */
248
+ ignoreErrors?: IgnoreErrorPattern[];
229
249
  /**
230
250
  * Keep the FULL trace whenever it contains an error: an ERROR-status
231
251
  * span (e.g. a 5xx request), a recorded exception, or a
@@ -782,6 +802,10 @@ interface AutterLoggingOptions {
782
802
  * (use when the app's own spans are not exported to Autter).
783
803
  */
784
804
  exceptions?: "auto" | "log";
805
+ /** Same semantics as initAutterServer: share of captured errors reported (crashes never sampled). */
806
+ sampleRate?: number;
807
+ /** Same semantics as initAutterServer: errors never reported (type or message). */
808
+ ignoreErrors?: IgnoreErrorPattern[];
785
809
  }
786
810
  interface AutterLogging {
787
811
  captureException(error: unknown, attributes?: Attributes): void;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { IncomingMessage, ServerResponse } from 'node:http';
2
- import { b as RedactOptions, c as Redactor$1, d as RuntimeLogLevel, e as RuntimeOperationKind, f as RuntimeSink, F as FileSinkOptions, g as RuntimeLogContext, a as RuntimeOutcome, h as RuntimeCarrier, B as BreadcrumbInput } from './sinks-CPGDyfU8.js';
3
- export { i as Breadcrumb, j as BreadcrumbLevel, k as BreadcrumbType, l as CODE_PATTERN, n as ClientErrorBody, o as ConsoleSinkOptions, O as OtlpSinkOptions, p as RuntimeError, q as RuntimeErrorCatalog, r as RuntimeErrorDefinition, s as RuntimeErrorExtras, t as RuntimeErrorFactory, u as RuntimeErrorLike, v as RuntimeErrorOptions, R as RuntimeEvent, w as RuntimeLogContextValue, x as RuntimeSinkContext, y as consoleSink, z as defineRuntimeErrors, A as errorAttributes, D as fileSink, E as isRuntimeErrorLike, G as otlpSink, H as redactAttributes, I as redactText, J as toClientError } from './sinks-CPGDyfU8.js';
2
+ import { b as RedactOptions, c as Redactor$1, d as RuntimeLogLevel, e as RuntimeOperationKind, f as RuntimeSink, F as FileSinkOptions, g as RuntimeLogContext, a as RuntimeOutcome, h as RuntimeCarrier, I as IgnoreErrorPattern, B as BreadcrumbInput } from './sinks-CIdlmYwy.js';
3
+ export { i as Breadcrumb, j as BreadcrumbLevel, k as BreadcrumbType, l as CODE_PATTERN, n as ClientErrorBody, o as ConsoleSinkOptions, O as OtlpSinkOptions, p as RuntimeError, q as RuntimeErrorCatalog, r as RuntimeErrorDefinition, s as RuntimeErrorExtras, t as RuntimeErrorFactory, u as RuntimeErrorLike, v as RuntimeErrorOptions, R as RuntimeEvent, w as RuntimeLogContextValue, x as RuntimeSinkContext, y as consoleSink, z as defineRuntimeErrors, A as errorAttributes, D as fileSink, E as isRuntimeErrorLike, G as otlpSink, H as redactAttributes, J as redactText, K as toClientError } from './sinks-CIdlmYwy.js';
4
4
  import { Attributes } from '@opentelemetry/api';
5
5
 
6
6
  /**
@@ -198,8 +198,9 @@ type RuntimeContextHandle = typeof runtimeContext;
198
198
  * call)
199
199
  * successful traces : 1% (head sampling, configurable)
200
200
  * request metrics : aggregated every 60 s, keyed by route
201
- * template (Express routes detected
202
- * out of the box — see captureExpressRoute)
201
+ * template (Express and Next.js routes
202
+ * detected out of the box — see
203
+ * captureRequestRoute, route-label.ts)
203
204
  * operation / request summaries: 100% (withRuntimeOperation,
204
205
  * autterRequests, … — one wide
205
206
  * record per unit of work, never
@@ -226,6 +227,25 @@ interface AutterServerOptions {
226
227
  release?: string;
227
228
  /** Head-sampling ratio for regular traces. Default 0.01 (1%). */
228
229
  traceSampleRate?: number;
230
+ /**
231
+ * Share of captured errors reported, 0..1 (default 1: all). Applies to
232
+ * `captureException`, error-severity `captureMessage` and `reportOutcome`.
233
+ * Never samples out a fatal message, a crash (uncaught exception) or an
234
+ * unhandled rejection; warnings and info are never sampled. One thrown
235
+ * value is decided once, however many hooks report it. What is sampled
236
+ * out is not counted anywhere: for counted volume control use
237
+ * suppression rules in Autter (ingester 1.9.0). Not `traceSampleRate`,
238
+ * which samples healthy traces.
239
+ */
240
+ sampleRate?: number;
241
+ /**
242
+ * Errors never reported: strings match when the error's type or message
243
+ * contains them (case-sensitive), RegExps are tested against the type,
244
+ * the message and `"<type>: <message>"`. Applies to every capture path,
245
+ * crashes included. A request that failed still records its failed
246
+ * span and summary: leave those out with a suppression rule in Autter.
247
+ */
248
+ ignoreErrors?: IgnoreErrorPattern[];
229
249
  /**
230
250
  * Keep the FULL trace whenever it contains an error: an ERROR-status
231
251
  * span (e.g. a 5xx request), a recorded exception, or a
@@ -782,6 +802,10 @@ interface AutterLoggingOptions {
782
802
  * (use when the app's own spans are not exported to Autter).
783
803
  */
784
804
  exceptions?: "auto" | "log";
805
+ /** Same semantics as initAutterServer: share of captured errors reported (crashes never sampled). */
806
+ sampleRate?: number;
807
+ /** Same semantics as initAutterServer: errors never reported (type or message). */
808
+ ignoreErrors?: IgnoreErrorPattern[];
785
809
  }
786
810
  interface AutterLogging {
787
811
  captureException(error: unknown, attributes?: Attributes): void;
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  compileIgnore,
9
9
  configureRuntimeLogger,
10
10
  consoleSink,
11
+ createErrorFilter,
11
12
  createRequestState,
12
13
  createRuntimeLogger,
13
14
  currentOperation,
@@ -45,10 +46,10 @@ import {
45
46
  splitFingerprint,
46
47
  toClientError,
47
48
  withRuntimeOperation
48
- } from "./chunk-5KISVAVB.js";
49
+ } from "./chunk-QKY2OQSO.js";
49
50
  import {
50
51
  runDoctor
51
- } from "./chunk-L5ENELB2.js";
52
+ } from "./chunk-UC3QH4PC.js";
52
53
  import {
53
54
  COMPAT_MANIFEST,
54
55
  CountingExporter,
@@ -70,7 +71,7 @@ import {
70
71
  sharedSlot,
71
72
  telemetryStats,
72
73
  unregisterFlushTargets
73
- } from "./chunk-HRDELHZP.js";
74
+ } from "./chunk-B5ZMOCEM.js";
74
75
 
75
76
  // src/relay.ts
76
77
  var IpWindow = class {
@@ -441,6 +442,9 @@ function createBrowserRelayHandler(opts) {
441
442
  }
442
443
 
443
444
  // src/server.ts
445
+ import { errorMonitor } from "events";
446
+ import { createRequire } from "module";
447
+ import { join } from "path";
444
448
  import { ServerResponse } from "http";
445
449
  import { randomUUID } from "crypto";
446
450
  import {
@@ -450,7 +454,7 @@ import {
450
454
  SpanStatusCode,
451
455
  TraceFlags
452
456
  } from "@opentelemetry/api";
453
- import { getRPCMetadata as getRPCMetadata2, RPCType as RPCType2 } from "@opentelemetry/core";
457
+ import { getRPCMetadata as getRPCMetadata3, RPCType as RPCType3 } from "@opentelemetry/core";
454
458
  import {
455
459
  AggregationTemporalityPreference,
456
460
  OTLPMetricExporter
@@ -1276,6 +1280,40 @@ function installUnhandledRejectionCapture(capture, mode = unhandledRejectionsMod
1276
1280
  };
1277
1281
  }
1278
1282
 
1283
+ // src/route-label.ts
1284
+ import { getRPCMetadata as getRPCMetadata2, RPCType as RPCType2 } from "@opentelemetry/core";
1285
+ var ours = /* @__PURE__ */ new WeakMap();
1286
+ var RAW_PATH_SPAN_TYPES = /* @__PURE__ */ new Set(["BaseServer.renderToResponse"]);
1287
+ function noteFrameworkRoute(parent, attributes) {
1288
+ const route = attributes?.["next.route"];
1289
+ if (typeof route !== "string" || !route.startsWith("/")) return;
1290
+ if (RAW_PATH_SPAN_TYPES.has(String(attributes?.["next.span_type"] ?? ""))) return;
1291
+ const rpc = getRPCMetadata2(parent);
1292
+ if (!rpc || rpc.type !== RPCType2.HTTP) return;
1293
+ const mine = ours.get(rpc);
1294
+ if (rpc.route !== void 0 && rpc.route !== mine) return;
1295
+ if (mine !== void 0 && mine.includes("[") && !route.includes("[")) return;
1296
+ if (mine !== void 0 && (route === `${mine}/route` || route === `${mine}/page`)) return;
1297
+ rpc.route = route;
1298
+ ours.set(rpc, route);
1299
+ }
1300
+ var RouteLabelSampler = class {
1301
+ constructor(delegate) {
1302
+ this.delegate = delegate;
1303
+ }
1304
+ delegate;
1305
+ shouldSample(ctx, traceId, spanName, spanKind, attributes, links) {
1306
+ try {
1307
+ noteFrameworkRoute(ctx, attributes);
1308
+ } catch {
1309
+ }
1310
+ return this.delegate.shouldSample(ctx, traceId, spanName, spanKind, attributes, links);
1311
+ }
1312
+ toString() {
1313
+ return `RouteLabel(${this.delegate.toString()})`;
1314
+ }
1315
+ };
1316
+
1279
1317
  // src/server.ts
1280
1318
  var S = sharedSlot("server", () => ({
1281
1319
  active: null,
@@ -1597,17 +1635,33 @@ function recordError(span, err) {
1597
1635
  function redactWithActive(attributes) {
1598
1636
  return S.redactor(attributes);
1599
1637
  }
1600
- function captureExpressRoute(_span, response) {
1638
+ function patchLoadedHttpModules() {
1639
+ try {
1640
+ const load = createRequire(join(process.cwd(), "autter-runtime-http.cjs"));
1641
+ load("http");
1642
+ load("https");
1643
+ } catch {
1644
+ }
1645
+ }
1646
+ var METRIC_ROUTE_ATTR = "autter.metric_has_route";
1647
+ function captureRequestRoute(span, response) {
1601
1648
  if (!(response instanceof ServerResponse)) return;
1602
- const rpcMetadata = getRPCMetadata2(context2.active());
1603
- if (rpcMetadata?.type !== RPCType2.HTTP) return;
1649
+ const rpcMetadata = getRPCMetadata3(context2.active());
1650
+ if (rpcMetadata?.type !== RPCType3.HTTP) return;
1651
+ let failed = false;
1652
+ response.on(errorMonitor, () => {
1653
+ failed = true;
1654
+ });
1604
1655
  const setRoute = () => {
1605
1656
  if (rpcMetadata.route) return;
1606
1657
  const route = expressRouteOf(response.req);
1607
1658
  if (route) rpcMetadata.route = route;
1608
1659
  };
1609
1660
  response.prependListener("finish", setRoute);
1610
- response.prependListener("close", setRoute);
1661
+ response.prependListener("close", () => {
1662
+ setRoute();
1663
+ if (rpcMetadata.route && !failed) span.setAttribute(METRIC_ROUTE_ATTR, true);
1664
+ });
1611
1665
  if (S.hookRequests) startHookRequest(response);
1612
1666
  }
1613
1667
  function structuredErrorAttributes(error) {
@@ -1656,9 +1710,16 @@ function initAutterServer(options) {
1656
1710
  "telemetry.distro.version": distro.version,
1657
1711
  // Tells the ingester request metrics arrive on the metrics pipe, so
1658
1712
  // it must not also fold our server spans into usage rollups (that
1659
- // would double-count every sampled request).
1660
- "autter.metrics_wired": true
1713
+ // would double-count every sampled request)...
1714
+ "autter.metrics_wired": true,
1715
+ // ...for the requests whose metric carries their route: those
1716
+ // request spans say so (`autter.metric_has_route`, see
1717
+ // captureRequestRoute). Ingesters honour metrics_wired only with
1718
+ // this, so an older SDK, whose Next.js metrics have no route, keeps
1719
+ // its span-fed per-route counts.
1720
+ "autter.metrics_routes": true
1661
1721
  });
1722
+ const errorFilter = createErrorFilter({ ignoreErrors: options.ignoreErrors, sampleRate: options.sampleRate });
1662
1723
  const rootSampler = new TraceIdRatioBasedSampler(options.traceSampleRate ?? 0.01);
1663
1724
  const headSampler = new ParentBasedSampler({
1664
1725
  root: rootSampler,
@@ -1674,6 +1735,7 @@ function initAutterServer(options) {
1674
1735
  const retainTraces = retainOnError || slowThresholdMs > 0;
1675
1736
  let sampler = retainTraces ? new RecordUnsampledSampler(headSampler) : headSampler;
1676
1737
  if (options.llmTracing !== false) sampler = new LlmAwareSampler(sampler);
1738
+ sampler = new RouteLabelSampler(sampler);
1677
1739
  const errorTraceBuffer = retainTraces ? new ErrorTraceRetentionProcessor(
1678
1740
  new BatchSpanProcessor(traceExporter(), { scheduledDelayMillis: 2e3 }),
1679
1741
  retainOnError,
@@ -1712,11 +1774,12 @@ function initAutterServer(options) {
1712
1774
  ) })
1713
1775
  ],
1714
1776
  instrumentations: [
1715
- new HttpInstrumentation({ responseHook: captureExpressRoute }),
1777
+ new HttpInstrumentation({ responseHook: captureRequestRoute }),
1716
1778
  ...options.instrumentations ?? []
1717
1779
  ]
1718
1780
  });
1719
1781
  sdk.start();
1782
+ patchLoadedHttpModules();
1720
1783
  const stopMemoryMetrics = options.memoryMetrics === false ? null : startMemoryMetrics();
1721
1784
  noteCompatFeature("endpoint_latency");
1722
1785
  if (stopMemoryMetrics) noteCompatFeature("memory_metrics");
@@ -1732,6 +1795,16 @@ function initAutterServer(options) {
1732
1795
  const processTracer = alwaysOnProvider.getTracer("autter-processes");
1733
1796
  const llmTracer = alwaysOnProvider.getTracer("autter-llm");
1734
1797
  function captureException2(error, attributes) {
1798
+ const isErrValue = isError(error);
1799
+ const reported = errorFilter({
1800
+ type: isErrValue ? String(error.name ?? "") : "Error",
1801
+ message: isErrValue ? String(error.message ?? "") : String(error),
1802
+ crash: attributes?.["autter.unhandled"] === true || attributes?.["autter.unhandled_rejection"] === true
1803
+ });
1804
+ if (!reported) {
1805
+ markCaptured(error);
1806
+ return;
1807
+ }
1735
1808
  errorTraceBuffer?.retainActiveTrace();
1736
1809
  telemetryStats.markCaptured();
1737
1810
  const isErr = isError(error);
@@ -1784,6 +1857,7 @@ function initAutterServer(options) {
1784
1857
  if (!reuseActive) span.end();
1785
1858
  }
1786
1859
  function captureMessage2(message, severity = "warning", attributes) {
1860
+ if (!errorFilter({ type: "Message", message: String(message), severity })) return;
1787
1861
  if (severity === "error" || severity === "fatal") {
1788
1862
  errorTraceBuffer?.retainActiveTrace();
1789
1863
  }
@@ -1804,6 +1878,7 @@ function initAutterServer(options) {
1804
1878
  span.end();
1805
1879
  }
1806
1880
  function reportOutcome2(name, message, attributes) {
1881
+ if (!errorFilter({ type: "OutcomeFailure", message: `${name}: ${message}` })) return;
1807
1882
  errorTraceBuffer?.retainActiveTrace();
1808
1883
  telemetryStats.markCaptured();
1809
1884
  const activeSpan = trace2.getActiveSpan();
@@ -2357,8 +2432,16 @@ function initAutterLogging(options) {
2357
2432
  const redact = makeRedactor(options.redactAttributes ?? true);
2358
2433
  const mode = options.exceptions ?? "auto";
2359
2434
  debugLog(`initialising logger-only service=${options.service} endpoint=${endpoint}`);
2435
+ const errorFilter = createErrorFilter({ ignoreErrors: options.ignoreErrors, sampleRate: options.sampleRate });
2360
2436
  function captureException2(error, attributes) {
2361
2437
  markCaptured(error);
2438
+ const isErrValue = isError(error);
2439
+ const reported = errorFilter({
2440
+ type: isErrValue ? String(error.name ?? "") : "Error",
2441
+ message: isErrValue ? String(error.message ?? "") : String(error),
2442
+ crash: attributes?.["autter.unhandled"] === true || attributes?.["autter.unhandled_rejection"] === true
2443
+ });
2444
+ if (!reported) return;
2362
2445
  const split = splitFingerprint(attributes);
2363
2446
  const fingerprint = fingerprintEventAttributes(split.fingerprint, redact.text);
2364
2447
  const redacted = redact(split.attributes);
@@ -250,6 +250,26 @@ interface BreadcrumbInput {
250
250
  at?: string | number | Date;
251
251
  }
252
252
 
253
+ /**
254
+ * Client-side volume control shared by the server SDKs (runtime-node,
255
+ * runtime-edge; 1.8.0 / 1.2.0, EI-38): `ignoreErrors` and `sampleRate`.
256
+ * The browser has its own copy in `@autter/runtime-browser/filters`.
257
+ *
258
+ * - `ignoreErrors`: strings or RegExps. A string matches when the error's
259
+ * type or message contains it (case-sensitive, like the message itself);
260
+ * a RegExp is tested against the type, the message and
261
+ * `"<type>: <message>"`. A match is never reported, whatever its severity.
262
+ * - `sampleRate`: 0..1, the share of errors reported. Errors only: warnings
263
+ * and info messages are never sampled, and neither is a fatal error, a
264
+ * crash (uncaught exception) or an unhandled rejection, which may be one.
265
+ * Out of range or not a number: everything is reported.
266
+ *
267
+ * What is filtered here never leaves the process and is counted nowhere.
268
+ * To leave errors out of every SDK at once, and see how many were left out,
269
+ * use suppression rules in Autter (applied by the ingester, 1.9.0).
270
+ */
271
+ type IgnoreErrorPattern = string | RegExp;
272
+
253
273
  /**
254
274
  * Where runtime records go. The logger pipeline is
255
275
  * `enrich → redact/bound → sinks[]`; each sink receives the same immutable
@@ -338,4 +358,4 @@ interface MemorySink extends RuntimeSink {
338
358
  /** Keeps every record in memory — for tests (`@autter/runtime-node/testing`). */
339
359
  declare function memorySink(): MemorySink;
340
360
 
341
- export { errorAttributes as A, type BreadcrumbInput as B, type CapturedException as C, fileSink as D, isRuntimeErrorLike as E, type FileSinkOptions as F, otlpSink as G, redactAttributes as H, redactText as I, toClientError as J, type MemorySink as M, type OtlpSinkOptions as O, type RuntimeEvent as R, type RuntimeOutcome as a, type RedactOptions as b, type Redactor$1 as c, type RuntimeLogLevel as d, type RuntimeOperationKind as e, type RuntimeSink as f, type RuntimeLogContext as g, type RuntimeCarrier as h, type Breadcrumb as i, type BreadcrumbLevel as j, type BreadcrumbType as k, CODE_PATTERN as l, memorySink as m, type ClientErrorBody as n, type ConsoleSinkOptions as o, RuntimeError as p, type RuntimeErrorCatalog as q, type RuntimeErrorDefinition as r, type RuntimeErrorExtras as s, type RuntimeErrorFactory as t, type RuntimeErrorLike as u, type RuntimeErrorOptions as v, type RuntimeLogContextValue as w, type RuntimeSinkContext as x, consoleSink as y, defineRuntimeErrors as z };
361
+ export { errorAttributes as A, type BreadcrumbInput as B, type CapturedException as C, fileSink as D, isRuntimeErrorLike as E, type FileSinkOptions as F, otlpSink as G, redactAttributes as H, type IgnoreErrorPattern as I, redactText as J, toClientError as K, type MemorySink as M, type OtlpSinkOptions as O, type RuntimeEvent as R, type RuntimeOutcome as a, type RedactOptions as b, type Redactor$1 as c, type RuntimeLogLevel as d, type RuntimeOperationKind as e, type RuntimeSink as f, type RuntimeLogContext as g, type RuntimeCarrier as h, type Breadcrumb as i, type BreadcrumbLevel as j, type BreadcrumbType as k, CODE_PATTERN as l, memorySink as m, type ClientErrorBody as n, type ConsoleSinkOptions as o, RuntimeError as p, type RuntimeErrorCatalog as q, type RuntimeErrorDefinition as r, type RuntimeErrorExtras as s, type RuntimeErrorFactory as t, type RuntimeErrorLike as u, type RuntimeErrorOptions as v, type RuntimeLogContextValue as w, type RuntimeSinkContext as x, consoleSink as y, defineRuntimeErrors as z };
@@ -250,6 +250,26 @@ interface BreadcrumbInput {
250
250
  at?: string | number | Date;
251
251
  }
252
252
 
253
+ /**
254
+ * Client-side volume control shared by the server SDKs (runtime-node,
255
+ * runtime-edge; 1.8.0 / 1.2.0, EI-38): `ignoreErrors` and `sampleRate`.
256
+ * The browser has its own copy in `@autter/runtime-browser/filters`.
257
+ *
258
+ * - `ignoreErrors`: strings or RegExps. A string matches when the error's
259
+ * type or message contains it (case-sensitive, like the message itself);
260
+ * a RegExp is tested against the type, the message and
261
+ * `"<type>: <message>"`. A match is never reported, whatever its severity.
262
+ * - `sampleRate`: 0..1, the share of errors reported. Errors only: warnings
263
+ * and info messages are never sampled, and neither is a fatal error, a
264
+ * crash (uncaught exception) or an unhandled rejection, which may be one.
265
+ * Out of range or not a number: everything is reported.
266
+ *
267
+ * What is filtered here never leaves the process and is counted nowhere.
268
+ * To leave errors out of every SDK at once, and see how many were left out,
269
+ * use suppression rules in Autter (applied by the ingester, 1.9.0).
270
+ */
271
+ type IgnoreErrorPattern = string | RegExp;
272
+
253
273
  /**
254
274
  * Where runtime records go. The logger pipeline is
255
275
  * `enrich → redact/bound → sinks[]`; each sink receives the same immutable
@@ -338,4 +358,4 @@ interface MemorySink extends RuntimeSink {
338
358
  /** Keeps every record in memory — for tests (`@autter/runtime-node/testing`). */
339
359
  declare function memorySink(): MemorySink;
340
360
 
341
- export { errorAttributes as A, type BreadcrumbInput as B, type CapturedException as C, fileSink as D, isRuntimeErrorLike as E, type FileSinkOptions as F, otlpSink as G, redactAttributes as H, redactText as I, toClientError as J, type MemorySink as M, type OtlpSinkOptions as O, type RuntimeEvent as R, type RuntimeOutcome as a, type RedactOptions as b, type Redactor$1 as c, type RuntimeLogLevel as d, type RuntimeOperationKind as e, type RuntimeSink as f, type RuntimeLogContext as g, type RuntimeCarrier as h, type Breadcrumb as i, type BreadcrumbLevel as j, type BreadcrumbType as k, CODE_PATTERN as l, memorySink as m, type ClientErrorBody as n, type ConsoleSinkOptions as o, RuntimeError as p, type RuntimeErrorCatalog as q, type RuntimeErrorDefinition as r, type RuntimeErrorExtras as s, type RuntimeErrorFactory as t, type RuntimeErrorLike as u, type RuntimeErrorOptions as v, type RuntimeLogContextValue as w, type RuntimeSinkContext as x, consoleSink as y, defineRuntimeErrors as z };
361
+ export { errorAttributes as A, type BreadcrumbInput as B, type CapturedException as C, fileSink as D, isRuntimeErrorLike as E, type FileSinkOptions as F, otlpSink as G, redactAttributes as H, type IgnoreErrorPattern as I, redactText as J, toClientError as K, type MemorySink as M, type OtlpSinkOptions as O, type RuntimeEvent as R, type RuntimeOutcome as a, type RedactOptions as b, type Redactor$1 as c, type RuntimeLogLevel as d, type RuntimeOperationKind as e, type RuntimeSink as f, type RuntimeLogContext as g, type RuntimeCarrier as h, type Breadcrumb as i, type BreadcrumbLevel as j, type BreadcrumbType as k, CODE_PATTERN as l, memorySink as m, type ClientErrorBody as n, type ConsoleSinkOptions as o, RuntimeError as p, type RuntimeErrorCatalog as q, type RuntimeErrorDefinition as r, type RuntimeErrorExtras as s, type RuntimeErrorFactory as t, type RuntimeErrorLike as u, type RuntimeErrorOptions as v, type RuntimeLogContextValue as w, type RuntimeSinkContext as x, consoleSink as y, defineRuntimeErrors as z };
package/dist/testing.cjs CHANGED
@@ -2,22 +2,22 @@
2
2
 
3
3
 
4
4
 
5
- var _chunkUXTIMS3Gcjs = require('./chunk-UXTIMS3G.cjs');
6
- require('./chunk-4MVWIRBI.cjs');
5
+ var _chunk37W7YYXOcjs = require('./chunk-37W7YYXO.cjs');
6
+ require('./chunk-MOZOUEMA.cjs');
7
7
 
8
8
  // src/testing.ts
9
9
  function captureRuntime() {
10
- const sink = _chunkUXTIMS3Gcjs.memorySink.call(void 0, );
11
- const remove = _chunkUXTIMS3Gcjs.addRuntimeSink.call(void 0, sink);
10
+ const sink = _chunk37W7YYXOcjs.memorySink.call(void 0, );
11
+ const remove = _chunk37W7YYXOcjs.addRuntimeSink.call(void 0, sink);
12
12
  return {
13
13
  get events() {
14
14
  return [...sink.events];
15
15
  },
16
16
  get operations() {
17
- return sink.events.filter(_chunkUXTIMS3Gcjs.isSummary);
17
+ return sink.events.filter(_chunk37W7YYXOcjs.isSummary);
18
18
  },
19
19
  get logs() {
20
- return sink.events.filter((event) => !_chunkUXTIMS3Gcjs.isSummary.call(void 0, event));
20
+ return sink.events.filter((event) => !_chunk37W7YYXOcjs.isSummary.call(void 0, event));
21
21
  },
22
22
  get exceptions() {
23
23
  return [...sink.exceptions];
@@ -98,7 +98,7 @@ var OperationExpectation = class {
98
98
  }
99
99
  };
100
100
  function expectOperation(source, name) {
101
- const events = Array.isArray(source) ? source.filter(_chunkUXTIMS3Gcjs.isSummary) : source.operations;
101
+ const events = Array.isArray(source) ? source.filter(_chunk37W7YYXOcjs.isSummary) : source.operations;
102
102
  const matches = events.filter((event2) => {
103
103
  const actual = String(_nullishCoalesce(event2.attributes["autter.operation.name"], () => ( "")));
104
104
  return typeof name === "string" ? actual === name : name.test(actual);
@@ -118,4 +118,4 @@ function expectOperation(source, name) {
118
118
 
119
119
 
120
120
 
121
- exports.captureRuntime = captureRuntime; exports.expectOperation = expectOperation; exports.memorySink = _chunkUXTIMS3Gcjs.memorySink;
121
+ exports.captureRuntime = captureRuntime; exports.expectOperation = expectOperation; exports.memorySink = _chunk37W7YYXOcjs.memorySink;
@@ -1,5 +1,5 @@
1
- import { R as RuntimeEvent, a as RuntimeOutcome, C as CapturedException } from './sinks-CPGDyfU8.cjs';
2
- export { M as MemorySink, m as memorySink } from './sinks-CPGDyfU8.cjs';
1
+ import { R as RuntimeEvent, a as RuntimeOutcome, C as CapturedException } from './sinks-CIdlmYwy.cjs';
2
+ export { M as MemorySink, m as memorySink } from './sinks-CIdlmYwy.cjs';
3
3
 
4
4
  /**
5
5
  * Test helpers — `@autter/runtime-node/testing`. No ingester, no network:
package/dist/testing.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { R as RuntimeEvent, a as RuntimeOutcome, C as CapturedException } from './sinks-CPGDyfU8.js';
2
- export { M as MemorySink, m as memorySink } from './sinks-CPGDyfU8.js';
1
+ import { R as RuntimeEvent, a as RuntimeOutcome, C as CapturedException } from './sinks-CIdlmYwy.js';
2
+ export { M as MemorySink, m as memorySink } from './sinks-CIdlmYwy.js';
3
3
 
4
4
  /**
5
5
  * Test helpers — `@autter/runtime-node/testing`. No ingester, no network:
package/dist/testing.js CHANGED
@@ -2,8 +2,8 @@ import {
2
2
  addRuntimeSink,
3
3
  isSummary,
4
4
  memorySink
5
- } from "./chunk-5KISVAVB.js";
6
- import "./chunk-HRDELHZP.js";
5
+ } from "./chunk-QKY2OQSO.js";
6
+ import "./chunk-B5ZMOCEM.js";
7
7
 
8
8
  // src/testing.ts
9
9
  function captureRuntime() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autter/runtime-node",
3
- "version": "1.6.1",
3
+ "version": "1.8.0",
4
4
  "description": "Autter Runtime for Node.js: request wide events, coded errors, operation logging, same-origin browser relay and a curated OpenTelemetry server tracker",
5
5
  "license": "MIT",
6
6
  "type": "module",