@autter/runtime-node 1.2.1 → 1.3.1
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.cjs +27 -5
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +28 -6
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -238,6 +238,7 @@ function createBrowserRelayHandler(opts) {
|
|
|
238
238
|
|
|
239
239
|
// src/server.ts
|
|
240
240
|
var import_node_http = require("http");
|
|
241
|
+
var import_node_crypto = require("crypto");
|
|
241
242
|
var import_api = require("@opentelemetry/api");
|
|
242
243
|
var import_core2 = require("@opentelemetry/core");
|
|
243
244
|
var import_exporter_metrics_otlp_http = require("@opentelemetry/exporter-metrics-otlp-http");
|
|
@@ -764,12 +765,16 @@ function withSampledFlag(span) {
|
|
|
764
765
|
};
|
|
765
766
|
}
|
|
766
767
|
var ErrorTraceRetentionProcessor = class {
|
|
767
|
-
constructor(inner) {
|
|
768
|
+
constructor(inner, retainErrors = true, slowThresholdMs = 0) {
|
|
768
769
|
this.inner = inner;
|
|
770
|
+
this.retainErrors = retainErrors;
|
|
771
|
+
this.slowThresholdMs = slowThresholdMs;
|
|
769
772
|
this.sweeper = setInterval(() => this.sweep(), RETENTION_SWEEP_INTERVAL_MS);
|
|
770
773
|
this.sweeper.unref?.();
|
|
771
774
|
}
|
|
772
775
|
inner;
|
|
776
|
+
retainErrors;
|
|
777
|
+
slowThresholdMs;
|
|
773
778
|
traces = /* @__PURE__ */ new Map();
|
|
774
779
|
bufferedSpans = 0;
|
|
775
780
|
sweeper;
|
|
@@ -781,7 +786,7 @@ var ErrorTraceRetentionProcessor = class {
|
|
|
781
786
|
const entry = this.entryFor(ctx.traceId);
|
|
782
787
|
if (entry.retained) {
|
|
783
788
|
this.forward(span);
|
|
784
|
-
} else if (spanIndicatesError(span)) {
|
|
789
|
+
} else if (this.retainErrors && spanIndicatesError(span) || this.slowThresholdMs > 0 && span.kind === import_api.SpanKind.SERVER && span.duration[0] * 1e3 + span.duration[1] / 1e6 >= this.slowThresholdMs) {
|
|
785
790
|
entry.retained = true;
|
|
786
791
|
this.flush(entry);
|
|
787
792
|
this.forward(span);
|
|
@@ -815,6 +820,10 @@ var ErrorTraceRetentionProcessor = class {
|
|
|
815
820
|
entryFor(traceId) {
|
|
816
821
|
let entry = this.traces.get(traceId);
|
|
817
822
|
if (!entry) {
|
|
823
|
+
if (this.traces.size >= RETENTION_MAX_BUFFERED_SPANS) {
|
|
824
|
+
const oldest = this.traces.keys().next().value;
|
|
825
|
+
if (oldest) this.drop(oldest);
|
|
826
|
+
}
|
|
818
827
|
entry = { spans: [], retained: false, firstSeenAtMs: Date.now() };
|
|
819
828
|
this.traces.set(traceId, entry);
|
|
820
829
|
}
|
|
@@ -996,6 +1005,7 @@ function initAutterServer(options) {
|
|
|
996
1005
|
activeRedactor = makeRedactor(options.redactAttributes ?? true);
|
|
997
1006
|
const resource = new import_resources.Resource({
|
|
998
1007
|
[import_semantic_conventions.ATTR_SERVICE_NAME]: options.service,
|
|
1008
|
+
"service.instance.id": (0, import_node_crypto.randomUUID)(),
|
|
999
1009
|
...options.release ? { [import_semantic_conventions.ATTR_SERVICE_VERSION]: options.release } : {},
|
|
1000
1010
|
"deployment.environment": environment,
|
|
1001
1011
|
// Tells the ingester request metrics arrive on the metrics pipe, so
|
|
@@ -1007,15 +1017,19 @@ function initAutterServer(options) {
|
|
|
1007
1017
|
root: new import_sdk_trace_base.TraceIdRatioBasedSampler(options.traceSampleRate ?? 0.01)
|
|
1008
1018
|
});
|
|
1009
1019
|
const retainOnError = options.retainTracesOnError !== false;
|
|
1010
|
-
|
|
1020
|
+
const slowThresholdMs = Number.isFinite(options.retainTracesAboveMs) ? Math.max(0, options.retainTracesAboveMs) : 0;
|
|
1021
|
+
const retainTraces = retainOnError || slowThresholdMs > 0;
|
|
1022
|
+
let sampler = retainTraces ? new RecordUnsampledSampler(headSampler) : headSampler;
|
|
1011
1023
|
if (options.llmTracing !== false) sampler = new LlmAwareSampler(sampler);
|
|
1012
|
-
const errorTraceBuffer =
|
|
1024
|
+
const errorTraceBuffer = retainTraces ? new ErrorTraceRetentionProcessor(
|
|
1013
1025
|
new import_sdk_trace_base.BatchSpanProcessor(
|
|
1014
1026
|
new CountingExporter(
|
|
1015
1027
|
new import_exporter_trace_otlp_http.OTLPTraceExporter({ url: `${endpoint}/v1/traces`, headers })
|
|
1016
1028
|
),
|
|
1017
1029
|
{ scheduledDelayMillis: 2e3 }
|
|
1018
|
-
)
|
|
1030
|
+
),
|
|
1031
|
+
retainOnError,
|
|
1032
|
+
slowThresholdMs
|
|
1019
1033
|
) : null;
|
|
1020
1034
|
const mainSpanProcessor = new import_sdk_trace_base.BatchSpanProcessor(
|
|
1021
1035
|
new CountingExporter(
|
|
@@ -1042,6 +1056,14 @@ function initAutterServer(options) {
|
|
|
1042
1056
|
...errorTraceBuffer ? [errorTraceBuffer] : []
|
|
1043
1057
|
],
|
|
1044
1058
|
metricReader,
|
|
1059
|
+
views: [
|
|
1060
|
+
new import_sdk_metrics.View({ instrumentName: "http.server.duration", aggregation: new import_sdk_metrics.ExplicitBucketHistogramAggregation(
|
|
1061
|
+
[5, 10, 25, 50, 100, 250, 500, 750, 1e3, 1500, 2e3, 3e3, 5e3, 7500, 1e4, 15e3, 2e4, 3e4, 6e4, 12e4]
|
|
1062
|
+
) }),
|
|
1063
|
+
new import_sdk_metrics.View({ instrumentName: "http.server.request.duration", aggregation: new import_sdk_metrics.ExplicitBucketHistogramAggregation(
|
|
1064
|
+
[5e-3, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 0.75, 1, 1.5, 2, 3, 5, 7.5, 10, 15, 20, 30, 60, 120]
|
|
1065
|
+
) })
|
|
1066
|
+
],
|
|
1045
1067
|
instrumentations: [
|
|
1046
1068
|
new import_instrumentation_http.HttpInstrumentation({ responseHook: captureExpressRoute }),
|
|
1047
1069
|
...options.instrumentations ?? []
|
package/dist/index.d.cts
CHANGED
|
@@ -116,6 +116,7 @@ interface AutterServerOptions {
|
|
|
116
116
|
* Default true.
|
|
117
117
|
*/
|
|
118
118
|
retainTracesOnError?: boolean;
|
|
119
|
+
retainTracesAboveMs?: number;
|
|
119
120
|
/** Metric export interval. Default 60_000 ms. */
|
|
120
121
|
metricIntervalMs?: number;
|
|
121
122
|
/** Capture crashing exceptions via process.uncaughtExceptionMonitor (default true). */
|
package/dist/index.d.ts
CHANGED
|
@@ -116,6 +116,7 @@ interface AutterServerOptions {
|
|
|
116
116
|
* Default true.
|
|
117
117
|
*/
|
|
118
118
|
retainTracesOnError?: boolean;
|
|
119
|
+
retainTracesAboveMs?: number;
|
|
119
120
|
/** Metric export interval. Default 60_000 ms. */
|
|
120
121
|
metricIntervalMs?: number;
|
|
121
122
|
/** Capture crashing exceptions via process.uncaughtExceptionMonitor (default true). */
|
package/dist/index.js
CHANGED
|
@@ -199,6 +199,7 @@ function createBrowserRelayHandler(opts) {
|
|
|
199
199
|
|
|
200
200
|
// src/server.ts
|
|
201
201
|
import { ServerResponse } from "http";
|
|
202
|
+
import { randomUUID } from "crypto";
|
|
202
203
|
import {
|
|
203
204
|
context,
|
|
204
205
|
trace,
|
|
@@ -214,7 +215,7 @@ import {
|
|
|
214
215
|
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
215
216
|
import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
|
|
216
217
|
import { Resource } from "@opentelemetry/resources";
|
|
217
|
-
import { PeriodicExportingMetricReader } from "@opentelemetry/sdk-metrics";
|
|
218
|
+
import { ExplicitBucketHistogramAggregation, PeriodicExportingMetricReader, View } from "@opentelemetry/sdk-metrics";
|
|
218
219
|
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
219
220
|
import {
|
|
220
221
|
BatchSpanProcessor,
|
|
@@ -744,12 +745,16 @@ function withSampledFlag(span) {
|
|
|
744
745
|
};
|
|
745
746
|
}
|
|
746
747
|
var ErrorTraceRetentionProcessor = class {
|
|
747
|
-
constructor(inner) {
|
|
748
|
+
constructor(inner, retainErrors = true, slowThresholdMs = 0) {
|
|
748
749
|
this.inner = inner;
|
|
750
|
+
this.retainErrors = retainErrors;
|
|
751
|
+
this.slowThresholdMs = slowThresholdMs;
|
|
749
752
|
this.sweeper = setInterval(() => this.sweep(), RETENTION_SWEEP_INTERVAL_MS);
|
|
750
753
|
this.sweeper.unref?.();
|
|
751
754
|
}
|
|
752
755
|
inner;
|
|
756
|
+
retainErrors;
|
|
757
|
+
slowThresholdMs;
|
|
753
758
|
traces = /* @__PURE__ */ new Map();
|
|
754
759
|
bufferedSpans = 0;
|
|
755
760
|
sweeper;
|
|
@@ -761,7 +766,7 @@ var ErrorTraceRetentionProcessor = class {
|
|
|
761
766
|
const entry = this.entryFor(ctx.traceId);
|
|
762
767
|
if (entry.retained) {
|
|
763
768
|
this.forward(span);
|
|
764
|
-
} else if (spanIndicatesError(span)) {
|
|
769
|
+
} else if (this.retainErrors && spanIndicatesError(span) || this.slowThresholdMs > 0 && span.kind === SpanKind.SERVER && span.duration[0] * 1e3 + span.duration[1] / 1e6 >= this.slowThresholdMs) {
|
|
765
770
|
entry.retained = true;
|
|
766
771
|
this.flush(entry);
|
|
767
772
|
this.forward(span);
|
|
@@ -795,6 +800,10 @@ var ErrorTraceRetentionProcessor = class {
|
|
|
795
800
|
entryFor(traceId) {
|
|
796
801
|
let entry = this.traces.get(traceId);
|
|
797
802
|
if (!entry) {
|
|
803
|
+
if (this.traces.size >= RETENTION_MAX_BUFFERED_SPANS) {
|
|
804
|
+
const oldest = this.traces.keys().next().value;
|
|
805
|
+
if (oldest) this.drop(oldest);
|
|
806
|
+
}
|
|
798
807
|
entry = { spans: [], retained: false, firstSeenAtMs: Date.now() };
|
|
799
808
|
this.traces.set(traceId, entry);
|
|
800
809
|
}
|
|
@@ -976,6 +985,7 @@ function initAutterServer(options) {
|
|
|
976
985
|
activeRedactor = makeRedactor(options.redactAttributes ?? true);
|
|
977
986
|
const resource = new Resource({
|
|
978
987
|
[ATTR_SERVICE_NAME]: options.service,
|
|
988
|
+
"service.instance.id": randomUUID(),
|
|
979
989
|
...options.release ? { [ATTR_SERVICE_VERSION]: options.release } : {},
|
|
980
990
|
"deployment.environment": environment,
|
|
981
991
|
// Tells the ingester request metrics arrive on the metrics pipe, so
|
|
@@ -987,15 +997,19 @@ function initAutterServer(options) {
|
|
|
987
997
|
root: new TraceIdRatioBasedSampler(options.traceSampleRate ?? 0.01)
|
|
988
998
|
});
|
|
989
999
|
const retainOnError = options.retainTracesOnError !== false;
|
|
990
|
-
|
|
1000
|
+
const slowThresholdMs = Number.isFinite(options.retainTracesAboveMs) ? Math.max(0, options.retainTracesAboveMs) : 0;
|
|
1001
|
+
const retainTraces = retainOnError || slowThresholdMs > 0;
|
|
1002
|
+
let sampler = retainTraces ? new RecordUnsampledSampler(headSampler) : headSampler;
|
|
991
1003
|
if (options.llmTracing !== false) sampler = new LlmAwareSampler(sampler);
|
|
992
|
-
const errorTraceBuffer =
|
|
1004
|
+
const errorTraceBuffer = retainTraces ? new ErrorTraceRetentionProcessor(
|
|
993
1005
|
new BatchSpanProcessor(
|
|
994
1006
|
new CountingExporter(
|
|
995
1007
|
new OTLPTraceExporter({ url: `${endpoint}/v1/traces`, headers })
|
|
996
1008
|
),
|
|
997
1009
|
{ scheduledDelayMillis: 2e3 }
|
|
998
|
-
)
|
|
1010
|
+
),
|
|
1011
|
+
retainOnError,
|
|
1012
|
+
slowThresholdMs
|
|
999
1013
|
) : null;
|
|
1000
1014
|
const mainSpanProcessor = new BatchSpanProcessor(
|
|
1001
1015
|
new CountingExporter(
|
|
@@ -1022,6 +1036,14 @@ function initAutterServer(options) {
|
|
|
1022
1036
|
...errorTraceBuffer ? [errorTraceBuffer] : []
|
|
1023
1037
|
],
|
|
1024
1038
|
metricReader,
|
|
1039
|
+
views: [
|
|
1040
|
+
new View({ instrumentName: "http.server.duration", aggregation: new ExplicitBucketHistogramAggregation(
|
|
1041
|
+
[5, 10, 25, 50, 100, 250, 500, 750, 1e3, 1500, 2e3, 3e3, 5e3, 7500, 1e4, 15e3, 2e4, 3e4, 6e4, 12e4]
|
|
1042
|
+
) }),
|
|
1043
|
+
new View({ instrumentName: "http.server.request.duration", aggregation: new ExplicitBucketHistogramAggregation(
|
|
1044
|
+
[5e-3, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 0.75, 1, 1.5, 2, 3, 5, 7.5, 10, 15, 20, 30, 60, 120]
|
|
1045
|
+
) })
|
|
1046
|
+
],
|
|
1025
1047
|
instrumentations: [
|
|
1026
1048
|
new HttpInstrumentation({ responseHook: captureExpressRoute }),
|
|
1027
1049
|
...options.instrumentations ?? []
|
package/package.json
CHANGED