From 8e876f0dff9bf3013d4b5da52df23a154d27d3d0 Mon Sep 17 00:00:00 2001 From: t2t2 Date: Wed, 31 Jan 2024 14:51:36 +0200 Subject: [PATCH 01/10] Add otlp exporter support behind config option --- package-lock.json | 466 ++++++++++++------ packages/web/package.json | 25 +- packages/web/src/exporters/common.ts | 45 ++ packages/web/src/exporters/otlp.ts | 70 +++ packages/web/src/exporters/rate-limit.ts | 75 +++ .../zipkin.ts} | 62 +-- packages/web/src/index.ts | 26 +- 7 files changed, 543 insertions(+), 226 deletions(-) create mode 100644 packages/web/src/exporters/common.ts create mode 100644 packages/web/src/exporters/otlp.ts create mode 100644 packages/web/src/exporters/rate-limit.ts rename packages/web/src/{SplunkExporter.ts => exporters/zipkin.ts} (69%) diff --git a/package-lock.json b/package-lock.json index 4eae201b..c38b7c38 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3392,36 +3392,65 @@ } }, "node_modules/@opentelemetry/api": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.6.0.tgz", - "integrity": "sha512-OWlrQAnWn9577PhVgqjUvMr1pg57Bc4jv0iL4w0PRuOSRvq67rvHW9Ie/dZVMvCzhSCB+UxhcY/PmCmFj33Q+g==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.7.0.tgz", + "integrity": "sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==", "engines": { "node": ">=8.0.0" } }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.48.0.tgz", + "integrity": "sha512-1/aMiU4Eqo3Zzpfwu51uXssp5pzvHFObk8S9pKAiXb1ne8pvg1qxBQitYL1XUiAMEXFzgjaidYG2V6624DRhhw==", + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/@opentelemetry/core": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.17.1.tgz", - "integrity": "sha512-I6LrZvl1FF97FQXPR0iieWQmKnGxYtMbWA1GrAXnLUR+B1Hn2m8KqQNEIlZAucyv00GBgpWkpllmULmZfG8P3g==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.21.0.tgz", + "integrity": "sha512-KP+OIweb3wYoP7qTYL/j5IpOlu52uxBv5M4+QhSmmUfLyTgu1OIS71msK3chFo1D6Y61BIH3wMiMYRCxJCQctA==", "dependencies": { - "@opentelemetry/semantic-conventions": "1.17.1" + "@opentelemetry/semantic-conventions": "1.21.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.7.0" + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.48.0.tgz", + "integrity": "sha512-QEZKbfWqXrbKVpr2PHd4KyKI0XVOhUYC+p2RPV8s+2K5QzZBE3+F9WlxxrXDfkrvGmpQAZytBoHQQYA3AGOtpw==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/otlp-exporter-base": "0.48.0", + "@opentelemetry/otlp-transformer": "0.48.0", + "@opentelemetry/resources": "1.21.0", + "@opentelemetry/sdk-trace-base": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" } }, "node_modules/@opentelemetry/exporter-zipkin": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-1.17.1.tgz", - "integrity": "sha512-FaLZlIhdpxlZiKu/G8OvA+so4xoCL1hCo/JgNdeSxzI4GnJrmFFbZT6DXgUzXJO7F9Qw3KDE1cBFUHawLVz58g==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-1.21.0.tgz", + "integrity": "sha512-J0ejrOx52s1PqvjNalIHvY/4v9ZxR2r7XS7WZbwK3qpVYZlGVq5V1+iCNweqsKnb/miUt/4TFvJBc9f5Q/kGcA==", "dependencies": { - "@opentelemetry/core": "1.17.1", - "@opentelemetry/resources": "1.17.1", - "@opentelemetry/sdk-trace-base": "1.17.1", - "@opentelemetry/semantic-conventions": "1.17.1" + "@opentelemetry/core": "1.21.0", + "@opentelemetry/resources": "1.21.0", + "@opentelemetry/sdk-trace-base": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" }, "engines": { "node": ">=14" @@ -3431,12 +3460,12 @@ } }, "node_modules/@opentelemetry/instrumentation": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.44.0.tgz", - "integrity": "sha512-B6OxJTRRCceAhhnPDBshyQO7K07/ltX3quOLu0icEvPK9QZ7r9P1y0RQX8O5DxB4vTv4URRkxkg+aFU/plNtQw==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.48.0.tgz", + "integrity": "sha512-sjtZQB5PStIdCw5ovVTDGwnmQC+GGYArJNgIcydrDSqUTdYBnMrN9P4pwQZgS3vTGIp+TU1L8vMXGe51NVmIKQ==", "dependencies": { "@types/shimmer": "^1.0.2", - "import-in-the-middle": "1.4.2", + "import-in-the-middle": "1.7.1", "require-in-the-middle": "^7.1.1", "semver": "^7.5.2", "shimmer": "^1.2.1" @@ -3449,12 +3478,12 @@ } }, "node_modules/@opentelemetry/instrumentation-document-load": { - "version": "0.33.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-document-load/-/instrumentation-document-load-0.33.2.tgz", - "integrity": "sha512-9RaEdaGBB5MS327dpBinfNcNuHcHZvqqLXsf4C+j92UZeIgKE2tuYuvbcSruDeECW6PdYknX7wtnJNAFXyRSMg==", + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-document-load/-/instrumentation-document-load-0.35.0.tgz", + "integrity": "sha512-U3zQBjbAF0rm7GT7YJ8DPqgiCdBoshmld4c1pZe3tAGAMa5QPIjonIfSMSvJ2XMh6Nvi+8Rfe3XFCe0cuWIjsQ==", "dependencies": { "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.44.0", + "@opentelemetry/instrumentation": "^0.48.0", "@opentelemetry/sdk-trace-base": "^1.0.0", "@opentelemetry/sdk-trace-web": "^1.15.0", "@opentelemetry/semantic-conventions": "^1.0.0" @@ -3467,14 +3496,14 @@ } }, "node_modules/@opentelemetry/instrumentation-fetch": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fetch/-/instrumentation-fetch-0.44.0.tgz", - "integrity": "sha512-2AhpCgugeiAqOKuYs5Yl4oMwsqyzDWgKq2VuOxhZzyyxs0aCjKCu+IAZbiP02gg+Y5gMPOThngxfNzivCzXxCQ==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fetch/-/instrumentation-fetch-0.48.0.tgz", + "integrity": "sha512-y4Zw9VeUUMaowg3aXYZXcaUJQ7IKfpR6sjClrAQOJwWG8LYFpM6NIRSoAeJv/ShfxWWCPWC0P4zgXcKRqpURFQ==", "dependencies": { - "@opentelemetry/core": "1.17.1", - "@opentelemetry/instrumentation": "0.44.0", - "@opentelemetry/sdk-trace-web": "1.17.1", - "@opentelemetry/semantic-conventions": "1.17.1" + "@opentelemetry/core": "1.21.0", + "@opentelemetry/instrumentation": "0.48.0", + "@opentelemetry/sdk-trace-web": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" }, "engines": { "node": ">=14" @@ -3484,14 +3513,28 @@ } }, "node_modules/@opentelemetry/instrumentation-xml-http-request": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-xml-http-request/-/instrumentation-xml-http-request-0.44.0.tgz", - "integrity": "sha512-wK3YoC40PzZUYRsdPo9VssOYLVeu1by05VQDBaL/Aiyoko7I0wakQ2Fg425IM06TJ2jbWQh4E+B3x4v0bsmoLw==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-xml-http-request/-/instrumentation-xml-http-request-0.48.0.tgz", + "integrity": "sha512-YJ9d1sR28hcEVtP4/tHtPX5Hhu0w2LsAMp3M+75YGTHkkunsN8PwcY/1FcSHUP9xwy7Z2myQvT7fTpL3g4tn4A==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/instrumentation": "0.48.0", + "@opentelemetry/sdk-trace-web": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.48.0.tgz", + "integrity": "sha512-T4LJND+Ugl87GUONoyoQzuV9qCn4BFIPOnCH1biYqdGhc2JahjuLqVD9aefwLzGBW638iLAo88Lh68h2F1FLiA==", "dependencies": { - "@opentelemetry/core": "1.17.1", - "@opentelemetry/instrumentation": "0.44.0", - "@opentelemetry/sdk-trace-web": "1.17.1", - "@opentelemetry/semantic-conventions": "1.17.1" + "@opentelemetry/core": "1.21.0" }, "engines": { "node": ">=14" @@ -3500,57 +3543,108 @@ "@opentelemetry/api": "^1.0.0" } }, + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.48.0.tgz", + "integrity": "sha512-yuoS4cUumaTK/hhxW3JUy3wl2U4keMo01cFDrUOmjloAdSSXvv1zyQ920IIH4lymp5Xd21Dj2/jq2LOro56TJg==", + "dependencies": { + "@opentelemetry/api-logs": "0.48.0", + "@opentelemetry/core": "1.21.0", + "@opentelemetry/resources": "1.21.0", + "@opentelemetry/sdk-logs": "0.48.0", + "@opentelemetry/sdk-metrics": "1.21.0", + "@opentelemetry/sdk-trace-base": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.8.0" + } + }, "node_modules/@opentelemetry/resources": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.17.1.tgz", - "integrity": "sha512-M2e5emqg5I7qRKqlzKx0ROkcPyF8PbcSaWEdsm72od9txP7Z/Pl8PDYOyu80xWvbHAWk5mDxOF6v3vNdifzclA==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.21.0.tgz", + "integrity": "sha512-1Z86FUxPKL6zWVy2LdhueEGl9AHDJcx+bvHStxomruz6Whd02mE3lNUMjVJ+FGRoktx/xYQcxccYb03DiUP6Yw==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.8.0" + } + }, + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.48.0.tgz", + "integrity": "sha512-lRcA5/qkSJuSh4ItWCddhdn/nNbVvnzM+cm9Fg1xpZUeTeozjJDBcHnmeKoOaWRnrGYBdz6UTY6bynZR9aBeAA==", "dependencies": { - "@opentelemetry/core": "1.17.1", - "@opentelemetry/semantic-conventions": "1.17.1" + "@opentelemetry/core": "1.21.0", + "@opentelemetry/resources": "1.21.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.7.0" + "@opentelemetry/api": ">=1.4.0 <1.8.0", + "@opentelemetry/api-logs": ">=0.39.1" + } + }, + "node_modules/@opentelemetry/sdk-metrics": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.21.0.tgz", + "integrity": "sha512-on1jTzIHc5DyWhRP+xpf+zrgrREXcHBH4EDAfaB5mIG7TWpKxNXooQ1JCylaPsswZUv4wGnVTinr4HrBdGARAQ==", + "dependencies": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/resources": "1.21.0", + "lodash.merge": "^4.6.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.8.0" } }, "node_modules/@opentelemetry/sdk-trace-base": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.17.1.tgz", - "integrity": "sha512-pfSJJSjZj5jkCJUQZicSpzN8Iz9UKMryPWikZRGObPnJo6cUSoKkjZh6BM3j+D47G4olMBN+YZKYqkFM1L6zNA==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.21.0.tgz", + "integrity": "sha512-yrElGX5Fv0umzp8Nxpta/XqU71+jCAyaLk34GmBzNcrW43nqbrqvdPs4gj4MVy/HcTjr6hifCDCYA3rMkajxxA==", "dependencies": { - "@opentelemetry/core": "1.17.1", - "@opentelemetry/resources": "1.17.1", - "@opentelemetry/semantic-conventions": "1.17.1" + "@opentelemetry/core": "1.21.0", + "@opentelemetry/resources": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.7.0" + "@opentelemetry/api": ">=1.0.0 <1.8.0" } }, "node_modules/@opentelemetry/sdk-trace-web": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.17.1.tgz", - "integrity": "sha512-Nle48xE1eaR6lRqyOvUlIwW/C2Bz6pptHzlHqrd+a6tGSLWEP1ZhPfuJbNeq/tWX5PX2RgeOsLlvPLEEBKeKxg==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.21.0.tgz", + "integrity": "sha512-MxkmY/UNXkDiZj7JUu5T7wWt8Ai4NJEwSjGoQQ9YLvgLUIivvaIo9Mne+Q+KLOUG2v/uhivz3qzxbCODVa0c1A==", "dependencies": { - "@opentelemetry/core": "1.17.1", - "@opentelemetry/sdk-trace-base": "1.17.1", - "@opentelemetry/semantic-conventions": "1.17.1" + "@opentelemetry/core": "1.21.0", + "@opentelemetry/sdk-trace-base": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.7.0" + "@opentelemetry/api": ">=1.0.0 <1.8.0" } }, "node_modules/@opentelemetry/semantic-conventions": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.17.1.tgz", - "integrity": "sha512-xbR2U+2YjauIuo42qmE8XyJK6dYeRMLJuOlUP5SO4auET4VtOHOzgkRVOq+Ik18N+Xf3YPcqJs9dZMiDddz1eQ==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.21.0.tgz", + "integrity": "sha512-lkC8kZYntxVKr7b8xmjCVUgE0a8xgDakPyDo9uSWavXPyYqLgYYGdEd2j8NxihRyb6UwpX3G/hFUF4/9q2V+/g==", "engines": { "node": ">=14" } @@ -9797,9 +9891,9 @@ } }, "node_modules/import-in-the-middle": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz", - "integrity": "sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.7.1.tgz", + "integrity": "sha512-1LrZPDtW+atAxH42S6288qyDFNQ2YCty+2mxEPRtfazH6Z5QwkaBSTS2ods7hnVJioF6rkRfNoA6A/MstpFXLg==", "dependencies": { "acorn": "^8.8.2", "acorn-import-assertions": "^1.9.0", @@ -11541,8 +11635,7 @@ "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "node_modules/lodash.pick": { "version": "4.4.0", @@ -16426,9 +16519,9 @@ } }, "node_modules/web-vitals": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.4.0.tgz", - "integrity": "sha512-n9fZ5/bG1oeDkyxLWyep0eahrNcPDF6bFqoyispt7xkW0xhDzpUBTgyDKqWDi1twT0MgH4HvvqzpUyh0ZxZV4A==" + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.5.2.tgz", + "integrity": "sha512-c0rhqNcHXRkY/ogGDJQxZ9Im9D19hDihbzSQJrsioex+KnFgmMzBiy57Z1EjkhX/+OjyBpclDCzz2ITtjokFmg==" }, "node_modules/webidl-conversions": { "version": "7.0.0", @@ -16928,19 +17021,20 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.22.6", - "@opentelemetry/api": "^1.6.0", - "@opentelemetry/core": "^1.17.1", - "@opentelemetry/exporter-zipkin": "^1.17.1", - "@opentelemetry/instrumentation": "^0.44.0", - "@opentelemetry/instrumentation-document-load": "^0.33.2", - "@opentelemetry/instrumentation-fetch": "^0.44.0", - "@opentelemetry/instrumentation-xml-http-request": "^0.44.0", - "@opentelemetry/resources": "^1.17.1", - "@opentelemetry/sdk-trace-base": "^1.17.1", - "@opentelemetry/sdk-trace-web": "^1.17.1", - "@opentelemetry/semantic-conventions": "^1.17.1", + "@opentelemetry/api": "^1.7.0", + "@opentelemetry/core": "^1.21.0", + "@opentelemetry/exporter-trace-otlp-http": "^0.48.0", + "@opentelemetry/exporter-zipkin": "^1.21.0", + "@opentelemetry/instrumentation": "^0.48.0", + "@opentelemetry/instrumentation-document-load": "^0.35.0", + "@opentelemetry/instrumentation-fetch": "^0.48.0", + "@opentelemetry/instrumentation-xml-http-request": "^0.48.0", + "@opentelemetry/resources": "^1.21.0", + "@opentelemetry/sdk-trace-base": "^1.21.0", + "@opentelemetry/sdk-trace-web": "^1.21.0", + "@opentelemetry/semantic-conventions": "^1.21.0", "shimmer": "^1.2.1", - "web-vitals": "^3.4.0" + "web-vitals": "^3.5.2" }, "devDependencies": { "@babel/plugin-transform-runtime": "^7.22.9", @@ -19569,108 +19663,168 @@ } }, "@opentelemetry/api": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.6.0.tgz", - "integrity": "sha512-OWlrQAnWn9577PhVgqjUvMr1pg57Bc4jv0iL4w0PRuOSRvq67rvHW9Ie/dZVMvCzhSCB+UxhcY/PmCmFj33Q+g==" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.7.0.tgz", + "integrity": "sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==" + }, + "@opentelemetry/api-logs": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.48.0.tgz", + "integrity": "sha512-1/aMiU4Eqo3Zzpfwu51uXssp5pzvHFObk8S9pKAiXb1ne8pvg1qxBQitYL1XUiAMEXFzgjaidYG2V6624DRhhw==", + "requires": { + "@opentelemetry/api": "^1.0.0" + } }, "@opentelemetry/core": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.17.1.tgz", - "integrity": "sha512-I6LrZvl1FF97FQXPR0iieWQmKnGxYtMbWA1GrAXnLUR+B1Hn2m8KqQNEIlZAucyv00GBgpWkpllmULmZfG8P3g==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.21.0.tgz", + "integrity": "sha512-KP+OIweb3wYoP7qTYL/j5IpOlu52uxBv5M4+QhSmmUfLyTgu1OIS71msK3chFo1D6Y61BIH3wMiMYRCxJCQctA==", "requires": { - "@opentelemetry/semantic-conventions": "1.17.1" + "@opentelemetry/semantic-conventions": "1.21.0" + } + }, + "@opentelemetry/exporter-trace-otlp-http": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.48.0.tgz", + "integrity": "sha512-QEZKbfWqXrbKVpr2PHd4KyKI0XVOhUYC+p2RPV8s+2K5QzZBE3+F9WlxxrXDfkrvGmpQAZytBoHQQYA3AGOtpw==", + "requires": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/otlp-exporter-base": "0.48.0", + "@opentelemetry/otlp-transformer": "0.48.0", + "@opentelemetry/resources": "1.21.0", + "@opentelemetry/sdk-trace-base": "1.21.0" } }, "@opentelemetry/exporter-zipkin": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-1.17.1.tgz", - "integrity": "sha512-FaLZlIhdpxlZiKu/G8OvA+so4xoCL1hCo/JgNdeSxzI4GnJrmFFbZT6DXgUzXJO7F9Qw3KDE1cBFUHawLVz58g==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-1.21.0.tgz", + "integrity": "sha512-J0ejrOx52s1PqvjNalIHvY/4v9ZxR2r7XS7WZbwK3qpVYZlGVq5V1+iCNweqsKnb/miUt/4TFvJBc9f5Q/kGcA==", "requires": { - "@opentelemetry/core": "1.17.1", - "@opentelemetry/resources": "1.17.1", - "@opentelemetry/sdk-trace-base": "1.17.1", - "@opentelemetry/semantic-conventions": "1.17.1" + "@opentelemetry/core": "1.21.0", + "@opentelemetry/resources": "1.21.0", + "@opentelemetry/sdk-trace-base": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" } }, "@opentelemetry/instrumentation": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.44.0.tgz", - "integrity": "sha512-B6OxJTRRCceAhhnPDBshyQO7K07/ltX3quOLu0icEvPK9QZ7r9P1y0RQX8O5DxB4vTv4URRkxkg+aFU/plNtQw==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.48.0.tgz", + "integrity": "sha512-sjtZQB5PStIdCw5ovVTDGwnmQC+GGYArJNgIcydrDSqUTdYBnMrN9P4pwQZgS3vTGIp+TU1L8vMXGe51NVmIKQ==", "requires": { "@types/shimmer": "^1.0.2", - "import-in-the-middle": "1.4.2", + "import-in-the-middle": "1.7.1", "require-in-the-middle": "^7.1.1", "semver": "^7.5.2", "shimmer": "^1.2.1" } }, "@opentelemetry/instrumentation-document-load": { - "version": "0.33.2", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-document-load/-/instrumentation-document-load-0.33.2.tgz", - "integrity": "sha512-9RaEdaGBB5MS327dpBinfNcNuHcHZvqqLXsf4C+j92UZeIgKE2tuYuvbcSruDeECW6PdYknX7wtnJNAFXyRSMg==", + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-document-load/-/instrumentation-document-load-0.35.0.tgz", + "integrity": "sha512-U3zQBjbAF0rm7GT7YJ8DPqgiCdBoshmld4c1pZe3tAGAMa5QPIjonIfSMSvJ2XMh6Nvi+8Rfe3XFCe0cuWIjsQ==", "requires": { "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.44.0", + "@opentelemetry/instrumentation": "^0.48.0", "@opentelemetry/sdk-trace-base": "^1.0.0", "@opentelemetry/sdk-trace-web": "^1.15.0", "@opentelemetry/semantic-conventions": "^1.0.0" } }, "@opentelemetry/instrumentation-fetch": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fetch/-/instrumentation-fetch-0.44.0.tgz", - "integrity": "sha512-2AhpCgugeiAqOKuYs5Yl4oMwsqyzDWgKq2VuOxhZzyyxs0aCjKCu+IAZbiP02gg+Y5gMPOThngxfNzivCzXxCQ==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fetch/-/instrumentation-fetch-0.48.0.tgz", + "integrity": "sha512-y4Zw9VeUUMaowg3aXYZXcaUJQ7IKfpR6sjClrAQOJwWG8LYFpM6NIRSoAeJv/ShfxWWCPWC0P4zgXcKRqpURFQ==", "requires": { - "@opentelemetry/core": "1.17.1", - "@opentelemetry/instrumentation": "0.44.0", - "@opentelemetry/sdk-trace-web": "1.17.1", - "@opentelemetry/semantic-conventions": "1.17.1" + "@opentelemetry/core": "1.21.0", + "@opentelemetry/instrumentation": "0.48.0", + "@opentelemetry/sdk-trace-web": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" } }, "@opentelemetry/instrumentation-xml-http-request": { - "version": "0.44.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-xml-http-request/-/instrumentation-xml-http-request-0.44.0.tgz", - "integrity": "sha512-wK3YoC40PzZUYRsdPo9VssOYLVeu1by05VQDBaL/Aiyoko7I0wakQ2Fg425IM06TJ2jbWQh4E+B3x4v0bsmoLw==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-xml-http-request/-/instrumentation-xml-http-request-0.48.0.tgz", + "integrity": "sha512-YJ9d1sR28hcEVtP4/tHtPX5Hhu0w2LsAMp3M+75YGTHkkunsN8PwcY/1FcSHUP9xwy7Z2myQvT7fTpL3g4tn4A==", "requires": { - "@opentelemetry/core": "1.17.1", - "@opentelemetry/instrumentation": "0.44.0", - "@opentelemetry/sdk-trace-web": "1.17.1", - "@opentelemetry/semantic-conventions": "1.17.1" + "@opentelemetry/core": "1.21.0", + "@opentelemetry/instrumentation": "0.48.0", + "@opentelemetry/sdk-trace-web": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" + } + }, + "@opentelemetry/otlp-exporter-base": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.48.0.tgz", + "integrity": "sha512-T4LJND+Ugl87GUONoyoQzuV9qCn4BFIPOnCH1biYqdGhc2JahjuLqVD9aefwLzGBW638iLAo88Lh68h2F1FLiA==", + "requires": { + "@opentelemetry/core": "1.21.0" + } + }, + "@opentelemetry/otlp-transformer": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.48.0.tgz", + "integrity": "sha512-yuoS4cUumaTK/hhxW3JUy3wl2U4keMo01cFDrUOmjloAdSSXvv1zyQ920IIH4lymp5Xd21Dj2/jq2LOro56TJg==", + "requires": { + "@opentelemetry/api-logs": "0.48.0", + "@opentelemetry/core": "1.21.0", + "@opentelemetry/resources": "1.21.0", + "@opentelemetry/sdk-logs": "0.48.0", + "@opentelemetry/sdk-metrics": "1.21.0", + "@opentelemetry/sdk-trace-base": "1.21.0" } }, "@opentelemetry/resources": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.17.1.tgz", - "integrity": "sha512-M2e5emqg5I7qRKqlzKx0ROkcPyF8PbcSaWEdsm72od9txP7Z/Pl8PDYOyu80xWvbHAWk5mDxOF6v3vNdifzclA==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.21.0.tgz", + "integrity": "sha512-1Z86FUxPKL6zWVy2LdhueEGl9AHDJcx+bvHStxomruz6Whd02mE3lNUMjVJ+FGRoktx/xYQcxccYb03DiUP6Yw==", "requires": { - "@opentelemetry/core": "1.17.1", - "@opentelemetry/semantic-conventions": "1.17.1" + "@opentelemetry/core": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" + } + }, + "@opentelemetry/sdk-logs": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.48.0.tgz", + "integrity": "sha512-lRcA5/qkSJuSh4ItWCddhdn/nNbVvnzM+cm9Fg1xpZUeTeozjJDBcHnmeKoOaWRnrGYBdz6UTY6bynZR9aBeAA==", + "requires": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/resources": "1.21.0" + } + }, + "@opentelemetry/sdk-metrics": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.21.0.tgz", + "integrity": "sha512-on1jTzIHc5DyWhRP+xpf+zrgrREXcHBH4EDAfaB5mIG7TWpKxNXooQ1JCylaPsswZUv4wGnVTinr4HrBdGARAQ==", + "requires": { + "@opentelemetry/core": "1.21.0", + "@opentelemetry/resources": "1.21.0", + "lodash.merge": "^4.6.2" } }, "@opentelemetry/sdk-trace-base": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.17.1.tgz", - "integrity": "sha512-pfSJJSjZj5jkCJUQZicSpzN8Iz9UKMryPWikZRGObPnJo6cUSoKkjZh6BM3j+D47G4olMBN+YZKYqkFM1L6zNA==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.21.0.tgz", + "integrity": "sha512-yrElGX5Fv0umzp8Nxpta/XqU71+jCAyaLk34GmBzNcrW43nqbrqvdPs4gj4MVy/HcTjr6hifCDCYA3rMkajxxA==", "requires": { - "@opentelemetry/core": "1.17.1", - "@opentelemetry/resources": "1.17.1", - "@opentelemetry/semantic-conventions": "1.17.1" + "@opentelemetry/core": "1.21.0", + "@opentelemetry/resources": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" } }, "@opentelemetry/sdk-trace-web": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.17.1.tgz", - "integrity": "sha512-Nle48xE1eaR6lRqyOvUlIwW/C2Bz6pptHzlHqrd+a6tGSLWEP1ZhPfuJbNeq/tWX5PX2RgeOsLlvPLEEBKeKxg==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.21.0.tgz", + "integrity": "sha512-MxkmY/UNXkDiZj7JUu5T7wWt8Ai4NJEwSjGoQQ9YLvgLUIivvaIo9Mne+Q+KLOUG2v/uhivz3qzxbCODVa0c1A==", "requires": { - "@opentelemetry/core": "1.17.1", - "@opentelemetry/sdk-trace-base": "1.17.1", - "@opentelemetry/semantic-conventions": "1.17.1" + "@opentelemetry/core": "1.21.0", + "@opentelemetry/sdk-trace-base": "1.21.0", + "@opentelemetry/semantic-conventions": "1.21.0" } }, "@opentelemetry/semantic-conventions": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.17.1.tgz", - "integrity": "sha512-xbR2U+2YjauIuo42qmE8XyJK6dYeRMLJuOlUP5SO4auET4VtOHOzgkRVOq+Ik18N+Xf3YPcqJs9dZMiDddz1eQ==" + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.21.0.tgz", + "integrity": "sha512-lkC8kZYntxVKr7b8xmjCVUgE0a8xgDakPyDo9uSWavXPyYqLgYYGdEd2j8NxihRyb6UwpX3G/hFUF4/9q2V+/g==" }, "@pkgjs/parseargs": { "version": "0.11.0", @@ -20555,17 +20709,18 @@ "@babel/preset-env": "^7.22.9", "@babel/runtime": "^7.22.6", "@babel/runtime-corejs3": "^7.22.6", - "@opentelemetry/api": "^1.6.0", - "@opentelemetry/core": "^1.17.1", - "@opentelemetry/exporter-zipkin": "^1.17.1", - "@opentelemetry/instrumentation": "^0.44.0", - "@opentelemetry/instrumentation-document-load": "^0.33.2", - "@opentelemetry/instrumentation-fetch": "^0.44.0", - "@opentelemetry/instrumentation-xml-http-request": "^0.44.0", - "@opentelemetry/resources": "^1.17.1", - "@opentelemetry/sdk-trace-base": "^1.17.1", - "@opentelemetry/sdk-trace-web": "^1.17.1", - "@opentelemetry/semantic-conventions": "^1.17.1", + "@opentelemetry/api": "^1.7.0", + "@opentelemetry/core": "^1.21.0", + "@opentelemetry/exporter-trace-otlp-http": "^0.48.0", + "@opentelemetry/exporter-zipkin": "^1.21.0", + "@opentelemetry/instrumentation": "^0.48.0", + "@opentelemetry/instrumentation-document-load": "^0.35.0", + "@opentelemetry/instrumentation-fetch": "^0.48.0", + "@opentelemetry/instrumentation-xml-http-request": "^0.48.0", + "@opentelemetry/resources": "^1.21.0", + "@opentelemetry/sdk-trace-base": "^1.21.0", + "@opentelemetry/sdk-trace-web": "^1.21.0", + "@opentelemetry/semantic-conventions": "^1.21.0", "@rollup/plugin-babel": "^6.0.3", "@rollup/plugin-commonjs": "^25.0.3", "@rollup/plugin-json": "^6.0.0", @@ -20613,7 +20768,7 @@ "socket.io": "^4.7.1", "socket.io-client": "^4.7.1", "ts-node": "^10.9.1", - "web-vitals": "^3.4.0", + "web-vitals": "^3.5.2", "ws": "^8.13.0" } }, @@ -24561,9 +24716,9 @@ } }, "import-in-the-middle": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.4.2.tgz", - "integrity": "sha512-9WOz1Yh/cvO/p69sxRmhyQwrIGGSp7EIdcb+fFNVi7CzQGQB8U1/1XrKVSbEd/GNOAeM0peJtmi7+qphe7NvAw==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.7.1.tgz", + "integrity": "sha512-1LrZPDtW+atAxH42S6288qyDFNQ2YCty+2mxEPRtfazH6Z5QwkaBSTS2ods7hnVJioF6rkRfNoA6A/MstpFXLg==", "requires": { "acorn": "^8.8.2", "acorn-import-assertions": "^1.9.0", @@ -25959,8 +26114,7 @@ "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "lodash.pick": { "version": "4.4.0", @@ -29702,9 +29856,9 @@ "dev": true }, "web-vitals": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.4.0.tgz", - "integrity": "sha512-n9fZ5/bG1oeDkyxLWyep0eahrNcPDF6bFqoyispt7xkW0xhDzpUBTgyDKqWDi1twT0MgH4HvvqzpUyh0ZxZV4A==" + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.5.2.tgz", + "integrity": "sha512-c0rhqNcHXRkY/ogGDJQxZ9Im9D19hDihbzSQJrsioex+KnFgmMzBiy57Z1EjkhX/+OjyBpclDCzz2ITtjokFmg==" }, "webidl-conversions": { "version": "7.0.0", diff --git a/packages/web/package.json b/packages/web/package.json index bb122875..ee0de42c 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -47,19 +47,20 @@ ], "dependencies": { "@babel/runtime": "^7.22.6", - "@opentelemetry/api": "^1.6.0", - "@opentelemetry/core": "^1.17.1", - "@opentelemetry/exporter-zipkin": "^1.17.1", - "@opentelemetry/instrumentation": "^0.44.0", - "@opentelemetry/instrumentation-document-load": "^0.33.2", - "@opentelemetry/instrumentation-fetch": "^0.44.0", - "@opentelemetry/instrumentation-xml-http-request": "^0.44.0", - "@opentelemetry/resources": "^1.17.1", - "@opentelemetry/sdk-trace-base": "^1.17.1", - "@opentelemetry/sdk-trace-web": "^1.17.1", - "@opentelemetry/semantic-conventions": "^1.17.1", + "@opentelemetry/api": "^1.7.0", + "@opentelemetry/core": "^1.21.0", + "@opentelemetry/exporter-trace-otlp-http": "^0.48.0", + "@opentelemetry/exporter-zipkin": "^1.21.0", + "@opentelemetry/instrumentation": "^0.48.0", + "@opentelemetry/instrumentation-document-load": "^0.35.0", + "@opentelemetry/instrumentation-fetch": "^0.48.0", + "@opentelemetry/instrumentation-xml-http-request": "^0.48.0", + "@opentelemetry/resources": "^1.21.0", + "@opentelemetry/sdk-trace-base": "^1.21.0", + "@opentelemetry/sdk-trace-web": "^1.21.0", + "@opentelemetry/semantic-conventions": "^1.21.0", "shimmer": "^1.2.1", - "web-vitals": "^3.4.0" + "web-vitals": "^3.5.2" }, "devDependencies": { "@babel/plugin-transform-runtime": "^7.22.9", diff --git a/packages/web/src/exporters/common.ts b/packages/web/src/exporters/common.ts new file mode 100644 index 00000000..e1a03fc7 --- /dev/null +++ b/packages/web/src/exporters/common.ts @@ -0,0 +1,45 @@ +/* +Copyright 2024 Splunk Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { Attributes } from '@opentelemetry/api'; +import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; + +export interface SplunkExporterConfig { + url: string; + onAttributesSerializing?: (attributes: Attributes, span: ReadableSpan) => Attributes, + xhrSender?: (url: string, data: string, headers?: Record) => void, + beaconSender?: (url: string, data: string, headers?: Record) => void, +} + +export function NOOP_ATTRIBUTES_TRANSFORMER(attributes: Attributes): Attributes { + return attributes; +} +export function NATIVE_XHR_SENDER(url: string, data: string, headers?: Record): void { + const xhr = new XMLHttpRequest(); + xhr.open('POST', url); + const defaultHeaders = { + Accept: 'application/json', + 'Content-Type': 'application/json', + }; + Object.entries(Object.assign(Object.assign({}, defaultHeaders), headers)).forEach(([k, v]) => { + xhr.setRequestHeader(k, v); + }); + xhr.send(data); +} +export function NATIVE_BEACON_SENDER(url: string, data: string, blobPropertyBag?: BlobPropertyBag): void { + const payload = blobPropertyBag ? new Blob([data], blobPropertyBag) : data; + navigator.sendBeacon(url, payload); +} diff --git a/packages/web/src/exporters/otlp.ts b/packages/web/src/exporters/otlp.ts new file mode 100644 index 00000000..7d1df93d --- /dev/null +++ b/packages/web/src/exporters/otlp.ts @@ -0,0 +1,70 @@ +/* +Copyright 2024 Splunk Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { diag } from '@opentelemetry/api'; +import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; +import { NOOP_ATTRIBUTES_TRANSFORMER, NATIVE_XHR_SENDER, NATIVE_BEACON_SENDER, SplunkExporterConfig } from './common'; +import { IExportTraceServiceRequest } from '@opentelemetry/otlp-transformer'; +import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; + +export class SplunkOTLPTraceExporter extends OTLPTraceExporter { + protected readonly _onAttributesSerializing: SplunkExporterConfig['onAttributesSerializing']; + protected readonly _xhrSender: SplunkExporterConfig['xhrSender'] = NATIVE_XHR_SENDER; + protected readonly _beaconSender: SplunkExporterConfig['beaconSender'] = typeof navigator !== 'undefined' && navigator.sendBeacon ? NATIVE_BEACON_SENDER : undefined; + + constructor(options: SplunkExporterConfig) { + super(options); + this._onAttributesSerializing = options.onAttributesSerializing || NOOP_ATTRIBUTES_TRANSFORMER; + } + + convert(spans: ReadableSpan[]): IExportTraceServiceRequest { + // Changes: Add attribute serializing hook to remove data before export + spans = spans.map(span => { + // @ts-expect-error Yep we're overwriting a readonly property here. Deal with it + span.attributes = this._onAttributesSerializing ? this._onAttributesSerializing(span.attributes, span) : span.attributes; + return span; + }); + + return super.convert(spans); + } + + send( + items: ReadableSpan[], + onSuccess: () => void, + ): void { + if (this._shutdownOnce.isCalled) { + diag.debug('Shutdown already started. Cannot send objects'); + return; + } + const serviceRequest = this.convert(items); + const body = JSON.stringify(serviceRequest); + + // Changed: Determine which exporter to use at the time of export + if (document.hidden && this._beaconSender && body.length <= 64000) { + this._beaconSender(this.url, body, { type: 'application/json' }); + } else { + this._xhrSender!(this.url, body, { + // These headers may only be necessary for otel's collector, + // need to test with actual ingest + Accept: 'application/json', + 'Content-Type': 'application/json', + ...this.headers + }); + } + + onSuccess(); + } +} \ No newline at end of file diff --git a/packages/web/src/exporters/rate-limit.ts b/packages/web/src/exporters/rate-limit.ts new file mode 100644 index 00000000..c57ba18a --- /dev/null +++ b/packages/web/src/exporters/rate-limit.ts @@ -0,0 +1,75 @@ +/* +Copyright 2024 Splunk Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { Context } from '@opentelemetry/api'; + +import { ReadableSpan, Span, SpanProcessor } from '@opentelemetry/sdk-trace-base'; + +const SPAN_RATE_LIMIT_PERIOD = 30000; // millis, sweep to clear out span counts +const MAX_SPANS_PER_PERIOD_PER_COMPONENT = 100; + +export class RateLimitProcessor implements SpanProcessor { + protected readonly _spanCounts = new Map(); + protected readonly _parents = new Map(); + protected readonly _limiterHandle: number; + + constructor( + protected _processor: SpanProcessor + ) { + this._limiterHandle = window.setInterval(() => { + this._spanCounts.clear(); + }, SPAN_RATE_LIMIT_PERIOD); + } + + forceFlush(): Promise { + return this._processor.forceFlush(); + } + + protected _filter(span: ReadableSpan): boolean { + if (span.parentSpanId) { + this._parents.set(span.parentSpanId, true); + } + const component = (span.attributes?.component ?? 'unknown').toString(); + if (!this._spanCounts.has(component)) { + this._spanCounts.set(component, -1); + } + const counter = (this._spanCounts.get(component) || 0) + 1; + this._spanCounts.set(component, counter); + + const { spanId } = span.spanContext(); + if (this._parents.has(spanId)) { + this._parents.delete(spanId); + return true; + } + return counter < MAX_SPANS_PER_PERIOD_PER_COMPONENT; + } + + onStart(span: Span, parentContext: Context): void { + return this._processor.onStart(span, parentContext); + } + + onEnd(span: ReadableSpan): void { + if (this._filter(span)) { + this._processor.onEnd(span); + } + } + + shutdown(): Promise { + clearInterval(this._limiterHandle); + return this._processor.shutdown(); + } + +} diff --git a/packages/web/src/SplunkExporter.ts b/packages/web/src/exporters/zipkin.ts similarity index 69% rename from packages/web/src/SplunkExporter.ts rename to packages/web/src/exporters/zipkin.ts index 5007a69c..0c10a2f1 100644 --- a/packages/web/src/SplunkExporter.ts +++ b/packages/web/src/exporters/zipkin.ts @@ -20,32 +20,14 @@ import { defaultStatusErrorTagName, } from '@opentelemetry/exporter-zipkin/build/src/transform.js'; import { ExportResult, ExportResultCode } from '@opentelemetry/core'; -import { limitLen } from './utils'; -import { SpanAttributes, SpanKind } from '@opentelemetry/api'; +import { SpanKind } from '@opentelemetry/api'; import { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace-base'; +import { limitLen } from '../utils'; +import { NOOP_ATTRIBUTES_TRANSFORMER, NATIVE_XHR_SENDER, NATIVE_BEACON_SENDER, SplunkExporterConfig } from './common'; const MAX_VALUE_LIMIT = 4096; -const SPAN_RATE_LIMIT_PERIOD = 30000; // millis, sweep to clear out span counts -const MAX_SPANS_PER_PERIOD_PER_COMPONENT = 100; const SERVICE_NAME = 'browser'; -export interface SplunkExporterConfig { - beaconUrl: string; - onAttributesSerializing?: (attributes: SpanAttributes, span: ReadableSpan) => SpanAttributes, - xhrSender?: (url: string, data) => void, - beaconSender?: (url: string, data: BodyInit) => void, -} - -export const NOOP_ATTRIBUTES_TRANSFORMER: SplunkExporterConfig['onAttributesSerializing'] = (attributes) => attributes; -export const NATIVE_XHR_SENDER: SplunkExporterConfig['xhrSender'] = (url: string, data) => { - const xhr = new XMLHttpRequest(); - xhr.open('POST', url); - xhr.setRequestHeader('Accept', '*/*'); - xhr.setRequestHeader('Content-Type', 'text/plain;charset=UTF-8'); - xhr.send(data); -}; -export const NATIVE_BEACON_SENDER: SplunkExporterConfig['beaconSender'] = typeof navigator !== 'undefined' && navigator.sendBeacon ? (url, data) => navigator.sendBeacon(url, data) : undefined; - // TODO: upstream proper exports from ZipkinExporter export interface ZipkinAnnotation { timestamp: number; @@ -83,70 +65,46 @@ export interface ZipkinSpan { /** * SplunkExporter is based on Zipkin V2. It includes Splunk-specific modifications. */ -export class SplunkExporter implements SpanExporter { +export class SplunkZipkinExporter implements SpanExporter { // TODO: a test which relies on beaconUrl needs to be fixed first public readonly beaconUrl: string; private readonly _onAttributesSerializing: SplunkExporterConfig['onAttributesSerializing']; private readonly _xhrSender: SplunkExporterConfig['xhrSender']; private readonly _beaconSender: SplunkExporterConfig['beaconSender']; - private readonly _spanCounts = new Map(); - private readonly _parents = new Map(); - private readonly _limiterHandle: number; constructor({ - beaconUrl, + url, onAttributesSerializing = NOOP_ATTRIBUTES_TRANSFORMER, xhrSender = NATIVE_XHR_SENDER, beaconSender = NATIVE_BEACON_SENDER, }: SplunkExporterConfig) { - this.beaconUrl = beaconUrl; + this.beaconUrl = url; this._onAttributesSerializing = onAttributesSerializing; this._xhrSender = xhrSender; this._beaconSender = beaconSender; - this._limiterHandle = window.setInterval(() => { - this._spanCounts.clear(); - }, SPAN_RATE_LIMIT_PERIOD); } export( spans: ReadableSpan[], resultCallback: (result: ExportResult) => void ): void { - spans = spans.filter(span => this._filter(span)); const zspans = spans.map(span => this._mapToZipkinSpan(span)); const zJson = JSON.stringify(zspans); if (document.hidden && this._beaconSender && zJson.length <= 64000) { this._beaconSender(this.beaconUrl, zJson); } else { - this._xhrSender(this.beaconUrl, zJson); + this._xhrSender(this.beaconUrl, zJson, { + Accept: '*/*', + 'Content-Type': 'text/plain;charset=UTF-8', + }); } resultCallback({ code: ExportResultCode.SUCCESS }); } shutdown(): Promise { - clearInterval(this._limiterHandle); return Promise.resolve(); } - private _filter(span: ReadableSpan) { - if (span.parentSpanId) { - this._parents.set(span.parentSpanId, true); - } - const component = (span.attributes?.component ?? 'unknown').toString(); - if (!this._spanCounts.has(component)) { - this._spanCounts.set(component, -1); - } - const counter = this._spanCounts.get(component) + 1; - this._spanCounts.set(component, counter); - - const { spanId } = span.spanContext(); - if (this._parents.has(spanId)) { - this._parents.delete(spanId); - return true; - } - return counter < MAX_SPANS_PER_PERIOD_PER_COMPONENT; - } - private _mapToZipkinSpan(span: ReadableSpan): ZipkinSpan { const preparedSpan = this._preTranslateSpan(span); const zspan = toZipkinSpan(preparedSpan, SERVICE_NAME, defaultStatusCodeTagName, defaultStatusErrorTagName); diff --git a/packages/web/src/index.ts b/packages/web/src/index.ts index 4a8442aa..369af157 100644 --- a/packages/web/src/index.ts +++ b/packages/web/src/index.ts @@ -38,7 +38,8 @@ import { DEFAULT_AUTO_INSTRUMENTED_EVENT_NAMES, UserInteractionEventsConfig, } from './SplunkUserInteractionInstrumentation'; -import { SplunkExporter, SplunkExporterConfig } from './SplunkExporter'; +import { SplunkExporterConfig } from './exporters/common'; +import { SplunkZipkinExporter } from './exporters/zipkin'; import { ERROR_INSTRUMENTATION_NAME, SplunkErrorInstrumentation } from './SplunkErrorInstrumentation'; import { generateId, getPluginConfig } from './utils'; import { getRumSessionId, initSessionTracking, SessionIdType } from './session'; @@ -67,8 +68,10 @@ import { getSyntheticsRunId, SYNTHETICS_RUN_ID_ATTRIBUTE } from './synthetics'; import { SplunkSpanAttributesProcessor } from './SplunkSpanAttributesProcessor'; import { SessionBasedSampler } from './SessionBasedSampler'; import { SocketIoClientInstrumentationConfig, SplunkSocketIoClientInstrumentation } from './SplunkSocketIoClientInstrumentation'; +import { SplunkOTLPTraceExporter } from './exporters/otlp'; -export * from './SplunkExporter'; +export { SplunkExporterConfig } from './exporters/common'; +export { SplunkZipkinExporter } from './exporters/zipkin'; export * from './SplunkWebTracerProvider'; export * from './SessionBasedSampler'; @@ -93,6 +96,11 @@ export interface SplunkOtelWebExporterOptions { * One potential use case of this method is to remove PII from the attributes. */ onAttributesSerializing?: (attributes: Attributes, span: ReadableSpan) => Attributes; + + /** + * Switch from zipkin to otlp for exporting + */ + otlp?: boolean; } export interface SplunkOtelWebConfig { @@ -185,7 +193,7 @@ interface SplunkOtelWebConfigInternal extends SplunkOtelWebConfig { bufferTimeout?: number; exporter: SplunkOtelWebExporterOptions & { - factory: (config: SplunkExporterConfig) => SpanExporter; + factory: (config: SplunkExporterConfig & {otlp?: boolean}) => SpanExporter; }; instrumentations: SplunkOtelWebOptionsInstrumentations; @@ -202,7 +210,12 @@ const OPTIONS_DEFAULTS: SplunkOtelWebConfigInternal = { bufferSize: 50, // spans, tradeoff between batching and hitting sendBeacon invididual limits instrumentations: {}, exporter: { - factory: (options) => new SplunkExporter(options), + factory: (options) => { + if (options.otlp) { + return new SplunkOTLPTraceExporter(options); + } + return new SplunkZipkinExporter(options); + }, }, spanProcessor: { factory: (exporter, config) => new BatchSpanProcessor(exporter, config), @@ -250,9 +263,10 @@ export const INSTRUMENTATIONS_ALL_DISABLED: SplunkOtelWebOptionsInstrumentations ); function buildExporter(options: SplunkOtelWebConfigInternal) { - const beaconUrl = options.beaconEndpoint + (options.rumAccessToken ? '?auth='+options.rumAccessToken : ''); + const url = options.beaconEndpoint + (options.rumAccessToken ? '?auth='+options.rumAccessToken : ''); return options.exporter.factory({ - beaconUrl, + url, + otlp: options.exporter.otlp, onAttributesSerializing: options.exporter.onAttributesSerializing, }); } From e5972a3f82d06e15fe7d143c866ef1413c41f67e Mon Sep 17 00:00:00 2001 From: t2t2 Date: Wed, 31 Jan 2024 15:10:14 +0200 Subject: [PATCH 02/10] Fixes for tests --- packages/web/package.json | 2 +- packages/web/test/SplunkExporter.test.ts | 32 ++++++++++++------------ packages/web/test/utils.ts | 7 +++--- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/packages/web/package.json b/packages/web/package.json index ee0de42c..2d00ca98 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -80,7 +80,7 @@ "browserstack-local": "^1.5.3", "chai": "^4.3.7", "chrome-launcher": "^1.0.0", - "chromedriver": "^119.0.1", + "chromedriver": "^121.0.0", "codecov": "^3.8.2", "compression": "^1.7.4", "cors": "^2.8.5", diff --git a/packages/web/test/SplunkExporter.test.ts b/packages/web/test/SplunkExporter.test.ts index 3c8863cb..b207f859 100644 --- a/packages/web/test/SplunkExporter.test.ts +++ b/packages/web/test/SplunkExporter.test.ts @@ -19,7 +19,7 @@ import { expect } from 'chai'; import * as api from '@opentelemetry/api'; import { timeInputToHrTime } from '@opentelemetry/core'; -import { SplunkExporter } from '../src/SplunkExporter'; +import { SplunkZipkinExporter } from '../src/exporters/zipkin'; function buildDummySpan({ name = '', @@ -42,7 +42,7 @@ function buildDummySpan({ }; } -describe('SplunkExporter', () => { +describe('SplunkZipkinExporter', () => { let beaconSenderMock; let xhrSenderMock; let exporter; @@ -58,8 +58,8 @@ describe('SplunkExporter', () => { }); it('uses Beacon API if in background', () => { - exporter = new SplunkExporter({ - beaconUrl: 'https://domain1', + exporter = new SplunkZipkinExporter({ + url: 'https://domain1', xhrSender: xhrSenderMock, }); @@ -86,8 +86,8 @@ describe('SplunkExporter', () => { }); it('uses XHR if Beacon API is unavailable', () => { - exporter = new SplunkExporter({ - beaconUrl: 'https://domain2', + exporter = new SplunkZipkinExporter({ + url: 'https://domain2', beaconSender: null, xhrSender: xhrSenderMock, }); @@ -103,8 +103,8 @@ describe('SplunkExporter', () => { }); it('limits spans sent', () => { - exporter = new SplunkExporter({ - beaconUrl: 'https://localhost', + exporter = new SplunkZipkinExporter({ + url: 'https://localhost', xhrSender: xhrSenderMock, }); @@ -118,8 +118,8 @@ describe('SplunkExporter', () => { }); it('still exports parent spans', () => { - exporter = new SplunkExporter({ - beaconUrl: 'https://localhost', + exporter = new SplunkZipkinExporter({ + url: 'https://localhost', xhrSender: xhrSenderMock, }); @@ -140,8 +140,8 @@ describe('SplunkExporter', () => { }); it('truncates long values', () => { - exporter = new SplunkExporter({ - beaconUrl: 'https://localhost', + exporter = new SplunkZipkinExporter({ + url: 'https://localhost', xhrSender: xhrSenderMock, }); @@ -161,8 +161,8 @@ describe('SplunkExporter', () => { }); it('filters out missing cors timings', () => { - exporter = new SplunkExporter({ - beaconUrl: 'https://localhost', + exporter = new SplunkZipkinExporter({ + url: 'https://localhost', xhrSender: xhrSenderMock, }); @@ -195,8 +195,8 @@ describe('SplunkExporter', () => { }); it('allows hooking into serialization', () => { - exporter = new SplunkExporter({ - beaconUrl: 'https://localhost', + exporter = new SplunkZipkinExporter({ + url: 'https://localhost', xhrSender: xhrSenderMock, onAttributesSerializing: (attributes) => ({ ...attributes, diff --git a/packages/web/test/utils.ts b/packages/web/test/utils.ts index 542813c5..d4d8923e 100644 --- a/packages/web/test/utils.ts +++ b/packages/web/test/utils.ts @@ -15,7 +15,8 @@ limitations under the License. */ import { ReadableSpan, SimpleSpanProcessor, SpanProcessor } from '@opentelemetry/sdk-trace-base'; -import SplunkRum, { SplunkExporter, ZipkinSpan } from '../src/index'; +import SplunkRum, { SplunkZipkinExporter } from '../src/index'; +import { ZipkinSpan } from '../src/exporters/zipkin'; export class SpanCapturer implements SpanProcessor { public readonly spans: ReadableSpan[] = []; @@ -31,11 +32,11 @@ export class SpanCapturer implements SpanProcessor { } export function buildInMemorySplunkExporter(): { - exporter: SplunkExporter, + exporter: SplunkZipkinExporter, getFinishedSpans: () => ZipkinSpan[], } { const spans: ZipkinSpan[] = []; - const exporter = new SplunkExporter({ + const exporter = new SplunkZipkinExporter({ beaconUrl: null, beaconSender: null, xhrSender: (_, data) => { From caaef317180b7c1e7ab28f4ace5ad5d3326638e4 Mon Sep 17 00:00:00 2001 From: t2t2 Date: Wed, 31 Jan 2024 15:15:37 +0200 Subject: [PATCH 03/10] update package-lock --- package-lock.json | 48 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index c38b7c38..b75fc599 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5693,12 +5693,12 @@ } }, "node_modules/axios": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", - "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dev": true, "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.4", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -6409,14 +6409,14 @@ } }, "node_modules/chromedriver": { - "version": "119.0.1", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-119.0.1.tgz", - "integrity": "sha512-lpCFFLaXPpvElTaUOWKdP74pFb/sJhWtWqMjn7Ju1YriWn8dT5JBk84BGXMPvZQs70WfCYWecxdMmwfIu1Mupg==", + "version": "121.0.0", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-121.0.0.tgz", + "integrity": "sha512-ZIKEdZrQAfuzT/RRofjl8/EZR99ghbdBXNTOcgJMKGP6N/UL6lHUX4n6ONWBV18pDvDFfQJ0x58h5AdOaXIOMw==", "dev": true, "hasInstallScript": true, "dependencies": { "@testim/chrome-version": "^1.1.4", - "axios": "^1.6.0", + "axios": "^1.6.5", "compare-versions": "^6.1.0", "extract-zip": "^2.0.1", "https-proxy-agent": "^5.0.1", @@ -8841,9 +8841,9 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "dev": true, "funding": [ { @@ -17054,7 +17054,7 @@ "browserstack-local": "^1.5.3", "chai": "^4.3.7", "chrome-launcher": "^1.0.0", - "chromedriver": "^119.0.1", + "chromedriver": "^121.0.0", "codecov": "^3.8.2", "compression": "^1.7.4", "cors": "^2.8.5", @@ -20735,7 +20735,7 @@ "browserstack-local": "^1.5.3", "chai": "^4.3.7", "chrome-launcher": "^1.0.0", - "chromedriver": "^119.0.1", + "chromedriver": "^121.0.0", "codecov": "^3.8.2", "compression": "^1.7.4", "cors": "^2.8.5", @@ -21507,12 +21507,12 @@ "dev": true }, "axios": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz", - "integrity": "sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", "dev": true, "requires": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.4", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -22033,13 +22033,13 @@ } }, "chromedriver": { - "version": "119.0.1", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-119.0.1.tgz", - "integrity": "sha512-lpCFFLaXPpvElTaUOWKdP74pFb/sJhWtWqMjn7Ju1YriWn8dT5JBk84BGXMPvZQs70WfCYWecxdMmwfIu1Mupg==", + "version": "121.0.0", + "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-121.0.0.tgz", + "integrity": "sha512-ZIKEdZrQAfuzT/RRofjl8/EZR99ghbdBXNTOcgJMKGP6N/UL6lHUX4n6ONWBV18pDvDFfQJ0x58h5AdOaXIOMw==", "dev": true, "requires": { "@testim/chrome-version": "^1.1.4", - "axios": "^1.6.0", + "axios": "^1.6.5", "compare-versions": "^6.1.0", "extract-zip": "^2.0.1", "https-proxy-agent": "^5.0.1", @@ -23958,9 +23958,9 @@ "dev": true }, "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", + "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "dev": true }, "for-each": { From 62f4ad9e470cba045571382298d14d3da0a725c9 Mon Sep 17 00:00:00 2001 From: t2t2 Date: Wed, 31 Jan 2024 15:51:53 +0200 Subject: [PATCH 04/10] fix tests a bit more --- packages/web/test/SplunkExporter.test.ts | 86 +++++++++++++----------- packages/web/test/utils.ts | 2 +- 2 files changed, 49 insertions(+), 39 deletions(-) diff --git a/packages/web/test/SplunkExporter.test.ts b/packages/web/test/SplunkExporter.test.ts index b207f859..822fb363 100644 --- a/packages/web/test/SplunkExporter.test.ts +++ b/packages/web/test/SplunkExporter.test.ts @@ -20,6 +20,8 @@ import { expect } from 'chai'; import * as api from '@opentelemetry/api'; import { timeInputToHrTime } from '@opentelemetry/core'; import { SplunkZipkinExporter } from '../src/exporters/zipkin'; +import { RateLimitProcessor } from '../src/exporters/rate-limit'; +import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; function buildDummySpan({ name = '', @@ -39,7 +41,7 @@ function buildDummySpan({ status: { code: api.SpanStatusCode.UNSET }, resource: { attributes: {} }, events: [] as ({time: api.HrTime; name: string})[], - }; + } as ReadableSpan; } describe('SplunkZipkinExporter', () => { @@ -102,43 +104,6 @@ describe('SplunkZipkinExporter', () => { expect(sentSpan.id).to.equal('0001'); }); - it('limits spans sent', () => { - exporter = new SplunkZipkinExporter({ - url: 'https://localhost', - xhrSender: xhrSenderMock, - }); - - const dummySpan = buildDummySpan(); - const spans: (typeof dummySpan)[] = []; - for (let i = 0; i < 110; i++) { spans.push(dummySpan); } - exporter.export(spans, () => {}); - - const sentSpans = JSON.parse(xhrSenderMock.getCall(0).args[1]); - expect(sentSpans).to.have.lengthOf(100); - }); - - it('still exports parent spans', () => { - exporter = new SplunkZipkinExporter({ - url: 'https://localhost', - xhrSender: xhrSenderMock, - }); - - const dummySpan = buildDummySpan(); - const spans: (typeof dummySpan)[] = []; - for (let i = 0; i < 110; i++) { spans.push(dummySpan); } - const parentSpan = buildDummySpan(); - parentSpan.spanContext = () => ({ - traceId: '0000', - spanId: '0002', - }); - parentSpan.parentSpanId = undefined; - spans.push(parentSpan); - exporter.export(spans, () => {}); - - const sentSpans = JSON.parse(xhrSenderMock.getCall(0).args[1]); - expect(sentSpans).to.have.lengthOf(101); - }); - it('truncates long values', () => { exporter = new SplunkZipkinExporter({ url: 'https://localhost', @@ -224,3 +189,48 @@ describe('SplunkZipkinExporter', () => { }); }); }); + +describe('Rate Limiter', () => { + it('limits spans sent', () => { + const allowedSpans: ReadableSpan[] = []; + const rateLimiter = new RateLimitProcessor({ + onStart() {}, + onEnd(span) { + allowedSpans.push(span); + }, + forceFlush() { return Promise.resolve(); }, + shutdown() { return Promise.resolve(); } + }); + + const dummySpan = buildDummySpan(); + for (let i = 0; i < 110; i++) { rateLimiter.onEnd(dummySpan); } + + expect(allowedSpans).to.have.lengthOf(100); + }); + + it('still exports parent spans', () => { + const allowedSpans: ReadableSpan[] = []; + const rateLimiter = new RateLimitProcessor({ + onStart() {}, + onEnd(span) { + allowedSpans.push(span); + }, + forceFlush() { return Promise.resolve(); }, + shutdown() { return Promise.resolve(); } + }); + + const dummySpan = buildDummySpan(); + for (let i = 0; i < 110; i++) { rateLimiter.onEnd(dummySpan); } + const parentSpan = buildDummySpan(); + // @ts-expect-error read-only + parentSpan.spanContext = () => ({ + traceId: '0000', + spanId: '0002', + }); + // @ts-expect-error read-only + parentSpan.parentSpanId = undefined; + rateLimiter.onEnd(parentSpan); + + expect(allowedSpans).to.have.lengthOf(101); + }); +}); diff --git a/packages/web/test/utils.ts b/packages/web/test/utils.ts index d4d8923e..bfbcbfd5 100644 --- a/packages/web/test/utils.ts +++ b/packages/web/test/utils.ts @@ -37,7 +37,7 @@ export function buildInMemorySplunkExporter(): { } { const spans: ZipkinSpan[] = []; const exporter = new SplunkZipkinExporter({ - beaconUrl: null, + url: '', beaconSender: null, xhrSender: (_, data) => { if (typeof data === 'string') { From be66fc7e0738c1f6fe7f49504c8f71ff9686c1fe Mon Sep 17 00:00:00 2001 From: t2t2 Date: Tue, 12 Mar 2024 15:04:11 +0200 Subject: [PATCH 05/10] update deps --- package-lock.json | 448 +++++++++++++------------ packages/session-recorder/package.json | 6 +- packages/web/package.json | 24 +- 3 files changed, 254 insertions(+), 224 deletions(-) diff --git a/package-lock.json b/package-lock.json index b75fc599..59349db3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3400,9 +3400,9 @@ } }, "node_modules/@opentelemetry/api-logs": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.48.0.tgz", - "integrity": "sha512-1/aMiU4Eqo3Zzpfwu51uXssp5pzvHFObk8S9pKAiXb1ne8pvg1qxBQitYL1XUiAMEXFzgjaidYG2V6624DRhhw==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.49.1.tgz", + "integrity": "sha512-kaNl/T7WzyMUQHQlVq7q0oV4Kev6+0xFwqzofryC66jgGMacd0QH5TwfpbUwSTby+SdAdprAe5UKMvBw4tKS5Q==", "dependencies": { "@opentelemetry/api": "^1.0.0" }, @@ -3411,29 +3411,29 @@ } }, "node_modules/@opentelemetry/core": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.21.0.tgz", - "integrity": "sha512-KP+OIweb3wYoP7qTYL/j5IpOlu52uxBv5M4+QhSmmUfLyTgu1OIS71msK3chFo1D6Y61BIH3wMiMYRCxJCQctA==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.22.0.tgz", + "integrity": "sha512-0VoAlT6x+Xzik1v9goJ3pZ2ppi6+xd3aUfg4brfrLkDBHRIVjMP0eBHrKrhB+NKcDyMAg8fAbGL3Npg/F6AwWA==", "dependencies": { - "@opentelemetry/semantic-conventions": "1.21.0" + "@opentelemetry/semantic-conventions": "1.22.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.8.0" + "@opentelemetry/api": ">=1.0.0 <1.9.0" } }, "node_modules/@opentelemetry/exporter-trace-otlp-http": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.48.0.tgz", - "integrity": "sha512-QEZKbfWqXrbKVpr2PHd4KyKI0XVOhUYC+p2RPV8s+2K5QzZBE3+F9WlxxrXDfkrvGmpQAZytBoHQQYA3AGOtpw==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.49.1.tgz", + "integrity": "sha512-KOLtZfZvIrpGZLVvblKsiVQT7gQUZNKcUUH24Zz6Xbi7LJb9Vt6xtUZFYdR5IIjvt47PIqBKDWUQlU0o1wAsRw==", "dependencies": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/otlp-exporter-base": "0.48.0", - "@opentelemetry/otlp-transformer": "0.48.0", - "@opentelemetry/resources": "1.21.0", - "@opentelemetry/sdk-trace-base": "1.21.0" + "@opentelemetry/core": "1.22.0", + "@opentelemetry/otlp-exporter-base": "0.49.1", + "@opentelemetry/otlp-transformer": "0.49.1", + "@opentelemetry/resources": "1.22.0", + "@opentelemetry/sdk-trace-base": "1.22.0" }, "engines": { "node": ">=14" @@ -3443,14 +3443,14 @@ } }, "node_modules/@opentelemetry/exporter-zipkin": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-1.21.0.tgz", - "integrity": "sha512-J0ejrOx52s1PqvjNalIHvY/4v9ZxR2r7XS7WZbwK3qpVYZlGVq5V1+iCNweqsKnb/miUt/4TFvJBc9f5Q/kGcA==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-1.22.0.tgz", + "integrity": "sha512-XcFs6rGvcTz0qW5uY7JZDYD0yNEXdekXAb6sFtnZgY/cHY6BQ09HMzOjv9SX+iaXplRDcHr1Gta7VQKM1XXM6g==", "dependencies": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/resources": "1.21.0", - "@opentelemetry/sdk-trace-base": "1.21.0", - "@opentelemetry/semantic-conventions": "1.21.0" + "@opentelemetry/core": "1.22.0", + "@opentelemetry/resources": "1.22.0", + "@opentelemetry/sdk-trace-base": "1.22.0", + "@opentelemetry/semantic-conventions": "1.22.0" }, "engines": { "node": ">=14" @@ -3460,10 +3460,11 @@ } }, "node_modules/@opentelemetry/instrumentation": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.48.0.tgz", - "integrity": "sha512-sjtZQB5PStIdCw5ovVTDGwnmQC+GGYArJNgIcydrDSqUTdYBnMrN9P4pwQZgS3vTGIp+TU1L8vMXGe51NVmIKQ==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.49.1.tgz", + "integrity": "sha512-0DLtWtaIppuNNRRllSD4bjU8ZIiLp1cDXvJEbp752/Zf+y3gaLNaoGRGIlX4UHhcsrmtL+P2qxi3Hodi8VuKiQ==", "dependencies": { + "@opentelemetry/api-logs": "0.49.1", "@types/shimmer": "^1.0.2", "import-in-the-middle": "1.7.1", "require-in-the-middle": "^7.1.1", @@ -3478,12 +3479,12 @@ } }, "node_modules/@opentelemetry/instrumentation-document-load": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-document-load/-/instrumentation-document-load-0.35.0.tgz", - "integrity": "sha512-U3zQBjbAF0rm7GT7YJ8DPqgiCdBoshmld4c1pZe3tAGAMa5QPIjonIfSMSvJ2XMh6Nvi+8Rfe3XFCe0cuWIjsQ==", + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-document-load/-/instrumentation-document-load-0.36.0.tgz", + "integrity": "sha512-LBz4Lr5XMlo3F0SVeNS4H8wn6GC0EQs7Up258AMROaxq9gZiYM1ZyecbvNz3wPvP0d8wP1D8qcO45pWBHK/4tw==", "dependencies": { "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.48.0", + "@opentelemetry/instrumentation": "^0.49.1", "@opentelemetry/sdk-trace-base": "^1.0.0", "@opentelemetry/sdk-trace-web": "^1.15.0", "@opentelemetry/semantic-conventions": "^1.0.0" @@ -3496,14 +3497,14 @@ } }, "node_modules/@opentelemetry/instrumentation-fetch": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fetch/-/instrumentation-fetch-0.48.0.tgz", - "integrity": "sha512-y4Zw9VeUUMaowg3aXYZXcaUJQ7IKfpR6sjClrAQOJwWG8LYFpM6NIRSoAeJv/ShfxWWCPWC0P4zgXcKRqpURFQ==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fetch/-/instrumentation-fetch-0.49.1.tgz", + "integrity": "sha512-hizhULZXlq02y8YC0vPQ4WtUWiXcwxPdEqHBy8p75jzF9rAuP/ldrVr0Oxvz5Xr9qQcdEOFLvEl0ZxbVL76WKw==", "dependencies": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/instrumentation": "0.48.0", - "@opentelemetry/sdk-trace-web": "1.21.0", - "@opentelemetry/semantic-conventions": "1.21.0" + "@opentelemetry/core": "1.22.0", + "@opentelemetry/instrumentation": "0.49.1", + "@opentelemetry/sdk-trace-web": "1.22.0", + "@opentelemetry/semantic-conventions": "1.22.0" }, "engines": { "node": ">=14" @@ -3513,14 +3514,14 @@ } }, "node_modules/@opentelemetry/instrumentation-xml-http-request": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-xml-http-request/-/instrumentation-xml-http-request-0.48.0.tgz", - "integrity": "sha512-YJ9d1sR28hcEVtP4/tHtPX5Hhu0w2LsAMp3M+75YGTHkkunsN8PwcY/1FcSHUP9xwy7Z2myQvT7fTpL3g4tn4A==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-xml-http-request/-/instrumentation-xml-http-request-0.49.1.tgz", + "integrity": "sha512-gCPd2o1geRXc1urJoLxWRnMKAF6Akbwlp1nfe+xg2akSUenlt4wopmq1gEIrJva4bXLsNSModVLrEVCTt5/fDA==", "dependencies": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/instrumentation": "0.48.0", - "@opentelemetry/sdk-trace-web": "1.21.0", - "@opentelemetry/semantic-conventions": "1.21.0" + "@opentelemetry/core": "1.22.0", + "@opentelemetry/instrumentation": "0.49.1", + "@opentelemetry/sdk-trace-web": "1.22.0", + "@opentelemetry/semantic-conventions": "1.22.0" }, "engines": { "node": ">=14" @@ -3530,11 +3531,11 @@ } }, "node_modules/@opentelemetry/otlp-exporter-base": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.48.0.tgz", - "integrity": "sha512-T4LJND+Ugl87GUONoyoQzuV9qCn4BFIPOnCH1biYqdGhc2JahjuLqVD9aefwLzGBW638iLAo88Lh68h2F1FLiA==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.49.1.tgz", + "integrity": "sha512-z6sHliPqDgJU45kQatAettY9/eVF58qVPaTuejw9YWfSRqid9pXPYeegDCSdyS47KAUgAtm+nC28K3pfF27HWg==", "dependencies": { - "@opentelemetry/core": "1.21.0" + "@opentelemetry/core": "1.22.0" }, "engines": { "node": ">=14" @@ -3544,107 +3545,107 @@ } }, "node_modules/@opentelemetry/otlp-transformer": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.48.0.tgz", - "integrity": "sha512-yuoS4cUumaTK/hhxW3JUy3wl2U4keMo01cFDrUOmjloAdSSXvv1zyQ920IIH4lymp5Xd21Dj2/jq2LOro56TJg==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.49.1.tgz", + "integrity": "sha512-Z+koA4wp9L9e3jkFacyXTGphSWTbOKjwwXMpb0CxNb0kjTHGUxhYRN8GnkLFsFo5NbZPjP07hwAqeEG/uCratQ==", "dependencies": { - "@opentelemetry/api-logs": "0.48.0", - "@opentelemetry/core": "1.21.0", - "@opentelemetry/resources": "1.21.0", - "@opentelemetry/sdk-logs": "0.48.0", - "@opentelemetry/sdk-metrics": "1.21.0", - "@opentelemetry/sdk-trace-base": "1.21.0" + "@opentelemetry/api-logs": "0.49.1", + "@opentelemetry/core": "1.22.0", + "@opentelemetry/resources": "1.22.0", + "@opentelemetry/sdk-logs": "0.49.1", + "@opentelemetry/sdk-metrics": "1.22.0", + "@opentelemetry/sdk-trace-base": "1.22.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.3.0 <1.8.0" + "@opentelemetry/api": ">=1.3.0 <1.9.0" } }, "node_modules/@opentelemetry/resources": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.21.0.tgz", - "integrity": "sha512-1Z86FUxPKL6zWVy2LdhueEGl9AHDJcx+bvHStxomruz6Whd02mE3lNUMjVJ+FGRoktx/xYQcxccYb03DiUP6Yw==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.22.0.tgz", + "integrity": "sha512-+vNeIFPH2hfcNL0AJk/ykJXoUCtR1YaDUZM+p3wZNU4Hq98gzq+7b43xbkXjadD9VhWIUQqEwXyY64q6msPj6A==", "dependencies": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/semantic-conventions": "1.21.0" + "@opentelemetry/core": "1.22.0", + "@opentelemetry/semantic-conventions": "1.22.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.8.0" + "@opentelemetry/api": ">=1.0.0 <1.9.0" } }, "node_modules/@opentelemetry/sdk-logs": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.48.0.tgz", - "integrity": "sha512-lRcA5/qkSJuSh4ItWCddhdn/nNbVvnzM+cm9Fg1xpZUeTeozjJDBcHnmeKoOaWRnrGYBdz6UTY6bynZR9aBeAA==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.49.1.tgz", + "integrity": "sha512-gCzYWsJE0h+3cuh3/cK+9UwlVFyHvj3PReIOCDOmdeXOp90ZjKRoDOJBc3mvk1LL6wyl1RWIivR8Rg9OToyesw==", "dependencies": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/resources": "1.21.0" + "@opentelemetry/core": "1.22.0", + "@opentelemetry/resources": "1.22.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.4.0 <1.8.0", + "@opentelemetry/api": ">=1.4.0 <1.9.0", "@opentelemetry/api-logs": ">=0.39.1" } }, "node_modules/@opentelemetry/sdk-metrics": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.21.0.tgz", - "integrity": "sha512-on1jTzIHc5DyWhRP+xpf+zrgrREXcHBH4EDAfaB5mIG7TWpKxNXooQ1JCylaPsswZUv4wGnVTinr4HrBdGARAQ==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.22.0.tgz", + "integrity": "sha512-k6iIx6H3TZ+BVMr2z8M16ri2OxWaljg5h8ihGJxi/KQWcjign6FEaEzuigXt5bK9wVEhqAcWLCfarSftaNWkkg==", "dependencies": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/resources": "1.21.0", + "@opentelemetry/core": "1.22.0", + "@opentelemetry/resources": "1.22.0", "lodash.merge": "^4.6.2" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.3.0 <1.8.0" + "@opentelemetry/api": ">=1.3.0 <1.9.0" } }, "node_modules/@opentelemetry/sdk-trace-base": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.21.0.tgz", - "integrity": "sha512-yrElGX5Fv0umzp8Nxpta/XqU71+jCAyaLk34GmBzNcrW43nqbrqvdPs4gj4MVy/HcTjr6hifCDCYA3rMkajxxA==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.22.0.tgz", + "integrity": "sha512-pfTuSIpCKONC6vkTpv6VmACxD+P1woZf4q0K46nSUvXFvOFqjBYKFaAMkKD3M1mlKUUh0Oajwj35qNjMl80m1Q==", "dependencies": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/resources": "1.21.0", - "@opentelemetry/semantic-conventions": "1.21.0" + "@opentelemetry/core": "1.22.0", + "@opentelemetry/resources": "1.22.0", + "@opentelemetry/semantic-conventions": "1.22.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.8.0" + "@opentelemetry/api": ">=1.0.0 <1.9.0" } }, "node_modules/@opentelemetry/sdk-trace-web": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.21.0.tgz", - "integrity": "sha512-MxkmY/UNXkDiZj7JUu5T7wWt8Ai4NJEwSjGoQQ9YLvgLUIivvaIo9Mne+Q+KLOUG2v/uhivz3qzxbCODVa0c1A==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.22.0.tgz", + "integrity": "sha512-id5bUhWYg475xbm4hjwWA4PnWM4duNK1EyFRkZxa3BZNuCITwiKCLvDkVhlE9RK2kvuDOPmcRxgSbU1apF9/1w==", "dependencies": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/sdk-trace-base": "1.21.0", - "@opentelemetry/semantic-conventions": "1.21.0" + "@opentelemetry/core": "1.22.0", + "@opentelemetry/sdk-trace-base": "1.22.0", + "@opentelemetry/semantic-conventions": "1.22.0" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.8.0" + "@opentelemetry/api": ">=1.0.0 <1.9.0" } }, "node_modules/@opentelemetry/semantic-conventions": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.21.0.tgz", - "integrity": "sha512-lkC8kZYntxVKr7b8xmjCVUgE0a8xgDakPyDo9uSWavXPyYqLgYYGdEd2j8NxihRyb6UwpX3G/hFUF4/9q2V+/g==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.22.0.tgz", + "integrity": "sha512-CAOgFOKLybd02uj/GhCdEeeBjOS0yeoDeo/CA7ASBSmenpZHAKGB3iDm/rv3BQLcabb/OprDEsSQ1y0P8A7Siw==", "engines": { "node": ">=14" } @@ -16977,9 +16978,9 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "~7.22.6", - "@opentelemetry/api": "^1.6.0", - "@opentelemetry/core": "^1.17.1", - "@opentelemetry/resources": "^1.17.1", + "@opentelemetry/api": "^1.8.0", + "@opentelemetry/core": "^1.22.0", + "@opentelemetry/resources": "^1.22.0", "fflate": "^0.8.0", "protobufjs": "~7.2.4", "rrweb": "^1.1.3", @@ -17004,6 +17005,14 @@ "@splunk/otel-web": "^0.17.0-beta.0" } }, + "packages/session-recorder/node_modules/@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", + "engines": { + "node": ">=8.0.0" + } + }, "packages/session-recorder/node_modules/type-fest": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.0.0.tgz", @@ -17021,18 +17030,18 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.22.6", - "@opentelemetry/api": "^1.7.0", - "@opentelemetry/core": "^1.21.0", - "@opentelemetry/exporter-trace-otlp-http": "^0.48.0", - "@opentelemetry/exporter-zipkin": "^1.21.0", - "@opentelemetry/instrumentation": "^0.48.0", - "@opentelemetry/instrumentation-document-load": "^0.35.0", - "@opentelemetry/instrumentation-fetch": "^0.48.0", - "@opentelemetry/instrumentation-xml-http-request": "^0.48.0", - "@opentelemetry/resources": "^1.21.0", - "@opentelemetry/sdk-trace-base": "^1.21.0", - "@opentelemetry/sdk-trace-web": "^1.21.0", - "@opentelemetry/semantic-conventions": "^1.21.0", + "@opentelemetry/api": "^1.8.0", + "@opentelemetry/core": "^1.22.0", + "@opentelemetry/exporter-trace-otlp-http": "^0.49.1", + "@opentelemetry/exporter-zipkin": "^1.22.0", + "@opentelemetry/instrumentation": "^0.49.1", + "@opentelemetry/instrumentation-document-load": "^0.36.0", + "@opentelemetry/instrumentation-fetch": "^0.49.1", + "@opentelemetry/instrumentation-xml-http-request": "^0.49.1", + "@opentelemetry/resources": "^1.22.0", + "@opentelemetry/sdk-trace-base": "^1.22.0", + "@opentelemetry/sdk-trace-web": "^1.22.0", + "@opentelemetry/semantic-conventions": "^1.22.0", "shimmer": "^1.2.1", "web-vitals": "^3.5.2" }, @@ -17088,6 +17097,14 @@ "ts-node": "^10.9.1", "ws": "^8.13.0" } + }, + "packages/web/node_modules/@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", + "engines": { + "node": ">=8.0.0" + } } }, "dependencies": { @@ -19668,49 +19685,50 @@ "integrity": "sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==" }, "@opentelemetry/api-logs": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.48.0.tgz", - "integrity": "sha512-1/aMiU4Eqo3Zzpfwu51uXssp5pzvHFObk8S9pKAiXb1ne8pvg1qxBQitYL1XUiAMEXFzgjaidYG2V6624DRhhw==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.49.1.tgz", + "integrity": "sha512-kaNl/T7WzyMUQHQlVq7q0oV4Kev6+0xFwqzofryC66jgGMacd0QH5TwfpbUwSTby+SdAdprAe5UKMvBw4tKS5Q==", "requires": { "@opentelemetry/api": "^1.0.0" } }, "@opentelemetry/core": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.21.0.tgz", - "integrity": "sha512-KP+OIweb3wYoP7qTYL/j5IpOlu52uxBv5M4+QhSmmUfLyTgu1OIS71msK3chFo1D6Y61BIH3wMiMYRCxJCQctA==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.22.0.tgz", + "integrity": "sha512-0VoAlT6x+Xzik1v9goJ3pZ2ppi6+xd3aUfg4brfrLkDBHRIVjMP0eBHrKrhB+NKcDyMAg8fAbGL3Npg/F6AwWA==", "requires": { - "@opentelemetry/semantic-conventions": "1.21.0" + "@opentelemetry/semantic-conventions": "1.22.0" } }, "@opentelemetry/exporter-trace-otlp-http": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.48.0.tgz", - "integrity": "sha512-QEZKbfWqXrbKVpr2PHd4KyKI0XVOhUYC+p2RPV8s+2K5QzZBE3+F9WlxxrXDfkrvGmpQAZytBoHQQYA3AGOtpw==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.49.1.tgz", + "integrity": "sha512-KOLtZfZvIrpGZLVvblKsiVQT7gQUZNKcUUH24Zz6Xbi7LJb9Vt6xtUZFYdR5IIjvt47PIqBKDWUQlU0o1wAsRw==", "requires": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/otlp-exporter-base": "0.48.0", - "@opentelemetry/otlp-transformer": "0.48.0", - "@opentelemetry/resources": "1.21.0", - "@opentelemetry/sdk-trace-base": "1.21.0" + "@opentelemetry/core": "1.22.0", + "@opentelemetry/otlp-exporter-base": "0.49.1", + "@opentelemetry/otlp-transformer": "0.49.1", + "@opentelemetry/resources": "1.22.0", + "@opentelemetry/sdk-trace-base": "1.22.0" } }, "@opentelemetry/exporter-zipkin": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-1.21.0.tgz", - "integrity": "sha512-J0ejrOx52s1PqvjNalIHvY/4v9ZxR2r7XS7WZbwK3qpVYZlGVq5V1+iCNweqsKnb/miUt/4TFvJBc9f5Q/kGcA==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-1.22.0.tgz", + "integrity": "sha512-XcFs6rGvcTz0qW5uY7JZDYD0yNEXdekXAb6sFtnZgY/cHY6BQ09HMzOjv9SX+iaXplRDcHr1Gta7VQKM1XXM6g==", "requires": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/resources": "1.21.0", - "@opentelemetry/sdk-trace-base": "1.21.0", - "@opentelemetry/semantic-conventions": "1.21.0" + "@opentelemetry/core": "1.22.0", + "@opentelemetry/resources": "1.22.0", + "@opentelemetry/sdk-trace-base": "1.22.0", + "@opentelemetry/semantic-conventions": "1.22.0" } }, "@opentelemetry/instrumentation": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.48.0.tgz", - "integrity": "sha512-sjtZQB5PStIdCw5ovVTDGwnmQC+GGYArJNgIcydrDSqUTdYBnMrN9P4pwQZgS3vTGIp+TU1L8vMXGe51NVmIKQ==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.49.1.tgz", + "integrity": "sha512-0DLtWtaIppuNNRRllSD4bjU8ZIiLp1cDXvJEbp752/Zf+y3gaLNaoGRGIlX4UHhcsrmtL+P2qxi3Hodi8VuKiQ==", "requires": { + "@opentelemetry/api-logs": "0.49.1", "@types/shimmer": "^1.0.2", "import-in-the-middle": "1.7.1", "require-in-the-middle": "^7.1.1", @@ -19719,112 +19737,112 @@ } }, "@opentelemetry/instrumentation-document-load": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-document-load/-/instrumentation-document-load-0.35.0.tgz", - "integrity": "sha512-U3zQBjbAF0rm7GT7YJ8DPqgiCdBoshmld4c1pZe3tAGAMa5QPIjonIfSMSvJ2XMh6Nvi+8Rfe3XFCe0cuWIjsQ==", + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-document-load/-/instrumentation-document-load-0.36.0.tgz", + "integrity": "sha512-LBz4Lr5XMlo3F0SVeNS4H8wn6GC0EQs7Up258AMROaxq9gZiYM1ZyecbvNz3wPvP0d8wP1D8qcO45pWBHK/4tw==", "requires": { "@opentelemetry/core": "^1.8.0", - "@opentelemetry/instrumentation": "^0.48.0", + "@opentelemetry/instrumentation": "^0.49.1", "@opentelemetry/sdk-trace-base": "^1.0.0", "@opentelemetry/sdk-trace-web": "^1.15.0", "@opentelemetry/semantic-conventions": "^1.0.0" } }, "@opentelemetry/instrumentation-fetch": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fetch/-/instrumentation-fetch-0.48.0.tgz", - "integrity": "sha512-y4Zw9VeUUMaowg3aXYZXcaUJQ7IKfpR6sjClrAQOJwWG8LYFpM6NIRSoAeJv/ShfxWWCPWC0P4zgXcKRqpURFQ==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fetch/-/instrumentation-fetch-0.49.1.tgz", + "integrity": "sha512-hizhULZXlq02y8YC0vPQ4WtUWiXcwxPdEqHBy8p75jzF9rAuP/ldrVr0Oxvz5Xr9qQcdEOFLvEl0ZxbVL76WKw==", "requires": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/instrumentation": "0.48.0", - "@opentelemetry/sdk-trace-web": "1.21.0", - "@opentelemetry/semantic-conventions": "1.21.0" + "@opentelemetry/core": "1.22.0", + "@opentelemetry/instrumentation": "0.49.1", + "@opentelemetry/sdk-trace-web": "1.22.0", + "@opentelemetry/semantic-conventions": "1.22.0" } }, "@opentelemetry/instrumentation-xml-http-request": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-xml-http-request/-/instrumentation-xml-http-request-0.48.0.tgz", - "integrity": "sha512-YJ9d1sR28hcEVtP4/tHtPX5Hhu0w2LsAMp3M+75YGTHkkunsN8PwcY/1FcSHUP9xwy7Z2myQvT7fTpL3g4tn4A==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-xml-http-request/-/instrumentation-xml-http-request-0.49.1.tgz", + "integrity": "sha512-gCPd2o1geRXc1urJoLxWRnMKAF6Akbwlp1nfe+xg2akSUenlt4wopmq1gEIrJva4bXLsNSModVLrEVCTt5/fDA==", "requires": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/instrumentation": "0.48.0", - "@opentelemetry/sdk-trace-web": "1.21.0", - "@opentelemetry/semantic-conventions": "1.21.0" + "@opentelemetry/core": "1.22.0", + "@opentelemetry/instrumentation": "0.49.1", + "@opentelemetry/sdk-trace-web": "1.22.0", + "@opentelemetry/semantic-conventions": "1.22.0" } }, "@opentelemetry/otlp-exporter-base": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.48.0.tgz", - "integrity": "sha512-T4LJND+Ugl87GUONoyoQzuV9qCn4BFIPOnCH1biYqdGhc2JahjuLqVD9aefwLzGBW638iLAo88Lh68h2F1FLiA==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.49.1.tgz", + "integrity": "sha512-z6sHliPqDgJU45kQatAettY9/eVF58qVPaTuejw9YWfSRqid9pXPYeegDCSdyS47KAUgAtm+nC28K3pfF27HWg==", "requires": { - "@opentelemetry/core": "1.21.0" + "@opentelemetry/core": "1.22.0" } }, "@opentelemetry/otlp-transformer": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.48.0.tgz", - "integrity": "sha512-yuoS4cUumaTK/hhxW3JUy3wl2U4keMo01cFDrUOmjloAdSSXvv1zyQ920IIH4lymp5Xd21Dj2/jq2LOro56TJg==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.49.1.tgz", + "integrity": "sha512-Z+koA4wp9L9e3jkFacyXTGphSWTbOKjwwXMpb0CxNb0kjTHGUxhYRN8GnkLFsFo5NbZPjP07hwAqeEG/uCratQ==", "requires": { - "@opentelemetry/api-logs": "0.48.0", - "@opentelemetry/core": "1.21.0", - "@opentelemetry/resources": "1.21.0", - "@opentelemetry/sdk-logs": "0.48.0", - "@opentelemetry/sdk-metrics": "1.21.0", - "@opentelemetry/sdk-trace-base": "1.21.0" + "@opentelemetry/api-logs": "0.49.1", + "@opentelemetry/core": "1.22.0", + "@opentelemetry/resources": "1.22.0", + "@opentelemetry/sdk-logs": "0.49.1", + "@opentelemetry/sdk-metrics": "1.22.0", + "@opentelemetry/sdk-trace-base": "1.22.0" } }, "@opentelemetry/resources": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.21.0.tgz", - "integrity": "sha512-1Z86FUxPKL6zWVy2LdhueEGl9AHDJcx+bvHStxomruz6Whd02mE3lNUMjVJ+FGRoktx/xYQcxccYb03DiUP6Yw==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.22.0.tgz", + "integrity": "sha512-+vNeIFPH2hfcNL0AJk/ykJXoUCtR1YaDUZM+p3wZNU4Hq98gzq+7b43xbkXjadD9VhWIUQqEwXyY64q6msPj6A==", "requires": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/semantic-conventions": "1.21.0" + "@opentelemetry/core": "1.22.0", + "@opentelemetry/semantic-conventions": "1.22.0" } }, "@opentelemetry/sdk-logs": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.48.0.tgz", - "integrity": "sha512-lRcA5/qkSJuSh4ItWCddhdn/nNbVvnzM+cm9Fg1xpZUeTeozjJDBcHnmeKoOaWRnrGYBdz6UTY6bynZR9aBeAA==", + "version": "0.49.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.49.1.tgz", + "integrity": "sha512-gCzYWsJE0h+3cuh3/cK+9UwlVFyHvj3PReIOCDOmdeXOp90ZjKRoDOJBc3mvk1LL6wyl1RWIivR8Rg9OToyesw==", "requires": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/resources": "1.21.0" + "@opentelemetry/core": "1.22.0", + "@opentelemetry/resources": "1.22.0" } }, "@opentelemetry/sdk-metrics": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.21.0.tgz", - "integrity": "sha512-on1jTzIHc5DyWhRP+xpf+zrgrREXcHBH4EDAfaB5mIG7TWpKxNXooQ1JCylaPsswZUv4wGnVTinr4HrBdGARAQ==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.22.0.tgz", + "integrity": "sha512-k6iIx6H3TZ+BVMr2z8M16ri2OxWaljg5h8ihGJxi/KQWcjign6FEaEzuigXt5bK9wVEhqAcWLCfarSftaNWkkg==", "requires": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/resources": "1.21.0", + "@opentelemetry/core": "1.22.0", + "@opentelemetry/resources": "1.22.0", "lodash.merge": "^4.6.2" } }, "@opentelemetry/sdk-trace-base": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.21.0.tgz", - "integrity": "sha512-yrElGX5Fv0umzp8Nxpta/XqU71+jCAyaLk34GmBzNcrW43nqbrqvdPs4gj4MVy/HcTjr6hifCDCYA3rMkajxxA==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.22.0.tgz", + "integrity": "sha512-pfTuSIpCKONC6vkTpv6VmACxD+P1woZf4q0K46nSUvXFvOFqjBYKFaAMkKD3M1mlKUUh0Oajwj35qNjMl80m1Q==", "requires": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/resources": "1.21.0", - "@opentelemetry/semantic-conventions": "1.21.0" + "@opentelemetry/core": "1.22.0", + "@opentelemetry/resources": "1.22.0", + "@opentelemetry/semantic-conventions": "1.22.0" } }, "@opentelemetry/sdk-trace-web": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.21.0.tgz", - "integrity": "sha512-MxkmY/UNXkDiZj7JUu5T7wWt8Ai4NJEwSjGoQQ9YLvgLUIivvaIo9Mne+Q+KLOUG2v/uhivz3qzxbCODVa0c1A==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-web/-/sdk-trace-web-1.22.0.tgz", + "integrity": "sha512-id5bUhWYg475xbm4hjwWA4PnWM4duNK1EyFRkZxa3BZNuCITwiKCLvDkVhlE9RK2kvuDOPmcRxgSbU1apF9/1w==", "requires": { - "@opentelemetry/core": "1.21.0", - "@opentelemetry/sdk-trace-base": "1.21.0", - "@opentelemetry/semantic-conventions": "1.21.0" + "@opentelemetry/core": "1.22.0", + "@opentelemetry/sdk-trace-base": "1.22.0", + "@opentelemetry/semantic-conventions": "1.22.0" } }, "@opentelemetry/semantic-conventions": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.21.0.tgz", - "integrity": "sha512-lkC8kZYntxVKr7b8xmjCVUgE0a8xgDakPyDo9uSWavXPyYqLgYYGdEd2j8NxihRyb6UwpX3G/hFUF4/9q2V+/g==" + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.22.0.tgz", + "integrity": "sha512-CAOgFOKLybd02uj/GhCdEeeBjOS0yeoDeo/CA7ASBSmenpZHAKGB3iDm/rv3BQLcabb/OprDEsSQ1y0P8A7Siw==" }, "@pkgjs/parseargs": { "version": "0.11.0", @@ -20709,18 +20727,18 @@ "@babel/preset-env": "^7.22.9", "@babel/runtime": "^7.22.6", "@babel/runtime-corejs3": "^7.22.6", - "@opentelemetry/api": "^1.7.0", - "@opentelemetry/core": "^1.21.0", - "@opentelemetry/exporter-trace-otlp-http": "^0.48.0", - "@opentelemetry/exporter-zipkin": "^1.21.0", - "@opentelemetry/instrumentation": "^0.48.0", - "@opentelemetry/instrumentation-document-load": "^0.35.0", - "@opentelemetry/instrumentation-fetch": "^0.48.0", - "@opentelemetry/instrumentation-xml-http-request": "^0.48.0", - "@opentelemetry/resources": "^1.21.0", - "@opentelemetry/sdk-trace-base": "^1.21.0", - "@opentelemetry/sdk-trace-web": "^1.21.0", - "@opentelemetry/semantic-conventions": "^1.21.0", + "@opentelemetry/api": "^1.8.0", + "@opentelemetry/core": "^1.22.0", + "@opentelemetry/exporter-trace-otlp-http": "^0.49.1", + "@opentelemetry/exporter-zipkin": "^1.22.0", + "@opentelemetry/instrumentation": "^0.49.1", + "@opentelemetry/instrumentation-document-load": "^0.36.0", + "@opentelemetry/instrumentation-fetch": "^0.49.1", + "@opentelemetry/instrumentation-xml-http-request": "^0.49.1", + "@opentelemetry/resources": "^1.22.0", + "@opentelemetry/sdk-trace-base": "^1.22.0", + "@opentelemetry/sdk-trace-web": "^1.22.0", + "@opentelemetry/semantic-conventions": "^1.22.0", "@rollup/plugin-babel": "^6.0.3", "@rollup/plugin-commonjs": "^25.0.3", "@rollup/plugin-json": "^6.0.0", @@ -20770,6 +20788,13 @@ "ts-node": "^10.9.1", "web-vitals": "^3.5.2", "ws": "^8.13.0" + }, + "dependencies": { + "@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==" + } } }, "@splunk/otel-web-session-recorder": { @@ -20779,9 +20804,9 @@ "@babel/preset-env": "^7.22.9", "@babel/runtime": "~7.22.6", "@babel/runtime-corejs3": "^7.22.6", - "@opentelemetry/api": "^1.6.0", - "@opentelemetry/core": "^1.17.1", - "@opentelemetry/resources": "^1.17.1", + "@opentelemetry/api": "^1.8.0", + "@opentelemetry/core": "^1.22.0", + "@opentelemetry/resources": "^1.22.0", "@rollup/plugin-commonjs": "^25.0.3", "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-node-resolve": "^15.1.0", @@ -20798,6 +20823,11 @@ "type-fest": "^4.0.0" }, "dependencies": { + "@opentelemetry/api": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==" + }, "type-fest": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.0.0.tgz", diff --git a/packages/session-recorder/package.json b/packages/session-recorder/package.json index 53e5d20b..cb3536f6 100644 --- a/packages/session-recorder/package.json +++ b/packages/session-recorder/package.json @@ -32,9 +32,9 @@ ], "dependencies": { "@babel/runtime": "~7.22.6", - "@opentelemetry/api": "^1.6.0", - "@opentelemetry/core": "^1.17.1", - "@opentelemetry/resources": "^1.17.1", + "@opentelemetry/api": "^1.8.0", + "@opentelemetry/core": "^1.22.0", + "@opentelemetry/resources": "^1.22.0", "fflate": "^0.8.0", "protobufjs": "~7.2.4", "rrweb": "^1.1.3", diff --git a/packages/web/package.json b/packages/web/package.json index 2d00ca98..f4b60b8d 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -47,18 +47,18 @@ ], "dependencies": { "@babel/runtime": "^7.22.6", - "@opentelemetry/api": "^1.7.0", - "@opentelemetry/core": "^1.21.0", - "@opentelemetry/exporter-trace-otlp-http": "^0.48.0", - "@opentelemetry/exporter-zipkin": "^1.21.0", - "@opentelemetry/instrumentation": "^0.48.0", - "@opentelemetry/instrumentation-document-load": "^0.35.0", - "@opentelemetry/instrumentation-fetch": "^0.48.0", - "@opentelemetry/instrumentation-xml-http-request": "^0.48.0", - "@opentelemetry/resources": "^1.21.0", - "@opentelemetry/sdk-trace-base": "^1.21.0", - "@opentelemetry/sdk-trace-web": "^1.21.0", - "@opentelemetry/semantic-conventions": "^1.21.0", + "@opentelemetry/api": "^1.8.0", + "@opentelemetry/core": "^1.22.0", + "@opentelemetry/exporter-trace-otlp-http": "^0.49.1", + "@opentelemetry/exporter-zipkin": "^1.22.0", + "@opentelemetry/instrumentation": "^0.49.1", + "@opentelemetry/instrumentation-document-load": "^0.36.0", + "@opentelemetry/instrumentation-fetch": "^0.49.1", + "@opentelemetry/instrumentation-xml-http-request": "^0.49.1", + "@opentelemetry/resources": "^1.22.0", + "@opentelemetry/sdk-trace-base": "^1.22.0", + "@opentelemetry/sdk-trace-web": "^1.22.0", + "@opentelemetry/semantic-conventions": "^1.22.0", "shimmer": "^1.2.1", "web-vitals": "^3.5.2" }, From 06f7e567382604c329acf72460b16d14cc6e0a46 Mon Sep 17 00:00:00 2001 From: t2t2 Date: Tue, 12 Mar 2024 19:08:19 +0200 Subject: [PATCH 06/10] session.id on spans, change how session recorder gets session id --- package-lock.json | 40 +++---------------- .../session-recorder/src/OTLPLogExporter.ts | 5 +-- packages/session-recorder/src/index.ts | 29 ++++++++++---- packages/session-recorder/src/utils.ts | 36 +++++++++++++++++ .../web/src/SplunkSpanAttributesProcessor.ts | 2 + packages/web/src/index.ts | 16 +++----- packages/web/src/utils.ts | 36 +++++++++++++++++ 7 files changed, 109 insertions(+), 55 deletions(-) create mode 100644 packages/session-recorder/src/utils.ts diff --git a/package-lock.json b/package-lock.json index 59349db3..a8c3ad4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3392,9 +3392,9 @@ } }, "node_modules/@opentelemetry/api": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.7.0.tgz", - "integrity": "sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", "engines": { "node": ">=8.0.0" } @@ -17005,14 +17005,6 @@ "@splunk/otel-web": "^0.17.0-beta.0" } }, - "packages/session-recorder/node_modules/@opentelemetry/api": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", - "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", - "engines": { - "node": ">=8.0.0" - } - }, "packages/session-recorder/node_modules/type-fest": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.0.0.tgz", @@ -17097,14 +17089,6 @@ "ts-node": "^10.9.1", "ws": "^8.13.0" } - }, - "packages/web/node_modules/@opentelemetry/api": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", - "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==", - "engines": { - "node": ">=8.0.0" - } } }, "dependencies": { @@ -19680,9 +19664,9 @@ } }, "@opentelemetry/api": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.7.0.tgz", - "integrity": "sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==" + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", + "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==" }, "@opentelemetry/api-logs": { "version": "0.49.1", @@ -20788,13 +20772,6 @@ "ts-node": "^10.9.1", "web-vitals": "^3.5.2", "ws": "^8.13.0" - }, - "dependencies": { - "@opentelemetry/api": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", - "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==" - } } }, "@splunk/otel-web-session-recorder": { @@ -20823,11 +20800,6 @@ "type-fest": "^4.0.0" }, "dependencies": { - "@opentelemetry/api": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz", - "integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==" - }, "type-fest": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.0.0.tgz", diff --git a/packages/session-recorder/src/OTLPLogExporter.ts b/packages/session-recorder/src/OTLPLogExporter.ts index a10585e6..83b80aa9 100644 --- a/packages/session-recorder/src/OTLPLogExporter.ts +++ b/packages/session-recorder/src/OTLPLogExporter.ts @@ -14,7 +14,6 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { Resource } from '@opentelemetry/resources'; import { gzipSync } from 'fflate'; import type { Root } from 'protobufjs'; import type { JsonArray, JsonObject, JsonValue } from 'type-fest'; @@ -26,7 +25,7 @@ import { VERSION } from './version.js'; interface OTLPLogExporterConfig { headers?: Record; beaconUrl: string; - resource: Resource; + getResourceAttributes: () => JsonObject; debug?: boolean; } @@ -98,7 +97,7 @@ export default class OTLPLogExporter { return { resourceLogs: [{ resource: { - attributes: convertToAnyValue(this.config.resource?.attributes || {}).kvlistValue.values, + attributes: convertToAnyValue(this.config.getResourceAttributes() || {}).kvlistValue!.values, }, scopeLogs: [{ scope: { name: 'splunk.rr-web', version: VERSION }, diff --git a/packages/session-recorder/src/index.ts b/packages/session-recorder/src/index.ts index 71d2b9c4..8b60879d 100644 --- a/packages/session-recorder/src/index.ts +++ b/packages/session-recorder/src/index.ts @@ -19,9 +19,10 @@ import { record } from 'rrweb'; import OTLPLogExporter from './OTLPLogExporter'; import { BatchLogProcessor, convert } from './BatchLogProcessor'; import { VERSION } from './version'; +import { getGlobal } from './utils'; import type { Resource } from '@opentelemetry/resources'; - +import type { SplunkOtelWebType } from '@splunk/otel-web'; interface BasicTracerProvider extends TracerProvider { readonly resource: Resource; @@ -110,16 +111,18 @@ const SplunkRumRecorder = { return; } + const SplunkRum = getGlobal('splunk.rum'); + let tracerProvider: BasicTracerProvider | ProxyTracerProvider = trace.getTracerProvider() as BasicTracerProvider; if (tracerProvider && 'getDelegate' in tracerProvider) { tracerProvider = (tracerProvider as unknown as ProxyTracerProvider).getDelegate() as BasicTracerProvider; } - if (!(tracerProvider?.resource)) { - console.error('Splunk OTEL Web must be inited before recorder.'); + if (!SplunkRum || !SplunkRum.resource) { + console.error('Splunk OTEL Web must be inited before session recorder.'); return; } - const resource = tracerProvider.resource; + const resource = SplunkRum.resource; migrateConfig(config); @@ -156,10 +159,20 @@ const SplunkRumRecorder = { exportUrl += `?auth=${rumAccessToken}`; } - const exporter = new OTLPLogExporter({ beaconUrl: exportUrl, debug, headers, resource }); + const exporter = new OTLPLogExporter({ + beaconUrl: exportUrl, + debug, + headers, + getResourceAttributes() { + return { + ...resource.attributes, + 'splunk.rumSessionId': SplunkRum.getSessionId()! + }; + } + }); const processor = new BatchLogProcessor(exporter, {}); - lastKnownSession = resource.attributes['splunk.rumSessionId'] as string; + lastKnownSession = SplunkRum.getSessionId() as string; sessionStartTime = Date.now(); inited = record({ @@ -174,11 +187,11 @@ const SplunkRumRecorder = { // Safeguards from our ingest getting DDOSed: // 1. A session can send up to 4 hours of data // 2. Recording resumes on session change if it isn't a background tab (session regenerated in an another tab) - if (resource.attributes['splunk.rumSessionId'] !== lastKnownSession) { + if (SplunkRum.getSessionId() !== lastKnownSession) { if (document.hidden) { return; } - lastKnownSession = resource.attributes['splunk.rumSessionId'] as string; + lastKnownSession = SplunkRum.getSessionId() as string; sessionStartTime = Date.now(); // reset counters eventCounter = 1; diff --git a/packages/session-recorder/src/utils.ts b/packages/session-recorder/src/utils.ts new file mode 100644 index 00000000..7352b7ae --- /dev/null +++ b/packages/session-recorder/src/utils.ts @@ -0,0 +1,36 @@ +/* +Copyright 2024 Splunk Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { VERSION } from './version'; + +const GLOBAL_OPENTELEMETRY_API_KEY = Symbol.for('opentelemetry.js.api.1'); +/** + * otel-api's global function. This isn't exported by otel/api but would be + * super useful to access global components for experimental purposes... + * For us, it's included to access components accessed by other packages, + * eg. sharing session id manager with session recorder + */ +export function getGlobal( + type: string +): Type | undefined { + const globalSplunkRumVersion = globalThis[GLOBAL_OPENTELEMETRY_API_KEY]?.['splunk.rum.version']; + if (!globalSplunkRumVersion || globalSplunkRumVersion !== VERSION) { + console.warn(`SplunkSessionRecorder: Version mismatch with SplunkRum (RUM: ${globalSplunkRumVersion}, recorder: ${VERSION})`); + return undefined; // undefined for eslint + } + + return globalThis[GLOBAL_OPENTELEMETRY_API_KEY]?.[type]; +} diff --git a/packages/web/src/SplunkSpanAttributesProcessor.ts b/packages/web/src/SplunkSpanAttributesProcessor.ts index aacab75b..640f3a1f 100644 --- a/packages/web/src/SplunkSpanAttributesProcessor.ts +++ b/packages/web/src/SplunkSpanAttributesProcessor.ts @@ -16,6 +16,7 @@ limitations under the License. import { Attributes } from '@opentelemetry/api'; import { Span, SpanProcessor } from '@opentelemetry/sdk-trace-base'; +import { getRumSessionId } from './session.js'; export class SplunkSpanAttributesProcessor implements SpanProcessor { private readonly _globalAttributes: Attributes; @@ -45,6 +46,7 @@ export class SplunkSpanAttributesProcessor implements SpanProcessor { onStart(span: Span): void { span.setAttribute('location.href', location.href); span.setAttributes(this._globalAttributes); + span.setAttribute('splunk.rumSessionId', getRumSessionId()); } onEnd(): void { diff --git a/packages/web/src/index.ts b/packages/web/src/index.ts index 369af157..26153a2a 100644 --- a/packages/web/src/index.ts +++ b/packages/web/src/index.ts @@ -41,7 +41,7 @@ import { import { SplunkExporterConfig } from './exporters/common'; import { SplunkZipkinExporter } from './exporters/zipkin'; import { ERROR_INSTRUMENTATION_NAME, SplunkErrorInstrumentation } from './SplunkErrorInstrumentation'; -import { generateId, getPluginConfig } from './utils'; +import { generateId, getPluginConfig, registerGlobal } from './utils'; import { getRumSessionId, initSessionTracking, SessionIdType } from './session'; import { SplunkWebSocketInstrumentation } from './SplunkWebSocketInstrumentation'; import { initWebVitals } from './webvitals'; @@ -272,6 +272,8 @@ function buildExporter(options: SplunkOtelWebConfigInternal) { } export interface SplunkOtelWebType extends SplunkOtelWebEventTarget { + readonly resource?: Resource; + deinit: () => void; error: (...args: Array) => void; @@ -423,18 +425,11 @@ export const SplunkRum: SplunkOtelWebType = { if (syntheticsRunId) { resourceAttrs[SYNTHETICS_RUN_ID_ATTRIBUTE] = syntheticsRunId; } + this.resource = new Resource(resourceAttrs); const provider = new SplunkWebTracerProvider({ ...processedOptions.tracer, - resource: new Resource(resourceAttrs), - }); - - Object.defineProperty(provider.resource.attributes, 'splunk.rumSessionId', { - get() { - return getRumSessionId(); - }, - configurable: true, - enumerable: true, + resource: this.resource, }); const instrumentations = INSTRUMENTATIONS.map(({ Instrument, confKey, disable }) => { @@ -504,6 +499,7 @@ export const SplunkRum: SplunkOtelWebType = { } inited = true; + registerGlobal('splunk.rum', this); diag.info('SplunkRum.init() complete'); }, diff --git a/packages/web/src/utils.ts b/packages/web/src/utils.ts index 5d2eda31..bfea0b1c 100644 --- a/packages/web/src/utils.ts +++ b/packages/web/src/utils.ts @@ -14,7 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */ +import { diag } from '@opentelemetry/api'; import { wrap } from 'shimmer'; +import { VERSION } from './version'; export function generateId(bits: number): string { const xes = 'x'.repeat(bits/4); @@ -163,3 +165,37 @@ export function waitForGlobal(identifier: string, callback: (value: unknown) => } }; } + +const GLOBAL_OPENTELEMETRY_API_KEY = Symbol.for('opentelemetry.js.api.1'); +/** + * otel-api's global function. This isn't exported by otel/api but would be + * super useful to register global components for experimental purposes... + * For us, it's included to register components accessed by other packages, + * eg. sharing session id manager with session recorder + */ +export function registerGlobal( + type: string, + instance: unknown, + allowOverride = false +): boolean { + if (!globalThis[GLOBAL_OPENTELEMETRY_API_KEY]) { + diag.error('SplunkRum: Tried to access global before otel setup'); + return false; + } + const api = globalThis[GLOBAL_OPENTELEMETRY_API_KEY]; + + if (!api['splunk.rum.version']) { + api['splunk.rum.version'] = VERSION; + } + if (api['splunk.rum.version'] !== VERSION) { + diag.warn(`SplunkRum: Global: Multiple versions detected (${VERSION} already registered)`); + } + + if (!allowOverride && api[type]) { + diag.error(`SplunkRum: Attempted duplicate registration of otel API ${type}`); + return false; + } + + api[type] = instance; + return true; +} From 7b8f61cf44fb107a5e8f88dfce405a459c9debd2 Mon Sep 17 00:00:00 2001 From: t2t2 Date: Tue, 12 Mar 2024 19:09:53 +0200 Subject: [PATCH 07/10] fix weird past logic in rate-limit --- packages/web/src/exporters/rate-limit.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web/src/exporters/rate-limit.ts b/packages/web/src/exporters/rate-limit.ts index c57ba18a..50b9b417 100644 --- a/packages/web/src/exporters/rate-limit.ts +++ b/packages/web/src/exporters/rate-limit.ts @@ -44,7 +44,7 @@ export class RateLimitProcessor implements SpanProcessor { } const component = (span.attributes?.component ?? 'unknown').toString(); if (!this._spanCounts.has(component)) { - this._spanCounts.set(component, -1); + this._spanCounts.set(component, 0); } const counter = (this._spanCounts.get(component) || 0) + 1; this._spanCounts.set(component, counter); @@ -54,7 +54,7 @@ export class RateLimitProcessor implements SpanProcessor { this._parents.delete(spanId); return true; } - return counter < MAX_SPANS_PER_PERIOD_PER_COMPONENT; + return counter <= MAX_SPANS_PER_PERIOD_PER_COMPONENT; } onStart(span: Span, parentContext: Context): void { From fda57696ed8b5a5cf5d00f2c6ae88df6ac9e8943 Mon Sep 17 00:00:00 2001 From: t2t2 Date: Tue, 12 Mar 2024 19:14:28 +0200 Subject: [PATCH 08/10] force workspace scripts order --- package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 4db6c218..5c36c015 100644 --- a/package.json +++ b/package.json @@ -2,8 +2,10 @@ "name": "@splunk/otel-web-dev-root", "private": true, "version": "0.17.0-beta.1", + "--workspaces": "Hardcoded so npm runs workspaces commands in order", "workspaces": [ - "packages/*" + "packages/web", + "packages/session-recorder" ], "engines": { "--": "Versions required for development only (recent enough to use npm workspaces)", From 2f9c52641a8181aed046adc5ff9bd6aaea543479 Mon Sep 17 00:00:00 2001 From: t2t2 Date: Tue, 12 Mar 2024 19:25:18 +0200 Subject: [PATCH 09/10] update test --- packages/web/src/index.ts | 1 + packages/web/test/init.test.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/web/src/index.ts b/packages/web/src/index.ts index 26153a2a..253859a5 100644 --- a/packages/web/src/index.ts +++ b/packages/web/src/index.ts @@ -518,6 +518,7 @@ export const SplunkRum: SplunkOtelWebType = { delete this.provider; eventTarget = undefined; diag.disable(); + registerGlobal('splunk.rum', undefined, true); inited = false; }, diff --git a/packages/web/test/init.test.ts b/packages/web/test/init.test.ts index b89f46fc..372aaf94 100644 --- a/packages/web/test/init.test.ts +++ b/packages/web/test/init.test.ts @@ -201,11 +201,11 @@ describe('creating spans is possible', () => { assert.strictEqual(exposedSpan.attributes['environment'], 'my-env'); assert.strictEqual(exposedSpan.attributes['app.version'], '1.2-test.3'); assert.strictEqual(exposedSpan.attributes.customerType, 'GOLD'); + assert.ok(exposedSpan.attributes['splunk.rumSessionId'], 'Checking splunk.rumSessionId'); // Attributes set on resource that zipkin exporter merges to span tags assert.ok(exposedSpan.resource.attributes['telemetry.sdk.name'], 'Checking telemetry.sdk.name'); assert.ok(exposedSpan.resource.attributes['telemetry.sdk.language'], 'Checking telemetry.sdk.language'); assert.ok(exposedSpan.resource.attributes['telemetry.sdk.version'], 'Checking telemetry.sdk.version'); - assert.ok(exposedSpan.resource.attributes['splunk.rumSessionId'], 'Checking splunk.rumSessionId'); assert.ok(exposedSpan.resource.attributes['splunk.rumVersion'], 'Checking splunk.rumVersion'); assert.ok(exposedSpan.resource.attributes['splunk.scriptInstance'], 'Checking splunk.scriptInstance'); assert.strictEqual(exposedSpan.resource.attributes['app'], 'my-app'); From b7e1b16822f3e24d19690628190a78436c8695e2 Mon Sep 17 00:00:00 2001 From: t2t2 Date: Tue, 12 Mar 2024 19:34:36 +0200 Subject: [PATCH 10/10] mochaaaaaaaa --- packages/web/src/SplunkSpanAttributesProcessor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/src/SplunkSpanAttributesProcessor.ts b/packages/web/src/SplunkSpanAttributesProcessor.ts index 640f3a1f..f254f24a 100644 --- a/packages/web/src/SplunkSpanAttributesProcessor.ts +++ b/packages/web/src/SplunkSpanAttributesProcessor.ts @@ -16,7 +16,7 @@ limitations under the License. import { Attributes } from '@opentelemetry/api'; import { Span, SpanProcessor } from '@opentelemetry/sdk-trace-base'; -import { getRumSessionId } from './session.js'; +import { getRumSessionId } from './session'; export class SplunkSpanAttributesProcessor implements SpanProcessor { private readonly _globalAttributes: Attributes;