@ryanzeng/nest-observe 0.1.1 → 0.1.2
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 +27 -1
- package/dist/index.d.mts +42 -15
- package/dist/index.d.ts +42 -15
- package/dist/index.js +347 -37
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +353 -39
- package/dist/index.mjs.map +1 -1
- package/dist/register.js +313 -40
- package/dist/register.js.map +1 -1
- package/dist/register.mjs +313 -40
- package/dist/register.mjs.map +1 -1
- package/package.json +19 -9
package/dist/register.js
CHANGED
|
@@ -93,15 +93,14 @@ function resolveObserveConfig(options = {}, env = process.env) {
|
|
|
93
93
|
allowedHeaders,
|
|
94
94
|
exportTimeoutMillis: positiveInteger(options.exportTimeoutMillis ?? env.OTEL_EXPORTER_OTLP_TIMEOUT, 1e4),
|
|
95
95
|
metricExportIntervalMillis: positiveInteger(options.metricExportIntervalMillis ?? env.OTEL_METRIC_EXPORT_INTERVAL, 6e4),
|
|
96
|
-
resourceAttributes
|
|
96
|
+
resourceAttributes,
|
|
97
|
+
diagnosticLogging: booleanValue(options.diagnosticLogging, true),
|
|
98
|
+
failFast: booleanValue(options.failFast, false)
|
|
97
99
|
};
|
|
98
100
|
if (options.exporters) result.exporters = options.exporters;
|
|
99
101
|
return result;
|
|
100
102
|
}
|
|
101
103
|
|
|
102
|
-
// src/exceptions/process-exception-capture.ts
|
|
103
|
-
var import_api = require("@opentelemetry/api");
|
|
104
|
-
|
|
105
104
|
// src/security/redaction.ts
|
|
106
105
|
var REDACTED = "[REDACTED]";
|
|
107
106
|
var SENSITIVE_KEY = /(?:authorization|proxy-authorization|cookie|set-cookie|pass(?:word|wd)?|secret|token|api[-_]?key|phone|mobile)/i;
|
|
@@ -135,7 +134,115 @@ function redact(value) {
|
|
|
135
134
|
return visit(value, /* @__PURE__ */ new WeakSet());
|
|
136
135
|
}
|
|
137
136
|
|
|
137
|
+
// src/diagnostics.ts
|
|
138
|
+
function toError(value) {
|
|
139
|
+
if (value instanceof Error) return value;
|
|
140
|
+
if (typeof value === "string") return new Error(value);
|
|
141
|
+
try {
|
|
142
|
+
return new Error(JSON.stringify(value));
|
|
143
|
+
} catch {
|
|
144
|
+
return new Error(String(value));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function sanitizeError(error) {
|
|
148
|
+
const sanitized = new Error(redactText(error.message));
|
|
149
|
+
sanitized.name = error.name;
|
|
150
|
+
if (error.stack) sanitized.stack = redactText(error.stack);
|
|
151
|
+
return sanitized;
|
|
152
|
+
}
|
|
153
|
+
var ObserveDiagnostics = class {
|
|
154
|
+
constructor(logging, onError) {
|
|
155
|
+
this.logging = logging;
|
|
156
|
+
this.onError = onError;
|
|
157
|
+
}
|
|
158
|
+
logging;
|
|
159
|
+
onError;
|
|
160
|
+
currentStatus = "starting";
|
|
161
|
+
currentError;
|
|
162
|
+
failedSignals = /* @__PURE__ */ new Set();
|
|
163
|
+
reported = /* @__PURE__ */ new Set();
|
|
164
|
+
get status() {
|
|
165
|
+
return this.currentStatus;
|
|
166
|
+
}
|
|
167
|
+
get lastError() {
|
|
168
|
+
return this.currentError;
|
|
169
|
+
}
|
|
170
|
+
activate() {
|
|
171
|
+
if (this.currentStatus === "starting") this.currentStatus = "active";
|
|
172
|
+
}
|
|
173
|
+
inactive() {
|
|
174
|
+
this.currentStatus = "inactive";
|
|
175
|
+
}
|
|
176
|
+
stop() {
|
|
177
|
+
this.currentStatus = "stopped";
|
|
178
|
+
}
|
|
179
|
+
success(signal) {
|
|
180
|
+
this.failedSignals.delete(signal);
|
|
181
|
+
for (const fingerprint of this.reported) {
|
|
182
|
+
if (fingerprint.startsWith(`${signal}\0`)) this.reported.delete(fingerprint);
|
|
183
|
+
}
|
|
184
|
+
if (this.currentStatus === "degraded" && this.failedSignals.size === 0) {
|
|
185
|
+
this.currentStatus = "active";
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
failure(signal, stage, value) {
|
|
189
|
+
const error = sanitizeError(toError(value));
|
|
190
|
+
const event = { signal, stage, error, timestamp: Date.now() };
|
|
191
|
+
this.currentError = event;
|
|
192
|
+
this.failedSignals.add(signal);
|
|
193
|
+
if (this.currentStatus !== "inactive" && this.currentStatus !== "stopped") {
|
|
194
|
+
this.currentStatus = "degraded";
|
|
195
|
+
}
|
|
196
|
+
const fingerprint = `${signal}\0${stage}\0${error.name}\0${error.message}`;
|
|
197
|
+
if (this.reported.has(fingerprint)) return;
|
|
198
|
+
this.reported.add(fingerprint);
|
|
199
|
+
try {
|
|
200
|
+
this.onError?.(event);
|
|
201
|
+
} catch {
|
|
202
|
+
}
|
|
203
|
+
if (!this.logging) return;
|
|
204
|
+
try {
|
|
205
|
+
process.stderr.write(
|
|
206
|
+
`[nest-observe] ${signal} ${stage} failed: ${redactText(error.message)}
|
|
207
|
+
`
|
|
208
|
+
);
|
|
209
|
+
} catch {
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
function withExporterDiagnostics(exporter, signal, diagnostics) {
|
|
214
|
+
const delegate = exporter;
|
|
215
|
+
return new Proxy(exporter, {
|
|
216
|
+
get(target, property) {
|
|
217
|
+
if (property === "export") {
|
|
218
|
+
return (items, callback) => {
|
|
219
|
+
try {
|
|
220
|
+
delegate.export.call(target, items, (result) => {
|
|
221
|
+
if (result.code === 0) {
|
|
222
|
+
diagnostics.success(signal);
|
|
223
|
+
} else {
|
|
224
|
+
diagnostics.failure(
|
|
225
|
+
signal,
|
|
226
|
+
"export",
|
|
227
|
+
result.error ?? new Error(`${signal} export failed`)
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
callback(result);
|
|
231
|
+
});
|
|
232
|
+
} catch (error) {
|
|
233
|
+
diagnostics.failure(signal, "export", error);
|
|
234
|
+
throw error;
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
const value = Reflect.get(target, property, target);
|
|
239
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
|
|
138
244
|
// src/exceptions/process-exception-capture.ts
|
|
245
|
+
var import_api = require("@opentelemetry/api");
|
|
139
246
|
function asError(value) {
|
|
140
247
|
return value instanceof Error ? value : new Error(String(value));
|
|
141
248
|
}
|
|
@@ -386,7 +493,13 @@ var SEVERITY = {
|
|
|
386
493
|
};
|
|
387
494
|
function bodyValue(message) {
|
|
388
495
|
if (message instanceof Error) return redactText(message.stack ?? `${message.name}: ${message.message}`);
|
|
389
|
-
|
|
496
|
+
const sanitized = redact(message);
|
|
497
|
+
if (sanitized === null || typeof sanitized !== "object") return sanitized;
|
|
498
|
+
try {
|
|
499
|
+
return JSON.stringify(sanitized, (_key, value) => typeof value === "bigint" ? value.toString() : value);
|
|
500
|
+
} catch {
|
|
501
|
+
return redactText(String(sanitized));
|
|
502
|
+
}
|
|
390
503
|
}
|
|
391
504
|
var NestLoggerInstrumentation = class {
|
|
392
505
|
constructor(emitter, resourceAttributes = {}) {
|
|
@@ -493,9 +606,14 @@ var HttpRequestMetrics = class {
|
|
|
493
606
|
errorCount;
|
|
494
607
|
startedAt = /* @__PURE__ */ new WeakMap();
|
|
495
608
|
start(request) {
|
|
609
|
+
if (this.startedAt.has(request)) return false;
|
|
496
610
|
this.startedAt.set(request, process.hrtime.bigint());
|
|
611
|
+
return true;
|
|
497
612
|
}
|
|
498
613
|
record(request, response) {
|
|
614
|
+
const started = this.startedAt.get(request);
|
|
615
|
+
if (started === void 0) return false;
|
|
616
|
+
this.startedAt.delete(request);
|
|
499
617
|
const statusCode = Number.isFinite(response.statusCode) ? response.statusCode : 0;
|
|
500
618
|
const attributes = {
|
|
501
619
|
"service.name": this.serviceName,
|
|
@@ -504,12 +622,9 @@ var HttpRequestMetrics = class {
|
|
|
504
622
|
"http.response.status_code": statusCode
|
|
505
623
|
};
|
|
506
624
|
this.requestCount.add(1, attributes);
|
|
507
|
-
|
|
508
|
-
if (started !== void 0) {
|
|
509
|
-
this.requestDuration.record(Number(process.hrtime.bigint() - started) / 1e9, attributes);
|
|
510
|
-
this.startedAt.delete(request);
|
|
511
|
-
}
|
|
625
|
+
this.requestDuration.record(Number(process.hrtime.bigint() - started) / 1e9, attributes);
|
|
512
626
|
if (statusCode >= 500) this.errorCount.add(1, attributes);
|
|
627
|
+
return true;
|
|
513
628
|
}
|
|
514
629
|
};
|
|
515
630
|
|
|
@@ -597,8 +712,118 @@ var RuntimeMetrics = class {
|
|
|
597
712
|
// src/resource.ts
|
|
598
713
|
var import_resources = require("@opentelemetry/resources");
|
|
599
714
|
var import_node_os2 = require("os");
|
|
600
|
-
|
|
601
|
-
|
|
715
|
+
|
|
716
|
+
// package.json
|
|
717
|
+
var package_default = {
|
|
718
|
+
name: "@ryanzeng/nest-observe",
|
|
719
|
+
version: "0.1.2",
|
|
720
|
+
description: "Zero-config, vendor-neutral OpenTelemetry observability for NestJS",
|
|
721
|
+
keywords: [
|
|
722
|
+
"nestjs",
|
|
723
|
+
"opentelemetry",
|
|
724
|
+
"observability",
|
|
725
|
+
"otlp",
|
|
726
|
+
"tracing",
|
|
727
|
+
"metrics",
|
|
728
|
+
"logging"
|
|
729
|
+
],
|
|
730
|
+
license: "MIT",
|
|
731
|
+
homepage: "https://github.com/ryanzen9/nest-observe#readme",
|
|
732
|
+
bugs: {
|
|
733
|
+
url: "https://github.com/ryanzen9/nest-observe/issues"
|
|
734
|
+
},
|
|
735
|
+
repository: {
|
|
736
|
+
type: "git",
|
|
737
|
+
url: "git+https://github.com/ryanzen9/nest-observe.git"
|
|
738
|
+
},
|
|
739
|
+
packageManager: "pnpm@10.13.1",
|
|
740
|
+
sideEffects: [
|
|
741
|
+
"./dist/register.js",
|
|
742
|
+
"./dist/register.mjs"
|
|
743
|
+
],
|
|
744
|
+
main: "./dist/index.js",
|
|
745
|
+
module: "./dist/index.mjs",
|
|
746
|
+
types: "./dist/index.d.ts",
|
|
747
|
+
exports: {
|
|
748
|
+
".": {
|
|
749
|
+
import: {
|
|
750
|
+
types: "./dist/index.d.mts",
|
|
751
|
+
default: "./dist/index.mjs"
|
|
752
|
+
},
|
|
753
|
+
require: {
|
|
754
|
+
types: "./dist/index.d.ts",
|
|
755
|
+
default: "./dist/index.js"
|
|
756
|
+
}
|
|
757
|
+
},
|
|
758
|
+
"./register": {
|
|
759
|
+
import: {
|
|
760
|
+
types: "./dist/register.d.mts",
|
|
761
|
+
default: "./dist/register.mjs"
|
|
762
|
+
},
|
|
763
|
+
require: {
|
|
764
|
+
types: "./dist/register.d.ts",
|
|
765
|
+
default: "./dist/register.js"
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
},
|
|
769
|
+
files: [
|
|
770
|
+
"dist",
|
|
771
|
+
"README.md",
|
|
772
|
+
"CHANGELOG.md",
|
|
773
|
+
"LICENSE"
|
|
774
|
+
],
|
|
775
|
+
scripts: {
|
|
776
|
+
build: "tsup",
|
|
777
|
+
test: "vitest run",
|
|
778
|
+
"test:watch": "vitest",
|
|
779
|
+
typecheck: "tsc --noEmit",
|
|
780
|
+
check: "pnpm typecheck && pnpm test && pnpm build"
|
|
781
|
+
},
|
|
782
|
+
engines: {
|
|
783
|
+
node: ">=20"
|
|
784
|
+
},
|
|
785
|
+
peerDependencies: {
|
|
786
|
+
"@nestjs/common": ">=10 <13",
|
|
787
|
+
"@nestjs/core": ">=10 <13",
|
|
788
|
+
"reflect-metadata": ">=0.1.12 <1",
|
|
789
|
+
rxjs: "^7.1.0"
|
|
790
|
+
},
|
|
791
|
+
dependencies: {
|
|
792
|
+
"@opentelemetry/api": "^1.9.0",
|
|
793
|
+
"@opentelemetry/api-logs": "^0.221.0",
|
|
794
|
+
"@opentelemetry/exporter-logs-otlp-proto": "^0.221.0",
|
|
795
|
+
"@opentelemetry/exporter-metrics-otlp-proto": "^0.221.0",
|
|
796
|
+
"@opentelemetry/exporter-trace-otlp-proto": "^0.221.0",
|
|
797
|
+
"@opentelemetry/instrumentation": "^0.221.0",
|
|
798
|
+
"@opentelemetry/instrumentation-http": "^0.221.0",
|
|
799
|
+
"@opentelemetry/instrumentation-nestjs-core": "^0.67.0",
|
|
800
|
+
"@opentelemetry/resources": "^2.10.0",
|
|
801
|
+
"@opentelemetry/sdk-logs": "^0.221.0",
|
|
802
|
+
"@opentelemetry/sdk-metrics": "^2.10.0",
|
|
803
|
+
"@opentelemetry/sdk-trace-base": "^2.10.0",
|
|
804
|
+
"@opentelemetry/sdk-trace-node": "^2.10.0",
|
|
805
|
+
"@prisma/instrumentation": "^7.10.0"
|
|
806
|
+
},
|
|
807
|
+
devDependencies: {
|
|
808
|
+
"@nestjs/common": "^12.0.1",
|
|
809
|
+
"@nestjs/core": "^12.0.1",
|
|
810
|
+
"@nestjs/testing": "^12.0.1",
|
|
811
|
+
"@opentelemetry/sdk-trace-base": "^2.10.0",
|
|
812
|
+
"@types/node": "^24.0.0",
|
|
813
|
+
"reflect-metadata": "^0.2.2",
|
|
814
|
+
rxjs: "^7.8.2",
|
|
815
|
+
tsup: "^8.5.1",
|
|
816
|
+
typescript: "^5.9.3",
|
|
817
|
+
vitest: "^4.1.11"
|
|
818
|
+
},
|
|
819
|
+
publishConfig: {
|
|
820
|
+
access: "public"
|
|
821
|
+
}
|
|
822
|
+
};
|
|
823
|
+
|
|
824
|
+
// src/resource.ts
|
|
825
|
+
var SDK_NAME = package_default.name;
|
|
826
|
+
var SDK_VERSION = package_default.version;
|
|
602
827
|
function createObserveResource(config) {
|
|
603
828
|
return (0, import_resources.defaultResource)().merge(
|
|
604
829
|
(0, import_resources.resourceFromAttributes)({
|
|
@@ -655,14 +880,23 @@ var SpanRedactionProcessor = class {
|
|
|
655
880
|
|
|
656
881
|
// src/sdk.ts
|
|
657
882
|
var InactiveObserveHandle = class {
|
|
658
|
-
constructor(config) {
|
|
883
|
+
constructor(config, diagnostics) {
|
|
659
884
|
this.config = config;
|
|
885
|
+
this.diagnostics = diagnostics;
|
|
660
886
|
}
|
|
661
887
|
config;
|
|
888
|
+
diagnostics;
|
|
662
889
|
started = false;
|
|
663
890
|
tracerProvider = void 0;
|
|
664
891
|
meterProvider = void 0;
|
|
665
892
|
loggerProvider = void 0;
|
|
893
|
+
httpRequestMetrics = void 0;
|
|
894
|
+
get status() {
|
|
895
|
+
return this.diagnostics.status;
|
|
896
|
+
}
|
|
897
|
+
get lastError() {
|
|
898
|
+
return this.diagnostics.lastError;
|
|
899
|
+
}
|
|
666
900
|
forceFlush() {
|
|
667
901
|
return Promise.resolve();
|
|
668
902
|
}
|
|
@@ -671,52 +905,73 @@ var InactiveObserveHandle = class {
|
|
|
671
905
|
}
|
|
672
906
|
};
|
|
673
907
|
var ActiveObserveHandle = class {
|
|
674
|
-
constructor(config, tracerProvider, meterProvider, loggerProvider, runtimeMetrics, loggerInstrumentation, exceptionCapture, instrumentations) {
|
|
908
|
+
constructor(config, tracerProvider, meterProvider, loggerProvider, httpRequestMetrics, runtimeMetrics, loggerInstrumentation, exceptionCapture, instrumentations, diagnostics) {
|
|
675
909
|
this.config = config;
|
|
676
910
|
this.tracerProvider = tracerProvider;
|
|
677
911
|
this.meterProvider = meterProvider;
|
|
678
912
|
this.loggerProvider = loggerProvider;
|
|
913
|
+
this.httpRequestMetrics = httpRequestMetrics;
|
|
679
914
|
this.runtimeMetrics = runtimeMetrics;
|
|
680
915
|
this.loggerInstrumentation = loggerInstrumentation;
|
|
681
916
|
this.exceptionCapture = exceptionCapture;
|
|
682
917
|
this.instrumentations = instrumentations;
|
|
918
|
+
this.diagnostics = diagnostics;
|
|
683
919
|
}
|
|
684
920
|
config;
|
|
685
921
|
tracerProvider;
|
|
686
922
|
meterProvider;
|
|
687
923
|
loggerProvider;
|
|
924
|
+
httpRequestMetrics;
|
|
688
925
|
runtimeMetrics;
|
|
689
926
|
loggerInstrumentation;
|
|
690
927
|
exceptionCapture;
|
|
691
928
|
instrumentations;
|
|
929
|
+
diagnostics;
|
|
692
930
|
started = true;
|
|
693
931
|
stopped = false;
|
|
932
|
+
get status() {
|
|
933
|
+
return this.diagnostics.status;
|
|
934
|
+
}
|
|
935
|
+
get lastError() {
|
|
936
|
+
return this.diagnostics.lastError;
|
|
937
|
+
}
|
|
694
938
|
async forceFlush() {
|
|
695
|
-
await
|
|
696
|
-
this.tracerProvider
|
|
697
|
-
this.meterProvider
|
|
698
|
-
this.loggerProvider
|
|
699
|
-
]
|
|
939
|
+
await this.runSafely("forceFlush", [
|
|
940
|
+
...this.config.traces && this.tracerProvider ? [["traces", () => this.tracerProvider.forceFlush()]] : [],
|
|
941
|
+
...this.config.metrics && this.meterProvider ? [["metrics", () => this.meterProvider.forceFlush()]] : [],
|
|
942
|
+
...this.config.logs && this.loggerProvider ? [["logs", () => this.loggerProvider.forceFlush({ timeoutMillis: this.config.exportTimeoutMillis })]] : []
|
|
943
|
+
]);
|
|
700
944
|
}
|
|
701
945
|
async shutdown() {
|
|
702
946
|
if (this.stopped) return;
|
|
703
947
|
this.stopped = true;
|
|
704
948
|
this.loggerInstrumentation?.disable();
|
|
705
|
-
this.runtimeMetrics?.stop();
|
|
706
949
|
this.exceptionCapture.stop();
|
|
707
950
|
for (const instrumentation of this.instrumentations) {
|
|
708
951
|
try {
|
|
709
952
|
instrumentation.disable();
|
|
710
|
-
} catch {
|
|
953
|
+
} catch (error) {
|
|
954
|
+
this.diagnostics.failure("sdk", "shutdown", error);
|
|
711
955
|
}
|
|
712
956
|
}
|
|
713
957
|
await this.forceFlush();
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
this.
|
|
717
|
-
this.
|
|
718
|
-
|
|
958
|
+
this.runtimeMetrics?.stop();
|
|
959
|
+
await this.runSafely("shutdown", [
|
|
960
|
+
...this.tracerProvider ? [["traces", () => this.tracerProvider.shutdown()]] : [],
|
|
961
|
+
...this.meterProvider ? [["metrics", () => this.meterProvider.shutdown()]] : [],
|
|
962
|
+
...this.loggerProvider ? [["logs", () => this.loggerProvider.shutdown()]] : []
|
|
963
|
+
]);
|
|
719
964
|
if (activeRuntime === this) activeRuntime = void 0;
|
|
965
|
+
this.diagnostics.stop();
|
|
966
|
+
}
|
|
967
|
+
async runSafely(stage, operations) {
|
|
968
|
+
await Promise.all(operations.map(async ([signal, operation]) => {
|
|
969
|
+
try {
|
|
970
|
+
await operation();
|
|
971
|
+
} catch (error) {
|
|
972
|
+
this.diagnostics.failure(signal, stage, error);
|
|
973
|
+
}
|
|
974
|
+
}));
|
|
720
975
|
}
|
|
721
976
|
};
|
|
722
977
|
var activeRuntime;
|
|
@@ -727,12 +982,16 @@ function exporterConfig(url, config) {
|
|
|
727
982
|
timeoutMillis: config.exportTimeoutMillis
|
|
728
983
|
};
|
|
729
984
|
}
|
|
730
|
-
function createTraceProvider(config, resource) {
|
|
985
|
+
function createTraceProvider(config, resource, diagnostics) {
|
|
731
986
|
if (!config.traces && !config.metrics) return void 0;
|
|
732
987
|
const spanProcessors = [new SpanRedactionProcessor()];
|
|
733
988
|
if (config.traces) {
|
|
734
989
|
const exporter = config.exporters?.span ?? new import_exporter_trace_otlp_proto.OTLPTraceExporter(exporterConfig(config.endpoints.traces, config));
|
|
735
|
-
spanProcessors.push(new import_sdk_trace_base.BatchSpanProcessor(
|
|
990
|
+
spanProcessors.push(new import_sdk_trace_base.BatchSpanProcessor(withExporterDiagnostics(
|
|
991
|
+
exporter,
|
|
992
|
+
"traces",
|
|
993
|
+
diagnostics
|
|
994
|
+
), {
|
|
736
995
|
exportTimeoutMillis: config.exportTimeoutMillis,
|
|
737
996
|
maxQueueSize: 2048,
|
|
738
997
|
maxExportBatchSize: 512
|
|
@@ -747,14 +1006,18 @@ function createTraceProvider(config, resource) {
|
|
|
747
1006
|
provider.register();
|
|
748
1007
|
return provider;
|
|
749
1008
|
}
|
|
750
|
-
function createMeterProvider(config, resource) {
|
|
1009
|
+
function createMeterProvider(config, resource, diagnostics) {
|
|
751
1010
|
if (!config.metrics) return void 0;
|
|
752
1011
|
let reader;
|
|
753
1012
|
if (config.exporters?.metricReader) {
|
|
754
1013
|
reader = config.exporters.metricReader;
|
|
755
1014
|
} else {
|
|
756
1015
|
reader = new import_sdk_metrics.PeriodicExportingMetricReader({
|
|
757
|
-
exporter:
|
|
1016
|
+
exporter: withExporterDiagnostics(
|
|
1017
|
+
new import_exporter_metrics_otlp_proto.OTLPMetricExporter(exporterConfig(config.endpoints.metrics, config)),
|
|
1018
|
+
"metrics",
|
|
1019
|
+
diagnostics
|
|
1020
|
+
),
|
|
758
1021
|
exportIntervalMillis: config.metricExportIntervalMillis,
|
|
759
1022
|
exportTimeoutMillis: Math.min(config.exportTimeoutMillis, config.metricExportIntervalMillis),
|
|
760
1023
|
cardinalityLimits: { default: 2e3, histogram: 2e3 }
|
|
@@ -772,13 +1035,13 @@ function createMeterProvider(config, resource) {
|
|
|
772
1035
|
import_api5.metrics.setGlobalMeterProvider(provider);
|
|
773
1036
|
return provider;
|
|
774
1037
|
}
|
|
775
|
-
function createLoggerProvider(config, resource) {
|
|
1038
|
+
function createLoggerProvider(config, resource, diagnostics) {
|
|
776
1039
|
if (!config.logs) return void 0;
|
|
777
1040
|
const exporter = config.exporters?.log ?? new import_exporter_logs_otlp_proto.OTLPLogExporter(exporterConfig(config.endpoints.logs, config));
|
|
778
1041
|
const provider = new import_sdk_logs.LoggerProvider({
|
|
779
1042
|
resource,
|
|
780
1043
|
processors: [new import_sdk_logs.BatchLogRecordProcessor({
|
|
781
|
-
exporter,
|
|
1044
|
+
exporter: withExporterDiagnostics(exporter, "logs", diagnostics),
|
|
782
1045
|
exportTimeoutMillis: config.exportTimeoutMillis,
|
|
783
1046
|
maxQueueSize: 2048,
|
|
784
1047
|
maxExportBatchSize: 512
|
|
@@ -790,7 +1053,11 @@ function createLoggerProvider(config, resource) {
|
|
|
790
1053
|
function observe(options = {}) {
|
|
791
1054
|
if (activeRuntime?.started) return activeRuntime;
|
|
792
1055
|
const config = resolveObserveConfig(options);
|
|
793
|
-
|
|
1056
|
+
const diagnostics = new ObserveDiagnostics(config.diagnosticLogging, options.onError);
|
|
1057
|
+
if (!config.enabled) {
|
|
1058
|
+
diagnostics.inactive();
|
|
1059
|
+
return new InactiveObserveHandle(config, diagnostics);
|
|
1060
|
+
}
|
|
794
1061
|
let tracerProvider;
|
|
795
1062
|
let meterProvider;
|
|
796
1063
|
let loggerProvider;
|
|
@@ -800,10 +1067,11 @@ function observe(options = {}) {
|
|
|
800
1067
|
const instrumentations = [];
|
|
801
1068
|
try {
|
|
802
1069
|
const resource = createObserveResource(config);
|
|
803
|
-
meterProvider = createMeterProvider(config, resource);
|
|
1070
|
+
meterProvider = createMeterProvider(config, resource, diagnostics);
|
|
804
1071
|
const meter = meterProvider?.getMeter(SDK_NAME, SDK_VERSION);
|
|
805
|
-
|
|
806
|
-
|
|
1072
|
+
const httpRequestMetrics = meter ? new HttpRequestMetrics(meter, config.serviceName) : void 0;
|
|
1073
|
+
tracerProvider = createTraceProvider(config, resource, diagnostics);
|
|
1074
|
+
loggerProvider = createLoggerProvider(config, resource, diagnostics);
|
|
807
1075
|
runtimeMetrics = meter ? new RuntimeMetrics(meter) : void 0;
|
|
808
1076
|
runtimeMetrics?.start();
|
|
809
1077
|
const otelLogger = loggerProvider?.getLogger(SDK_NAME, SDK_VERSION);
|
|
@@ -818,7 +1086,6 @@ function observe(options = {}) {
|
|
|
818
1086
|
exceptionCapture.start();
|
|
819
1087
|
if (config.traces || config.metrics) {
|
|
820
1088
|
const safeHeaders = config.allowedHeaders.filter((header) => !isSensitiveKey(header));
|
|
821
|
-
const httpRequestMetrics = meter ? new HttpRequestMetrics(meter, config.serviceName) : void 0;
|
|
822
1089
|
instrumentations.push(new import_instrumentation_http.HttpInstrumentation({
|
|
823
1090
|
requireParentforOutgoingSpans: false,
|
|
824
1091
|
headersToSpanAttributes: {
|
|
@@ -862,14 +1129,18 @@ function observe(options = {}) {
|
|
|
862
1129
|
tracerProvider,
|
|
863
1130
|
meterProvider,
|
|
864
1131
|
loggerProvider,
|
|
1132
|
+
httpRequestMetrics,
|
|
865
1133
|
runtimeMetrics,
|
|
866
1134
|
loggerInstrumentation,
|
|
867
1135
|
exceptionCapture,
|
|
868
|
-
instrumentations
|
|
1136
|
+
instrumentations,
|
|
1137
|
+
diagnostics
|
|
869
1138
|
);
|
|
1139
|
+
diagnostics.activate();
|
|
870
1140
|
activeRuntime = runtime;
|
|
871
1141
|
return runtime;
|
|
872
|
-
} catch {
|
|
1142
|
+
} catch (error) {
|
|
1143
|
+
diagnostics.failure("sdk", "initialization", error);
|
|
873
1144
|
loggerInstrumentation?.disable();
|
|
874
1145
|
runtimeMetrics?.stop();
|
|
875
1146
|
exceptionCapture?.stop();
|
|
@@ -884,7 +1155,9 @@ function observe(options = {}) {
|
|
|
884
1155
|
meterProvider?.shutdown(),
|
|
885
1156
|
loggerProvider?.shutdown()
|
|
886
1157
|
].filter((item) => Boolean(item)));
|
|
887
|
-
|
|
1158
|
+
diagnostics.inactive();
|
|
1159
|
+
if (config.failFast) throw toError(error);
|
|
1160
|
+
return new InactiveObserveHandle(config, diagnostics);
|
|
888
1161
|
}
|
|
889
1162
|
}
|
|
890
1163
|
|