diff --git a/package-lock.json b/package-lock.json index e55c5c6e..7eb7faba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,10 +5,12 @@ "packages": { "": { "name": "worker-apollo-server", + "hasInstallScript": true, "dependencies": { "@cloudflare/workers-honeycomb-logger": "^2.3.3", "@envelop/core": "^5.0.0", "@envelop/immediate-introspection": "^2.0.0", + "@envelop/opentelemetry": "^6.3.1", "@envelop/rate-limiter": "^5.0.0", "@faker-js/faker": "^8.0.2", "@graphql-authz/envelop-plugin": "^1.0.4", @@ -16,10 +18,12 @@ "@libsql/client": "^0.3.5", "@microlabs/otel-cf-workers": "^1.0.0-rc.40", "@neondatabase/serverless": "^0.4.26", + "@opentelemetry/api": "^1.9.0", "@pothos/core": "^3.30.0", "@pothos/plugin-authz": "^3.5.8", "@pothos/plugin-dataloader": "^3.19.0", "@pothos/plugin-tracing": "^0.5.8", + "@pothos/tracing-opentelemetry": "^1.1.0", "@sanity/client": "^6.7.0", "@tsndr/cloudflare-worker-jwt": "^2.5.3", "@types/react": "^18.2.22", @@ -36,6 +40,7 @@ "graphql-yoga": "^5.6.1", "hono": "^3.9.0", "mercadopago": "^2.0.9", + "npm-force-resolutions": "^0.0.10", "p-map": "^6.0.0", "pino": "^9.2.0", "pino-pretty": "^11.2.1", @@ -2168,6 +2173,41 @@ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" } }, + "node_modules/@envelop/opentelemetry": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/@envelop/opentelemetry/-/opentelemetry-6.3.1.tgz", + "integrity": "sha512-paauYvPtk+XgGDmNKEM31LAq+BkF2QRszC/Th1NE9EEsCG3ivDmMYJ5doyw32Rd6RTiAKYFlnoE5zbIB+D85KA==", + "dependencies": { + "@envelop/on-resolve": "^4.1.0", + "@opentelemetry/api": "^1.8.0", + "@opentelemetry/sdk-trace-base": "^1.11.0", + "tslib": "^2.5.0" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@envelop/core": "^5.0.1", + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@envelop/opentelemetry/node_modules/@envelop/on-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@envelop/on-resolve/-/on-resolve-4.1.0.tgz", + "integrity": "sha512-2AXxf8jbBIepBUiY0KQtyCO6gnT7LKBEYdaARZBJ7ujy1+iQHQPORKvAwl51kIdD6v5x38eldZnm7A19jFimOg==", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@envelop/core": "^5.0.0", + "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" + } + }, + "node_modules/@envelop/opentelemetry/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, "node_modules/@envelop/rate-limiter": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@envelop/rate-limiter/-/rate-limiter-5.0.1.tgz", @@ -3502,13 +3542,13 @@ } }, "node_modules/@graphql-codegen/typescript/node_modules/@graphql-tools/relay-operation-optimizer": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-7.0.0.tgz", - "integrity": "sha512-UNlJi5y3JylhVWU4MBpL0Hun4Q7IoJwv9xYtmAz+CgRa066szzY7dcuPfxrA7cIGgG/Q6TVsKsYaiF4OHPs1Fw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@graphql-tools/relay-operation-optimizer/-/relay-operation-optimizer-7.0.1.tgz", + "integrity": "sha512-y0ZrQ/iyqWZlsS/xrJfSir3TbVYJTYmMOu4TaSz6F4FRDTQ3ie43BlKkhf04rC28pnUOS4BO9pDcAo1D30l5+A==", "dev": true, "dependencies": { "@ardatan/relay-compiler": "12.0.0", - "@graphql-tools/utils": "^10.0.0", + "@graphql-tools/utils": "^10.0.13", "tslib": "^2.4.0" }, "engines": { @@ -3876,16 +3916,6 @@ "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@graphql-eslint/eslint-plugin/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, "node_modules/@graphql-eslint/eslint-plugin/node_modules/cosmiconfig": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.0.0.tgz", @@ -3953,18 +3983,6 @@ "jiti": "bin/jiti.js" } }, - "node_modules/@graphql-eslint/eslint-plugin/node_modules/minimatch": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.3.tgz", - "integrity": "sha512-lIUdtK5hdofgCTu3aT0sOaHsYR37viUuIc0rwnnDXImbwFRcumyLMeZaM0t0I/fgxS6s6JMfu0rLD1Wz9pv1ng==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@graphql-eslint/eslint-plugin/node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", @@ -4033,9 +4051,9 @@ } }, "node_modules/@graphql-tools/apollo-engine-loader/node_modules/@whatwg-node/node-fetch": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.4.18.tgz", - "integrity": "sha512-zdey6buMKCqDVDq+tMqcjopO75Fb6iLqWo+g6cWwN5kiwctEHtVcbws2lJUFhCbo+TLZeH6bMDRUXEo5bkPtcQ==", + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.4.19.tgz", + "integrity": "sha512-AW7/m2AuweAoSXmESrYQr/KBafueScNbn2iNO0u6xFr2JZdPmYsSm5yvAXYk6yDLv+eDmSSKrf7JnFZ0CsJIdA==", "dev": true, "dependencies": { "@whatwg-node/events": "^0.1.0", @@ -4213,9 +4231,9 @@ } }, "node_modules/@graphql-tools/executor-http/node_modules/@whatwg-node/node-fetch": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.4.18.tgz", - "integrity": "sha512-zdey6buMKCqDVDq+tMqcjopO75Fb6iLqWo+g6cWwN5kiwctEHtVcbws2lJUFhCbo+TLZeH6bMDRUXEo5bkPtcQ==", + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.4.19.tgz", + "integrity": "sha512-AW7/m2AuweAoSXmESrYQr/KBafueScNbn2iNO0u6xFr2JZdPmYsSm5yvAXYk6yDLv+eDmSSKrf7JnFZ0CsJIdA==", "dependencies": { "@whatwg-node/events": "^0.1.0", "busboy": "^1.6.0", @@ -4649,11 +4667,14 @@ } }, "node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/events": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", - "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.2.tgz", + "integrity": "sha512-ApcWxkrs1WmEMS2CaLLFUEem/49erT3sxIVjpzU5f6zmVcnijtDSrhoK2zVobOIikZJdH63jdAXOrvjf6eOUNQ==", + "dependencies": { + "tslib": "^2.6.3" + }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@graphql-tools/url-loader/node_modules/@whatwg-node/fetch": { @@ -4683,6 +4704,11 @@ "node": ">=16.0.0" } }, + "node_modules/@graphql-tools/url-loader/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, "node_modules/@graphql-tools/url-loader/node_modules/urlpattern-polyfill": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz", @@ -5169,6 +5195,14 @@ "@opentelemetry/semantic-conventions": "^1.17.1" } }, + "node_modules/@microlabs/otel-cf-workers/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==", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/@neon-rs/load": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/@neon-rs/load/-/load-0.0.4.tgz", @@ -5569,9 +5603,9 @@ "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==" }, "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.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "engines": { "node": ">=8.0.0" } @@ -6326,6 +6360,18 @@ "graphql": ">=15.1.0" } }, + "node_modules/@pothos/tracing-opentelemetry": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pothos/tracing-opentelemetry/-/tracing-opentelemetry-1.1.0.tgz", + "integrity": "sha512-jorRoUGMQVDlL9OAnWFKoY3kqkjIea7+EiXkGxaBDeNvQsfYVWiRkizcI8wAjwuzoNtGV+uUbFGSw1EKZYVXvA==", + "peerDependencies": { + "@opentelemetry/api": "*", + "@opentelemetry/semantic-conventions": "*", + "@pothos/core": "*", + "@pothos/plugin-tracing": "*", + "graphql": ">=16.6.0" + } + }, "node_modules/@radix-ui/colors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/colors/-/colors-1.0.1.tgz", @@ -9251,11 +9297,14 @@ } }, "node_modules/@whatwg-node/server/node_modules/@whatwg-node/events": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", - "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.2.tgz", + "integrity": "sha512-ApcWxkrs1WmEMS2CaLLFUEem/49erT3sxIVjpzU5f6zmVcnijtDSrhoK2zVobOIikZJdH63jdAXOrvjf6eOUNQ==", + "dependencies": { + "tslib": "^2.6.3" + }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/@whatwg-node/server/node_modules/@whatwg-node/fetch": { @@ -9285,6 +9334,11 @@ "node": ">=16.0.0" } }, + "node_modules/@whatwg-node/server/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" + }, "node_modules/@whatwg-node/server/node_modules/urlpattern-polyfill": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", @@ -10182,8 +10236,7 @@ "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "node_modules/busboy": { "version": "1.6.0", @@ -13966,26 +14019,6 @@ } } }, - "node_modules/graphql-config/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/graphql-config/node_modules/minimatch": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.3.tgz", - "integrity": "sha512-lIUdtK5hdofgCTu3aT0sOaHsYR37viUuIc0rwnnDXImbwFRcumyLMeZaM0t0I/fgxS6s6JMfu0rLD1Wz9pv1ng==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/graphql-depth-limit": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/graphql-depth-limit/-/graphql-depth-limit-1.1.0.tgz", @@ -14139,14 +14172,6 @@ "graphql": "^15.2.0 || ^16.0.0" } }, - "node_modules/graphql-yoga/node_modules/@whatwg-node/events": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@whatwg-node/events/-/events-0.1.1.tgz", - "integrity": "sha512-AyQEn5hIPV7Ze+xFoXVU3QTHXVbWPrzaOkxtENMPMuNL6VVHrp4hHfDt9nrQpjO7BgvuM95dMtkycX5M/DZR3w==", - "engines": { - "node": ">=16.0.0" - } - }, "node_modules/graphql-yoga/node_modules/@whatwg-node/fetch": { "version": "0.9.17", "resolved": "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.9.17.tgz", @@ -14160,18 +14185,17 @@ } }, "node_modules/graphql-yoga/node_modules/@whatwg-node/node-fetch": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.10.tgz", - "integrity": "sha512-KIAHepie/T1PRkUfze4t+bPlyvpxlWiXTPtcGlbIZ0vWkBJMdRmCg4ZrJ2y4XaO1eTPo1HlWYUuj1WvoIpumqg==", + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/@whatwg-node/node-fetch/-/node-fetch-0.5.20.tgz", + "integrity": "sha512-DFLsOG//CrDdIO0x7Q7Ompxj3TZhB4iMDeXpQKY4toSbIbzsKmbwyOkzXMwvV1syxvAtPoHBzyGGtDrPV424FA==", "dependencies": { "@kamilkisiela/fast-url-parser": "^1.1.4", - "@whatwg-node/events": "^0.1.0", "busboy": "^1.6.0", "fast-querystring": "^1.1.1", - "tslib": "^2.3.1" + "tslib": "^2.6.3" }, "engines": { - "node": ">=16.0.0" + "node": ">=18.0.0" } }, "node_modules/graphql-yoga/node_modules/lru-cache": { @@ -14183,9 +14207,9 @@ } }, "node_modules/graphql-yoga/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" }, "node_modules/graphql-yoga/node_modules/urlpattern-polyfill": { "version": "10.0.0", @@ -15319,6 +15343,11 @@ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, + "node_modules/json-format": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-format/-/json-format-1.0.1.tgz", + "integrity": "sha512-MoKIg/lBeQALqjYnqEanikfo3zBKRwclpXJexdF0FUniYAAN2ypEIXBEtpQb+9BkLFtDK1fyTLAsnGlyGfLGxw==" + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -15948,6 +15977,26 @@ } } }, + "node_modules/minimatch": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.3.tgz", + "integrity": "sha512-lIUdtK5hdofgCTu3aT0sOaHsYR37viUuIc0rwnnDXImbwFRcumyLMeZaM0t0I/fgxS6s6JMfu0rLD1Wz9pv1ng==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/minimatch/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", @@ -16268,6 +16317,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/npm-force-resolutions": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/npm-force-resolutions/-/npm-force-resolutions-0.0.10.tgz", + "integrity": "sha512-Jscex+xIU6tw3VsyrwxM1TeT+dd9Fd3UOMAjy6J1TMpuYeEqg4LQZnATQO5vjPrsARm3und6zc6Dii/GUyRE5A==", + "dependencies": { + "json-format": "^1.0.1", + "source-map-support": "^0.5.5", + "xmlhttprequest": "^1.8.0" + }, + "bin": { + "npm-force-resolutions": "index.js" + } + }, "node_modules/npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -19117,7 +19179,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -19135,7 +19196,6 @@ "version": "0.5.21", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -21352,6 +21412,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/xmlhttprequest": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", + "integrity": "sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/xmlhttprequest-ssl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", diff --git a/package.json b/package.json index 2604c767..5034285a 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "worker-apollo-server", "main": "./build/index.js", "scripts": { + "preinstall": "npx npm-force-resolutions", "drizzle-kit": "drizzle-kit", "db:generate": "drizzle-kit generate && prettier ./drizzle/migrations --write", "db:check": "drizzle-kit check", @@ -69,10 +70,14 @@ "engines": { "node": ">=18" }, + "resolutions": { + "@opentelemetry/api": "1.6.0" + }, "dependencies": { "@cloudflare/workers-honeycomb-logger": "^2.3.3", "@envelop/core": "^5.0.0", "@envelop/immediate-introspection": "^2.0.0", + "@envelop/opentelemetry": "^6.3.1", "@envelop/rate-limiter": "^5.0.0", "@faker-js/faker": "^8.0.2", "@graphql-authz/envelop-plugin": "^1.0.4", @@ -80,10 +85,12 @@ "@libsql/client": "^0.3.5", "@microlabs/otel-cf-workers": "^1.0.0-rc.40", "@neondatabase/serverless": "^0.4.26", + "@opentelemetry/api": "^1.9.0", "@pothos/core": "^3.30.0", "@pothos/plugin-authz": "^3.5.8", "@pothos/plugin-dataloader": "^3.19.0", "@pothos/plugin-tracing": "^0.5.8", + "@pothos/tracing-opentelemetry": "^1.1.0", "@sanity/client": "^6.7.0", "@tsndr/cloudflare-worker-jwt": "^2.5.3", "@types/react": "^18.2.22", @@ -100,6 +107,7 @@ "graphql-yoga": "^5.6.1", "hono": "^3.9.0", "mercadopago": "^2.0.9", + "npm-force-resolutions": "^0.0.10", "p-map": "^6.0.0", "pino": "^9.2.0", "pino-pretty": "^11.2.1", diff --git a/src/builder.ts b/src/builder.ts index 59af1e65..85d4c052 100644 --- a/src/builder.ts +++ b/src/builder.ts @@ -1,13 +1,26 @@ +import { AttributeValue } from "@opentelemetry/api"; import SchemaBuilder from "@pothos/core"; import AuthzPlugin from "@pothos/plugin-authz"; import DataloaderPlugin from "@pothos/plugin-dataloader"; -import TracingPlugin, { wrapResolver } from "@pothos/plugin-tracing"; +import TracingPlugin, { + isRootField, + wrapResolver, +} from "@pothos/plugin-tracing"; +import { createOpenTelemetryWrapper } from "@pothos/tracing-opentelemetry"; import { DateResolver, DateTimeResolver } from "graphql-scalars"; import * as rules from "~/authz"; import { defaultLogger } from "~/logging"; +import { tracer } from "~/tracing"; import { Context } from "~/types"; +type TracingOptions = boolean | { attributes?: Record }; + +const createSpan = createOpenTelemetryWrapper(tracer, { + includeSource: true, + includeArgs: true, +}); + export const builder = new SchemaBuilder<{ Context: Context; AuthZRule: keyof typeof rules; @@ -24,12 +37,14 @@ export const builder = new SchemaBuilder<{ }>({ plugins: [TracingPlugin, AuthzPlugin, DataloaderPlugin], tracing: { - default: () => true, + default: (config) => isRootField(config), wrap: (resolver, options, config) => wrapResolver(resolver, (error, duration) => { - defaultLogger.debug( + defaultLogger.info( `[TRACING] ${config.parentType}.${config.name} in ${duration}ms`, ); + + return createSpan(resolver, options); }), }, }); diff --git a/src/index.ts b/src/index.ts index 67fffdb5..8d0a26b8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,9 @@ import { useMaskedErrors } from "@envelop/core"; import { useImmediateIntrospection } from "@envelop/immediate-introspection"; +import { useOpenTelemetry } from "@envelop/opentelemetry"; import { authZEnvelopPlugin } from "@graphql-authz/envelop-plugin"; import { instrument, ResolveConfigFn } from "@microlabs/otel-cf-workers"; +import { trace } from "@opentelemetry/api"; import { createYoga, maskError } from "graphql-yoga"; import { Env } from "worker-configuration"; @@ -11,6 +13,7 @@ import { createGraphqlContext } from "~/context"; import { APP_ENV } from "~/env"; import { createLogger } from "~/logging"; import { schema } from "~/schema"; +import { tracingPlugin } from "~/tracing"; export const yoga = createYoga({ landingPage: APP_ENV !== "production", @@ -66,15 +69,32 @@ export const yoga = createYoga({ }), useImmediateIntrospection(), authZEnvelopPlugin({ rules }), + // useOpenTelemetry({ + // resolvers: true, // Tracks resolvers calls, and tracks resolvers thrown errors + // variables: true, // Includes the operation variables values as part of the metadata collected + // result: true, // Includes execution result object as part of the metadata collected + // }), + tracingPlugin, ].filter(Boolean), context: createGraphqlContext, }); const handler = { fetch: async (req: Request, env: Env, ctx: ExecutionContext) => { + const span = trace.getActiveSpan(); + + const internalUUID = crypto.randomUUID(); + + span?.setAttribute( + "extrenal-trace-id", + req.headers.get("x-trace-id") ?? "unknown", + ); + span?.setAttribute("trace-id", internalUUID); + + // const span = trace.getActiveSpan() const logger = createLogger("graphql", { externalTraceId: req.headers.get("x-trace-id"), - traceId: crypto.randomUUID(), + traceId: internalUUID, }); logTraceId(req, logger); diff --git a/src/tracing.ts b/src/tracing.ts new file mode 100644 index 00000000..82fcf1a5 --- /dev/null +++ b/src/tracing.ts @@ -0,0 +1,35 @@ +import { trace as OpenTelemetryTrace } from "@opentelemetry/api"; +import { AttributeNames, SpanNames } from "@pothos/tracing-opentelemetry"; +import { print } from "graphql"; +import { Plugin } from "graphql-yoga"; + +export const trace = OpenTelemetryTrace; +export const tracer = OpenTelemetryTrace.getTracer("graphql-api"); + +export const tracingPlugin: Plugin = { + onExecute: ({ setExecuteFn, executeFn }) => { + setExecuteFn((options) => + tracer.startActiveSpan( + SpanNames.EXECUTE, + { + attributes: { + [AttributeNames.OPERATION_NAME]: options.operationName ?? undefined, + [AttributeNames.SOURCE]: print(options.document), + }, + }, + async (span) => { + try { + const result = (await executeFn(options)) as unknown; + + return result; + } catch (error) { + span.recordException(error as Error); + throw error; + } finally { + span.end(); + } + }, + ), + ); + }, +};