diff --git a/package-lock.json b/package-lock.json index 048c51acf8..cb263c0fc5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "@netlify/edge-functions-bootstrap": "^2.14.0", "@netlify/eslint-config-node": "^7.0.1", "@netlify/functions": "^4.3.0", + "@netlify/otel": "^4.3.0", "@netlify/serverless-functions-api": "^2.5.0", "@netlify/zip-it-and-ship-it": "^14.1.8", "@opentelemetry/api": "^1.8.0", @@ -4373,6 +4374,165 @@ "@opentelemetry/api": "~1.8.0" } }, + "node_modules/@netlify/otel": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@netlify/otel/-/otel-4.3.0.tgz", + "integrity": "sha512-a0ABd3XFTUW4phYVQVBQ6hT+BTWyBblaFldGaTckKBJW0s+SEzKF9h22dq/CoVMfJ+zKgyKlU6ECXJmvehOSgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@opentelemetry/api": "1.9.0", + "@opentelemetry/core": "1.30.1", + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/otlp-transformer": "0.57.2", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/sdk-trace-node": "1.30.1" + }, + "engines": { + "node": "^18.14.0 || >=20.6.1" + } + }, + "node_modules/@netlify/otel/node_modules/@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@netlify/otel/node_modules/@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@netlify/otel/node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@netlify/otel/node_modules/@opentelemetry/otlp-transformer": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.57.2.tgz", + "integrity": "sha512-48IIRj49gbQVK52jYsw70+Jv+JbahT8BqT2Th7C4H7RCM9d0gZ5sgNPoMpWldmfjvIsSgiGJtjfk9MeZvjhoig==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/sdk-logs": "0.57.2", + "@opentelemetry/sdk-metrics": "1.30.1", + "@opentelemetry/sdk-trace-base": "1.30.1", + "protobufjs": "^7.3.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@netlify/otel/node_modules/@opentelemetry/resources": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", + "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@netlify/otel/node_modules/@opentelemetry/sdk-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.57.2.tgz", + "integrity": "sha512-TXFHJ5c+BKggWbdEQ/inpgIzEmS2BGQowLE9UhsMd7YYlUfBQJ4uax0VF/B5NYigdM/75OoJGhAV3upEhK+3gg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.57.2", + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.10.0" + } + }, + "node_modules/@netlify/otel/node_modules/@opentelemetry/sdk-metrics": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.30.1.tgz", + "integrity": "sha512-q9zcZ0Okl8jRgmy7eNW3Ku1XSgg3sDLa5evHZpCwjspw7E8Is4K/haRPDJrBcX3YSn/Y7gUvFnByNYEKQNbNog==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@netlify/otel/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.30.1.tgz", + "integrity": "sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@netlify/otel/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, "node_modules/@netlify/plugins-list": { "version": "6.80.0", "resolved": "https://registry.npmjs.org/@netlify/plugins-list/-/plugins-list-6.80.0.tgz", @@ -4767,6 +4927,19 @@ "node": ">=14" } }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.30.1.tgz", + "integrity": "sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, "node_modules/@opentelemetry/core": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.22.0.tgz", @@ -5051,6 +5224,50 @@ "node": ">=14" } }, + "node_modules/@opentelemetry/instrumentation": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.203.0.tgz", + "integrity": "sha512-ke1qyM+3AK2zPuBPb6Hk/GCsc5ewbLvPNkEuELx/JmANeEp6ZjnZ+wypPAJSucTw0wvCGrUaibDSdcrGFoWxKQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.203.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-logs": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.203.0.tgz", + "integrity": "sha512-9B9RU0H7Ya1Dx/Rkyc4stuBZSGVQF27WigitInx2QQoj6KUpEFYPKoWjdFTunJYxmXmh17HeBvbMa1EhGyPmqQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation/node_modules/import-in-the-middle": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.15.0.tgz", + "integrity": "sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, "node_modules/@opentelemetry/otlp-exporter-base": { "version": "0.49.1", "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.49.1.tgz", @@ -5158,6 +5375,90 @@ "node": ">=14" } }, + "node_modules/@opentelemetry/propagator-b3": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-1.30.1.tgz", + "integrity": "sha512-oATwWWDIJzybAZ4pO76ATN5N6FFbOA1otibAVlS8v90B4S1wClnhRUk7K+2CHAwN1JKYuj4jh/lpCEG5BAqFuQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-b3/node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-b3/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/propagator-jaeger": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.30.1.tgz", + "integrity": "sha512-Pj/BfnYEKIOImirH76M4hDaBSx6HyZ2CXUqk+Kj02m6BB80c/yo4BdWkn/1gDFfU+YPY+bPR2U0DKBfdxCKwmg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-jaeger/node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-jaeger/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, "node_modules/@opentelemetry/resources": { "version": "1.24.1", "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.24.1.tgz", @@ -5337,6 +5638,88 @@ "node": ">=14" } }, + "node_modules/@opentelemetry/sdk-trace-node": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.30.1.tgz", + "integrity": "sha512-cBjYOINt1JxXdpw1e5MlHmFRc5fgj4GW/86vsKFxJCJ8AL4PdVtYH41gWwl4qd4uQjqEL1oJVrXkSy5cnduAnQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/context-async-hooks": "1.30.1", + "@opentelemetry/core": "1.30.1", + "@opentelemetry/propagator-b3": "1.30.1", + "@opentelemetry/propagator-jaeger": "1.30.1", + "@opentelemetry/sdk-trace-base": "1.30.1", + "semver": "^7.5.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node/node_modules/@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node/node_modules/@opentelemetry/resources": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", + "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node/node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.30.1.tgz", + "integrity": "sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node/node_modules/@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, "node_modules/@opentelemetry/semantic-conventions": { "version": "1.24.1", "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz", @@ -5377,41 +5760,31 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/@protobufjs/codegen": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "dev": true, - "optional": true, - "peer": true, "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -5421,41 +5794,31 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/@rollup/pluginutils": { "version": "5.1.4", @@ -7673,9 +8036,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/clean-package": { "version": "2.2.0", @@ -12806,9 +13167,7 @@ "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/loose-envify": { "version": "1.4.0", @@ -13427,9 +13786,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/moize": { "version": "6.1.6", @@ -29175,8 +29532,6 @@ "integrity": "sha512-RXyHaACeqXeqAKGLDl68rQKbmObRsTIn4TYVUUug1KfS47YWCo5MacGITEryugIgZqORCvJWEk4l449POg5Txg==", "dev": true, "hasInstallScript": true, - "optional": true, - "peer": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -29659,8 +30014,6 @@ "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.3.0.tgz", "integrity": "sha512-nQFEv9gRw6SJAwWD2LrL0NmQvAcO7FBwJbwmr2ttPAacfy0xuiOjE5zt+zM4xDyuyvUaxBi/9gb2SoCyNEVJcw==", "dev": true, - "optional": true, - "peer": true, "dependencies": { "debug": "^4.1.1", "module-details-from-path": "^1.0.3", @@ -29675,8 +30028,6 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, - "optional": true, - "peer": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -35608,6 +35959,109 @@ "dev": true, "requires": {} }, + "@netlify/otel": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@netlify/otel/-/otel-4.3.0.tgz", + "integrity": "sha512-a0ABd3XFTUW4phYVQVBQ6hT+BTWyBblaFldGaTckKBJW0s+SEzKF9h22dq/CoVMfJ+zKgyKlU6ECXJmvehOSgg==", + "dev": true, + "requires": { + "@opentelemetry/api": "1.9.0", + "@opentelemetry/core": "1.30.1", + "@opentelemetry/instrumentation": "^0.203.0", + "@opentelemetry/otlp-transformer": "0.57.2", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/sdk-trace-node": "1.30.1" + }, + "dependencies": { + "@opentelemetry/api": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", + "dev": true + }, + "@opentelemetry/api-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.57.2.tgz", + "integrity": "sha512-uIX52NnTM0iBh84MShlpouI7UKqkZ7MrUszTmaypHBu4r7NofznSnQRfJ+uUeDtQDj6w8eFGg5KBLDAwAPz1+A==", + "dev": true, + "requires": { + "@opentelemetry/api": "^1.3.0" + } + }, + "@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "dev": true, + "requires": { + "@opentelemetry/semantic-conventions": "1.28.0" + } + }, + "@opentelemetry/otlp-transformer": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.57.2.tgz", + "integrity": "sha512-48IIRj49gbQVK52jYsw70+Jv+JbahT8BqT2Th7C4H7RCM9d0gZ5sgNPoMpWldmfjvIsSgiGJtjfk9MeZvjhoig==", + "dev": true, + "requires": { + "@opentelemetry/api-logs": "0.57.2", + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/sdk-logs": "0.57.2", + "@opentelemetry/sdk-metrics": "1.30.1", + "@opentelemetry/sdk-trace-base": "1.30.1", + "protobufjs": "^7.3.0" + } + }, + "@opentelemetry/resources": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", + "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "dev": true, + "requires": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + } + }, + "@opentelemetry/sdk-logs": { + "version": "0.57.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.57.2.tgz", + "integrity": "sha512-TXFHJ5c+BKggWbdEQ/inpgIzEmS2BGQowLE9UhsMd7YYlUfBQJ4uax0VF/B5NYigdM/75OoJGhAV3upEhK+3gg==", + "dev": true, + "requires": { + "@opentelemetry/api-logs": "0.57.2", + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1" + } + }, + "@opentelemetry/sdk-metrics": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.30.1.tgz", + "integrity": "sha512-q9zcZ0Okl8jRgmy7eNW3Ku1XSgg3sDLa5evHZpCwjspw7E8Is4K/haRPDJrBcX3YSn/Y7gUvFnByNYEKQNbNog==", + "dev": true, + "requires": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1" + } + }, + "@opentelemetry/sdk-trace-base": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.30.1.tgz", + "integrity": "sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==", + "dev": true, + "requires": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + } + }, + "@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true + } + } + }, "@netlify/plugins-list": { "version": "6.80.0", "resolved": "https://registry.npmjs.org/@netlify/plugins-list/-/plugins-list-6.80.0.tgz", @@ -35872,6 +36326,13 @@ "@opentelemetry/api": "^1.0.0" } }, + "@opentelemetry/context-async-hooks": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.30.1.tgz", + "integrity": "sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA==", + "dev": true, + "requires": {} + }, "@opentelemetry/core": { "version": "1.22.0", "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.22.0.tgz", @@ -36084,6 +36545,40 @@ } } }, + "@opentelemetry/instrumentation": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.203.0.tgz", + "integrity": "sha512-ke1qyM+3AK2zPuBPb6Hk/GCsc5ewbLvPNkEuELx/JmANeEp6ZjnZ+wypPAJSucTw0wvCGrUaibDSdcrGFoWxKQ==", + "dev": true, + "requires": { + "@opentelemetry/api-logs": "0.203.0", + "import-in-the-middle": "^1.8.1", + "require-in-the-middle": "^7.1.1" + }, + "dependencies": { + "@opentelemetry/api-logs": { + "version": "0.203.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.203.0.tgz", + "integrity": "sha512-9B9RU0H7Ya1Dx/Rkyc4stuBZSGVQF27WigitInx2QQoj6KUpEFYPKoWjdFTunJYxmXmh17HeBvbMa1EhGyPmqQ==", + "dev": true, + "requires": { + "@opentelemetry/api": "^1.3.0" + } + }, + "import-in-the-middle": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.15.0.tgz", + "integrity": "sha512-bpQy+CrsRmYmoPMAE/0G33iwRqwW4ouqdRg8jgbH3aKuCtOc8lxgmYXg2dMM92CRiGP660EtBcymH/eVUpCSaA==", + "dev": true, + "requires": { + "acorn": "^8.14.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + } + } + }, "@opentelemetry/otlp-exporter-base": { "version": "0.49.1", "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.49.1.tgz", @@ -36160,6 +36655,58 @@ } } }, + "@opentelemetry/propagator-b3": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-1.30.1.tgz", + "integrity": "sha512-oATwWWDIJzybAZ4pO76ATN5N6FFbOA1otibAVlS8v90B4S1wClnhRUk7K+2CHAwN1JKYuj4jh/lpCEG5BAqFuQ==", + "dev": true, + "requires": { + "@opentelemetry/core": "1.30.1" + }, + "dependencies": { + "@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "dev": true, + "requires": { + "@opentelemetry/semantic-conventions": "1.28.0" + } + }, + "@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true + } + } + }, + "@opentelemetry/propagator-jaeger": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.30.1.tgz", + "integrity": "sha512-Pj/BfnYEKIOImirH76M4hDaBSx6HyZ2CXUqk+Kj02m6BB80c/yo4BdWkn/1gDFfU+YPY+bPR2U0DKBfdxCKwmg==", + "dev": true, + "requires": { + "@opentelemetry/core": "1.30.1" + }, + "dependencies": { + "@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "dev": true, + "requires": { + "@opentelemetry/semantic-conventions": "1.28.0" + } + }, + "@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true + } + } + }, "@opentelemetry/resources": { "version": "1.24.1", "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.24.1.tgz", @@ -36289,6 +36836,58 @@ } } }, + "@opentelemetry/sdk-trace-node": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.30.1.tgz", + "integrity": "sha512-cBjYOINt1JxXdpw1e5MlHmFRc5fgj4GW/86vsKFxJCJ8AL4PdVtYH41gWwl4qd4uQjqEL1oJVrXkSy5cnduAnQ==", + "dev": true, + "requires": { + "@opentelemetry/context-async-hooks": "1.30.1", + "@opentelemetry/core": "1.30.1", + "@opentelemetry/propagator-b3": "1.30.1", + "@opentelemetry/propagator-jaeger": "1.30.1", + "@opentelemetry/sdk-trace-base": "1.30.1", + "semver": "^7.5.2" + }, + "dependencies": { + "@opentelemetry/core": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.30.1.tgz", + "integrity": "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ==", + "dev": true, + "requires": { + "@opentelemetry/semantic-conventions": "1.28.0" + } + }, + "@opentelemetry/resources": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.30.1.tgz", + "integrity": "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA==", + "dev": true, + "requires": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + } + }, + "@opentelemetry/sdk-trace-base": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.30.1.tgz", + "integrity": "sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg==", + "dev": true, + "requires": { + "@opentelemetry/core": "1.30.1", + "@opentelemetry/resources": "1.30.1", + "@opentelemetry/semantic-conventions": "1.28.0" + } + }, + "@opentelemetry/semantic-conventions": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.28.0.tgz", + "integrity": "sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA==", + "dev": true + } + } + }, "@opentelemetry/semantic-conventions": { "version": "1.24.1", "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.24.1.tgz", @@ -36317,41 +36916,31 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "@protobufjs/codegen": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "dev": true, - "optional": true, - "peer": true, "requires": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -36361,41 +36950,31 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "@rollup/pluginutils": { "version": "5.1.4", @@ -37258,8 +37837,7 @@ "dev": true }, "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "version": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { @@ -37930,9 +38508,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "clean-package": { "version": "2.2.0", @@ -38687,8 +39263,7 @@ } }, "dot-prop": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-9.0.0.tgz", + "version": "https://registry.npmjs.org/dot-prop/-/dot-prop-9.0.0.tgz", "integrity": "sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==", "dev": true, "requires": { @@ -41637,9 +42212,7 @@ "version": "5.2.3", "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "loose-envify": { "version": "1.4.0", @@ -42092,9 +42665,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "moize": { "version": "6.1.6", @@ -52925,8 +53496,6 @@ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.3.2.tgz", "integrity": "sha512-RXyHaACeqXeqAKGLDl68rQKbmObRsTIn4TYVUUug1KfS47YWCo5MacGITEryugIgZqORCvJWEk4l449POg5Txg==", "dev": true, - "optional": true, - "peer": true, "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -53287,8 +53856,6 @@ "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.3.0.tgz", "integrity": "sha512-nQFEv9gRw6SJAwWD2LrL0NmQvAcO7FBwJbwmr2ttPAacfy0xuiOjE5zt+zM4xDyuyvUaxBi/9gb2SoCyNEVJcw==", "dev": true, - "optional": true, - "peer": true, "requires": { "debug": "^4.1.1", "module-details-from-path": "^1.0.3", @@ -53300,8 +53867,6 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, - "optional": true, - "peer": true, "requires": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", diff --git a/package.json b/package.json index 3a571aa327..62587b74ae 100644 --- a/package.json +++ b/package.json @@ -57,10 +57,11 @@ "@netlify/build": "^35.1.7", "@netlify/config": "^24.0.4", "@netlify/edge-bundler": "^14.5.5", - "@netlify/edge-functions-bootstrap": "^2.14.0", "@netlify/edge-functions": "^2.17.1", + "@netlify/edge-functions-bootstrap": "^2.14.0", "@netlify/eslint-config-node": "^7.0.1", "@netlify/functions": "^4.3.0", + "@netlify/otel": "^4.3.0", "@netlify/serverless-functions-api": "^2.5.0", "@netlify/zip-it-and-ship-it": "^14.1.8", "@opentelemetry/api": "^1.8.0", diff --git a/src/build/templates/handler-monorepo.tmpl.js b/src/build/templates/handler-monorepo.tmpl.js index 82bd13cbf3..04a2dc321c 100644 --- a/src/build/templates/handler-monorepo.tmpl.js +++ b/src/build/templates/handler-monorepo.tmpl.js @@ -2,7 +2,7 @@ import { createRequestContext, runWithRequestContext, } from '{{cwd}}/.netlify/dist/run/handlers/request-context.cjs' -import { getTracer } from '{{cwd}}/.netlify/dist/run/handlers/tracer.cjs' +import { getTracer, withActiveSpan } from '{{cwd}}/.netlify/dist/run/handlers/tracer.cjs' process.chdir('{{cwd}}') @@ -15,8 +15,8 @@ export default async function (req, context) { const tracer = getTracer() const handlerResponse = await runWithRequestContext(requestContext, () => { - return tracer.withActiveSpan('Next.js Server Handler', async (span) => { - span.setAttributes({ + return withActiveSpan(tracer, 'Next.js Server Handler', async (span) => { + span?.setAttributes({ 'account.id': context.account.id, 'deploy.id': context.deploy.id, 'request.id': context.requestId, @@ -32,7 +32,7 @@ export default async function (req, context) { cachedHandler = handler } const response = await cachedHandler(req, context, span, requestContext) - span.setAttributes({ + span?.setAttributes({ 'http.status_code': response.status, }) return response diff --git a/src/build/templates/handler.tmpl.js b/src/build/templates/handler.tmpl.js index ccdf332036..f85d0bc9e5 100644 --- a/src/build/templates/handler.tmpl.js +++ b/src/build/templates/handler.tmpl.js @@ -3,7 +3,7 @@ import { runWithRequestContext, } from './.netlify/dist/run/handlers/request-context.cjs' import serverHandler from './.netlify/dist/run/handlers/server.js' -import { getTracer } from './.netlify/dist/run/handlers/tracer.cjs' +import { getTracer, withActiveSpan } from './.netlify/dist/run/handlers/tracer.cjs' // Set feature flag for regional blobs process.env.USE_REGIONAL_BLOBS = '{{useRegionalBlobs}}' @@ -13,8 +13,8 @@ export default async function handler(req, context) { const tracer = getTracer() const handlerResponse = await runWithRequestContext(requestContext, () => { - return tracer.withActiveSpan('Next.js Server Handler', async (span) => { - span.setAttributes({ + return withActiveSpan(tracer, 'Next.js Server Handler', async (span) => { + span?.setAttributes({ 'account.id': context.account.id, 'deploy.id': context.deploy.id, 'request.id': context.requestId, @@ -26,7 +26,7 @@ export default async function handler(req, context) { cwd: process.cwd(), }) const response = await serverHandler(req, context, span, requestContext) - span.setAttributes({ + span?.setAttributes({ 'http.status_code': response.status, }) return response diff --git a/src/run/handlers/cache.cts b/src/run/handlers/cache.cts index 7b2fd8d321..5839723480 100644 --- a/src/run/handlers/cache.cts +++ b/src/run/handlers/cache.cts @@ -5,7 +5,7 @@ import { Buffer } from 'node:buffer' import { join } from 'node:path' import { join as posixJoin } from 'node:path/posix' -import { type Span } from '@opentelemetry/api' +import type { Span } from '@netlify/otel/opentelemetry' import type { PrerenderManifest } from 'next/dist/build/index.js' import { NEXT_CACHE_TAGS_HEADER } from 'next/dist/lib/constants.js' @@ -32,7 +32,7 @@ import { type RevalidateTagDurations, type TagStaleOrExpiredStatus, } from './tags-handler.cjs' -import { getTracer, recordWarning } from './tracer.cjs' +import { getTracer, recordWarning, withActiveSpan } from './tracer.cjs' let memoizedPrerenderManifest: PrerenderManifest @@ -74,7 +74,7 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions { private captureResponseCacheLastModified( cacheValue: NetlifyCacheHandlerValue, key: string, - getCacheKeySpan: Span, + getCacheKeySpan?: Span, ) { if (cacheValue.value?.kind === 'FETCH') { return @@ -262,17 +262,17 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions { async get( ...args: Parameters ): ReturnType { - return this.tracer.withActiveSpan('get cache key', async (span) => { + return withActiveSpan(this.tracer, 'get cache key', async (span) => { const [key, context = {}] = args getLogger().debug(`[NetlifyCacheHandler.get]: ${key}`) - span.setAttributes({ key }) + span?.setAttributes({ key }) const blob = await this.cacheStore.get(key, 'blobStore.get') // if blob is null then we don't have a cache entry if (!blob) { - span.addEvent('Cache miss', { key }) + span?.addEvent('Cache miss', { key }) return null } @@ -281,7 +281,7 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions { if (getRequestContext()?.isBackgroundRevalidation && typeof ttl === 'number' && ttl < 0) { // background revalidation request should allow data that is not yet stale, // but opt to discard STALE data, so that Next.js generate fresh response - span.addEvent('Discarding stale entry due to SWR background revalidation request', { + span?.addEvent('Discarding stale entry due to SWR background revalidation request', { key, ttl, }) @@ -303,14 +303,14 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions { ) if (expiredByTags) { - span.addEvent('Expired', { expiredByTags, key, ttl }) + span?.addEvent('Expired', { expiredByTags, key, ttl }) return null } this.captureResponseCacheLastModified(blob, key, span) if (staleByTags) { - span.addEvent('Stale', { staleByTags, key, ttl }) + span?.addEvent('Stale', { staleByTags, key, ttl }) // note that we modify this after we capture last modified to ensure that Age is correct // but we still let Next.js know that entry is stale blob.lastModified = -1 // indicate that the entry is stale @@ -324,7 +324,7 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions { switch (blob.value?.kind) { case 'FETCH': - span.addEvent('FETCH', { + span?.addEvent('FETCH', { lastModified: blob.lastModified, revalidate: context.revalidate, ttl, @@ -336,7 +336,7 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions { case 'ROUTE': case 'APP_ROUTE': { - span.addEvent(blob.value?.kind, { + span?.addEvent(blob.value?.kind, { lastModified: blob.lastModified, status: blob.value.status, revalidate: blob.value.revalidate, @@ -362,7 +362,7 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions { requestContext.pageHandlerRevalidate = revalidate } - span.addEvent(blob.value?.kind, { lastModified: blob.lastModified, revalidate, ttl }) + span?.addEvent(blob.value?.kind, { lastModified: blob.lastModified, revalidate, ttl }) await this.injectEntryToPrerenderManifest(key, blob.value) @@ -379,7 +379,7 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions { const { revalidate, rscData, segmentData, ...restOfPageValue } = blob.value - span.addEvent(blob.value?.kind, { lastModified: blob.lastModified, revalidate, ttl }) + span?.addEvent(blob.value?.kind, { lastModified: blob.lastModified, revalidate, ttl }) await this.injectEntryToPrerenderManifest(key, blob.value) @@ -400,7 +400,7 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions { } } default: - span.recordException(new Error(`Unknown cache entry kind: ${blob.value?.kind}`)) + span?.recordException(new Error(`Unknown cache entry kind: ${blob.value?.kind}`)) } return null }) @@ -452,10 +452,10 @@ export class NetlifyCacheHandler implements CacheHandlerForMultipleVersions { } async set(...args: Parameters) { - return this.tracer.withActiveSpan('set cache key', async (span) => { + return withActiveSpan(this.tracer, 'set cache key', async (span?: Span) => { const [key, data, context] = args const lastModified = Date.now() - span.setAttributes({ key, lastModified }) + span?.setAttributes({ key, lastModified }) getLogger().debug(`[NetlifyCacheHandler.set]: ${key}`) diff --git a/src/run/handlers/server.ts b/src/run/handlers/server.ts index 6434a571d1..0a51163bb4 100644 --- a/src/run/handlers/server.ts +++ b/src/run/handlers/server.ts @@ -2,7 +2,7 @@ import type { OutgoingHttpHeaders } from 'http' import { ComputeJsOutgoingMessage, toComputeResponse, toReqRes } from '@fastly/http-compute-js' import type { Context } from '@netlify/functions' -import { Span } from '@opentelemetry/api' +import type { Span } from '@netlify/otel/opentelemetry' import type { WorkerRequestHandler } from 'next/dist/server/lib/types.js' import { getRunConfig, setRunConfig } from '../config.js' @@ -17,7 +17,7 @@ import { nextResponseProxy } from '../revalidate.js' import { setFetchBeforeNextPatchedIt } from '../storage/storage.cjs' import { getLogger, type RequestContext } from './request-context.cjs' -import { getTracer, recordWarning } from './tracer.cjs' +import { getTracer, recordWarning, withActiveSpan } from './tracer.cjs' import { configureUseCacheHandlers } from './use-cache-handler.js' import { setupWaitUntil } from './wait-until.cjs' // make use of global fetch before Next.js applies any patching @@ -61,13 +61,13 @@ const disableFaultyTransferEncodingHandling = (res: ComputeJsOutgoingMessage) => export default async ( request: Request, _context: Context, - topLevelSpan: Span, + topLevelSpan: Span | undefined, requestContext: RequestContext, ) => { const tracer = getTracer() if (!nextHandler) { - await tracer.withActiveSpan('initialize next server', async () => { + await withActiveSpan(tracer, 'initialize next server', async () => { const { getMockedRequestHandler } = await nextImportPromise const url = new URL(request.url) @@ -80,7 +80,7 @@ export default async ( }) } - return await tracer.withActiveSpan('generate response', async (span) => { + return await withActiveSpan(tracer, 'generate response', async (span) => { const { req, res } = toReqRes(request) // Work around a bug in http-proxy in next@<14.0.2 @@ -104,7 +104,7 @@ export default async ( getLogger().withError(error).error('next handler error') console.error(error) resProxy.statusCode = 500 - span.setAttribute('http.status_code', 500) + span?.setAttribute('http.status_code', 500) resProxy.end('Internal Server Error') }) @@ -113,7 +113,7 @@ export default async ( const response = await toComputeResponse(resProxy) if (requestContext.responseCacheKey) { - topLevelSpan.setAttribute('responseCacheKey', requestContext.responseCacheKey) + topLevelSpan?.setAttribute('responseCacheKey', requestContext.responseCacheKey) } const nextCache = response.headers.get('x-nextjs-cache') @@ -135,7 +135,7 @@ export default async ( const netlifyVary = response.headers.get('netlify-vary') ?? undefined const netlifyCdnCacheControl = response.headers.get('netlify-cdn-cache-control') ?? undefined - topLevelSpan.setAttributes({ + topLevelSpan?.setAttributes({ 'x-nextjs-cache': nextCache ?? undefined, isServedFromNextCache, netlifyVary, @@ -151,7 +151,7 @@ export default async ( (!isRSCRequest && contentType?.includes('text/html'))) ?? false - topLevelSpan.setAttributes({ + topLevelSpan?.setAttributes({ isRSCRequest, isCacheableAppPage: true, contentType, diff --git a/src/run/handlers/tracer.cts b/src/run/handlers/tracer.cts index 9147fce5d9..2f141fe2a3 100644 --- a/src/run/handlers/tracer.cts +++ b/src/run/handlers/tracer.cts @@ -1,8 +1,8 @@ +import { getTracer as otelGetTracer } from '@netlify/otel' // Here we need to actually import `trace` from @opentelemetry/api to add extra wrappers // other places should import `getTracer` from this module -// eslint-disable-next-line no-restricted-imports -import { type Span, trace, type Tracer } from '@opentelemetry/api' -import { type SugaredTracer, wrapTracer } from '@opentelemetry/api/experimental' +import { trace } from '@netlify/otel/opentelemetry' +import type { Span } from '@netlify/otel/opentelemetry' import { getRequestContext, type RequestContext } from './request-context.cjs' @@ -36,57 +36,55 @@ function spanHook(span: Span): Span { return span } -// startSpan and startActiveSpan don't automatically handle span ending and error handling -// so this typing just tries to enforce not using those methods in our code -// we should be using withActiveSpan (and optionally withSpan) instead -export type RuntimeTracer = Omit - -let tracer: RuntimeTracer | undefined - -export function getTracer(): RuntimeTracer { - if (!tracer) { - const baseTracer = trace.getTracer('Next.js Runtime') - - // we add hooks to capture span start and end events to be able to add server-timings - // while preserving OTEL api - const startSpan = baseTracer.startSpan.bind(baseTracer) - baseTracer.startSpan = ( - ...args: Parameters - ): ReturnType => { - const span = startSpan(...args) - spanMeta.set(span, { start: performance.now(), name: args[0] }) - return spanHook(span) - } +type NetlifyOtelTracer = NonNullable> - const startActiveSpan = baseTracer.startActiveSpan.bind(baseTracer) - - // @ts-expect-error Target signature provides too few arguments. Expected 4 or more, but got 2. - baseTracer.startActiveSpan = ( - ...args: Parameters - ): ReturnType => { - const [name, ...restOfArgs] = args - - const augmentedArgs = restOfArgs.map((arg) => { - // callback might be 2nd, 3rd or 4th argument depending on used signature - // only callback can be a function so target that and keep rest arguments as-is - if (typeof arg === 'function') { - return (span: Span) => { - spanMeta.set(span, { start: performance.now(), name: args[0] }) - spanHook(span) - return arg(span) - } - } +let tracer: NetlifyOtelTracer | undefined - return arg - }) as typeof restOfArgs +export function getTracer(): NetlifyOtelTracer | undefined { + if (tracer) return tracer - return startActiveSpan(name, ...augmentedArgs) - } + const baseTracer = otelGetTracer('Next.js Runtime') + + if (!baseTracer) return undefined + + // we add hooks to capture span start and end events to be able to add server-timings + // while preserving OTEL api + const startSpan = baseTracer.startSpan.bind(baseTracer) + baseTracer.startSpan = ( + ...args: Parameters + ): ReturnType => { + const span = startSpan(...args) + spanMeta.set(span, { start: performance.now(), name: args[0] }) + return spanHook(span) + } - // finally use SugaredTracer - tracer = wrapTracer(baseTracer) + const startActiveSpan = baseTracer.startActiveSpan.bind(baseTracer) + + // @ts-expect-error Target signature provides too few arguments. Expected 4 or more, but got 2. + baseTracer.startActiveSpan = ( + ...args: Parameters + ): ReturnType => { + const [name, ...restOfArgs] = args + + const augmentedArgs = restOfArgs.map((arg) => { + // callback might be 2nd, 3rd or 4th argument depending on used signature + // only callback can be a function so target that and keep rest arguments as-is + if (typeof arg === 'function') { + return (span: Span) => { + spanMeta.set(span, { start: performance.now(), name: args[0] }) + spanHook(span) + return arg(span) + } + } + + return arg + }) as typeof restOfArgs + + return startActiveSpan(name, ...augmentedArgs) } + tracer = baseTracer + return tracer } @@ -102,3 +100,5 @@ export function recordWarning(warning: Error, span?: Span) { warning: true, }) } + +export { withActiveSpan } from '@netlify/otel' diff --git a/src/run/handlers/use-cache-handler.ts b/src/run/handlers/use-cache-handler.ts index 510a2087b5..0fd85ac61e 100644 --- a/src/run/handlers/use-cache-handler.ts +++ b/src/run/handlers/use-cache-handler.ts @@ -14,7 +14,7 @@ import { isAnyTagStaleOrExpired, markTagsAsStaleAndPurgeEdgeCache, } from './tags-handler.cjs' -import { getTracer } from './tracer.cjs' +import { getTracer, withActiveSpan } from './tracer.cjs' // Most of this code is copied and adapted from Next.js default 'use cache' handler implementation // https://github.com/vercel/next.js/blob/84fde91e03918344c5d356986914ab68a5083462/packages/next/src/server/lib/cache-handlers/default.ts @@ -87,11 +87,12 @@ const tmpResolvePendingBeforeCreatingAPromise = () => {} export const NetlifyDefaultUseCacheHandler = { get(cacheKey: string): ReturnType { - return getTracer().withActiveSpan( + return withActiveSpan( + getTracer(), 'DefaultUseCacheHandler.get', async (span): ReturnType => { getLogger().withFields({ cacheKey }).debug(`[NetlifyDefaultUseCacheHandler] get`) - span.setAttributes({ + span?.setAttributes({ cacheKey, }) @@ -105,7 +106,7 @@ export const NetlifyDefaultUseCacheHandler = { getLogger() .withFields({ cacheKey, status: 'MISS' }) .debug(`[NetlifyDefaultUseCacheHandler] get result`) - span.setAttributes({ + span?.setAttributes({ cacheStatus: 'miss', }) return undefined @@ -120,7 +121,7 @@ export const NetlifyDefaultUseCacheHandler = { getLogger() .withFields({ cacheKey, ttl, status: 'STALE' }) .debug(`[NetlifyDefaultUseCacheHandler] get result`) - span.setAttributes({ + span?.setAttributes({ cacheStatus: 'expired, discarded', ttl, }) @@ -134,7 +135,7 @@ export const NetlifyDefaultUseCacheHandler = { .withFields({ cacheKey, ttl, status: 'STALE BY TAG' }) .debug(`[NetlifyDefaultUseCacheHandler] get result`) - span.setAttributes({ + span?.setAttributes({ cacheStatus: 'stale tag, discarded', ttl, }) @@ -150,7 +151,7 @@ export const NetlifyDefaultUseCacheHandler = { getLogger() .withFields({ cacheKey, ttl, status: 'HIT' }) .debug(`[NetlifyDefaultUseCacheHandler] get result`) - span.setAttributes({ + span?.setAttributes({ cacheStatus: 'hit', ttl, }) @@ -163,11 +164,12 @@ export const NetlifyDefaultUseCacheHandler = { ) }, set(cacheKey: string, pendingEntry: Promise): ReturnType { - return getTracer().withActiveSpan( + return withActiveSpan( + getTracer(), 'DefaultUseCacheHandler.set', async (span): ReturnType => { getLogger().withFields({ cacheKey }).debug(`[NetlifyDefaultUseCacheHandler]: set`) - span.setAttributes({ + span?.setAttributes({ cacheKey, }) @@ -182,7 +184,7 @@ export const NetlifyDefaultUseCacheHandler = { const entry = await pendingEntry - span.setAttributes({ + span?.setAttributes({ cacheKey, }) @@ -196,7 +198,7 @@ export const NetlifyDefaultUseCacheHandler = { size += Buffer.from(chunk.value).byteLength } - span.setAttributes({ + span?.setAttributes({ tags: entry.tags, timestamp: entry.timestamp, revalidate: entry.revalidate, @@ -224,10 +226,11 @@ export const NetlifyDefaultUseCacheHandler = { // while blocking pipeline }, getExpiration: function (...tags: string[]): ReturnType { - return getTracer().withActiveSpan( + return withActiveSpan( + getTracer(), 'DefaultUseCacheHandler.getExpiration', async (span): ReturnType => { - span.setAttributes({ + span?.setAttributes({ tags, }) @@ -236,7 +239,7 @@ export const NetlifyDefaultUseCacheHandler = { getLogger() .withFields({ tags, expiration }) .debug(`[NetlifyDefaultUseCacheHandler] getExpiration`) - span.setAttributes({ + span?.setAttributes({ expiration, }) @@ -245,11 +248,12 @@ export const NetlifyDefaultUseCacheHandler = { ) }, expireTags(...tags: string[]): ReturnType { - return getTracer().withActiveSpan( + return withActiveSpan( + getTracer(), 'DefaultUseCacheHandler.expireTags', async (span): ReturnType => { getLogger().withFields({ tags }).debug(`[NetlifyDefaultUseCacheHandler] expireTags`) - span.setAttributes({ + span?.setAttributes({ tags, }) diff --git a/src/run/headers.ts b/src/run/headers.ts index a4b66b4734..0ed7adbc6e 100644 --- a/src/run/headers.ts +++ b/src/run/headers.ts @@ -1,4 +1,4 @@ -import type { Span } from '@opentelemetry/api' +import type { Span } from '@netlify/otel/opentelemetry' import type { NextConfigComplete } from 'next/dist/server/config-shared.js' import type { NetlifyCachedRouteValue, NetlifyCacheHandlerValue } from '../shared/cache-types.cjs' @@ -152,7 +152,7 @@ export const adjustDateHeader = async ({ }: { headers: Headers request: Request - span: Span + span?: Span requestContext: RequestContext }) => { const key = new URL(request.url).pathname diff --git a/src/run/next.cts b/src/run/next.cts index 779b995e2b..7be6df5edb 100644 --- a/src/run/next.cts +++ b/src/run/next.cts @@ -9,7 +9,7 @@ import { HtmlBlob } from '../shared/blob-types.cjs' import type { NextConfigForMultipleVersions } from './config.js' import { getRequestContext } from './handlers/request-context.cjs' -import { getTracer } from './handlers/tracer.cjs' +import { getTracer, withActiveSpan } from './handlers/tracer.cjs' import { getMemoizedKeyValueStoreBackedByRegionalBlobStore } from './storage/storage.cjs' // https://github.com/vercel/next.js/pull/68193/files#diff-37243d614f1f5d3f7ea50bbf2af263f6b1a9a4f70e84427977781e07b02f57f1R49 @@ -91,8 +91,7 @@ export async function getMockedRequestHandler( */ const initAsyncLocalStorage = new AsyncLocalStorage() - const tracer = getTracer() - return tracer.withActiveSpan('mocked request handler', async () => { + return withActiveSpan(getTracer(), 'mocked request handler', async () => { const ofs = { ...fs } async function readFileFallbackBlobStore(...fsargs: Parameters) { diff --git a/src/run/storage/storage.cts b/src/run/storage/storage.cts index 273c8822de..98f11268f2 100644 --- a/src/run/storage/storage.cts +++ b/src/run/storage/storage.cts @@ -4,7 +4,7 @@ // There is eslint `no-restricted-imports` rule to enforce this. import { type BlobType } from '../../shared/blob-types.cjs' -import { getTracer } from '../handlers/tracer.cjs' +import { getTracer, withActiveSpan } from '../handlers/tracer.cjs' import { getRegionalBlobStore } from './regional-blob-store.cjs' import { getRequestScopedInMemoryCache } from './request-scoped-in-memory-cache.cjs' @@ -30,11 +30,11 @@ export const getMemoizedKeyValueStoreBackedByRegionalBlobStore = ( } const blobKey = await encodeBlobKey(key) - const getPromise = tracer.withActiveSpan(otelSpanTitle, async (span) => { - span.setAttributes({ key, blobKey }) + const getPromise = withActiveSpan(tracer, otelSpanTitle, async (span) => { + span?.setAttributes({ key, blobKey }) const blob = (await store.get(blobKey, { type: 'json' })) as T | null inMemoryCache.set(key, blob) - span.addEvent(blob ? 'Hit' : 'Miss') + span?.addEvent(blob ? 'Hit' : 'Miss') return blob }) inMemoryCache.set(key, getPromise) @@ -46,8 +46,8 @@ export const getMemoizedKeyValueStoreBackedByRegionalBlobStore = ( inMemoryCache.set(key, value) const blobKey = await encodeBlobKey(key) - return tracer.withActiveSpan(otelSpanTitle, async (span) => { - span.setAttributes({ key, blobKey }) + return withActiveSpan(tracer, otelSpanTitle, async (span) => { + span?.setAttributes({ key, blobKey }) return await store.setJSON(blobKey, value) }) },