From f3ae2c22dacc65d6f834ed33dc978fb24e2501ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Dan?= Date: Tue, 7 Nov 2023 19:01:09 +0100 Subject: [PATCH] feat: revert to otel instrumentation (#17) --- .env.example | 11 +- .github/workflows/test.yml | 5 - README.md | 11 - package-lock.json | 1205 ++++++++++++++++++++++-- package.json | 3 + src/apm/apm.module.ts | 11 - src/apm/apm.service.ts | 41 - src/app.module.ts | 2 + src/execute/execute.controller.spec.ts | 4 +- src/execute/execute.controller.ts | 91 +- src/execute/execute.module.ts | 3 +- src/execute/execute.processor.spec.ts | 39 +- src/execute/execute.processor.ts | 235 +++-- src/execute/execute.service.spec.ts | 30 +- src/execute/execute.service.ts | 175 ++-- src/telemetry/telemetry.module.ts | 9 + src/telemetry/telemetry.service.ts | 49 + src/utils/index.ts | 3 + test/execute.e2e-spec.ts | 4 - 19 files changed, 1539 insertions(+), 392 deletions(-) delete mode 100644 src/apm/apm.module.ts delete mode 100644 src/apm/apm.service.ts create mode 100644 src/telemetry/telemetry.module.ts create mode 100644 src/telemetry/telemetry.service.ts diff --git a/.env.example b/.env.example index 7951733..129d43c 100644 --- a/.env.example +++ b/.env.example @@ -2,10 +2,11 @@ AUTH0_AUDIENCE= AUTH0_ISSUER_URL= REDIS_HOST= REDIS_PORT= -TOPOS_SUBNET_ENDPOINT_WS= SUBNET_REGISTRATOR_CONTRACT_ADDRESS= TOPOS_CORE_PROXY_CONTRACT_ADDRESS= -TRACING_SERVICE_NAME= -TRACING_SERVICE_VERSION= -ELASTIC_APM_ENDPOINT= -ELASTIC_APM_TOKEN= +TOPOS_SUBNET_ENDPOINT_WS= + +# telemetry +OTEL_EXPORTER_OTLP_ENDPOINT= +OTEL_SERVICE_NAME= +OTEL_SERVICE_VERSION= diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0f85647..d1d4eee 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,9 +22,6 @@ jobs: - run: npm ci - run: npm run test - env: - ELASTIC_APM_ENDPOINT: ${{ secrets.ELASTIC_APM_ENDPOINT }} - ELASTIC_APM_TOKEN: ${{ secrets.ELASTIC_APM_TOKEN }} e2e-tests: name: E2E tests @@ -45,5 +42,3 @@ jobs: REDIS_HOST: ${{ vars.REDIS_HOST }} REDIS_PORT: ${{ vars.REDIS_PORT }} PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }} - ELASTIC_APM_ENDPOINT: ${{ secrets.ELASTIC_APM_ENDPOINT }} - ELASTIC_APM_TOKEN: ${{ secrets.ELASTIC_APM_TOKEN }} diff --git a/README.md b/README.md index 9bfed0c..efc9b67 100644 --- a/README.md +++ b/README.md @@ -33,17 +33,6 @@ The Executor Service requires a local environment to be set up. Create an `.env` at the root of the project, with the content of `.env.example`, and fill the revelant env var values. -``` -AUTH0_AUDIENCE= -AUTH0_ISSUER_URL= -REDIS_HOST= -REDIS_PORT= -TOPOS_SUBNET_ENDPOINT_WS= -SUBNET_REGISTRATOR_CONTRACT_ADDRESS= -TOPOS_CORE_PROXY_CONTRACT_ADDRESS= -ERC20_MESSAGING_CONTRACT_ADDRESS= -``` - ### Authentication (Auth0) The Executor Service leverages [Auth0](https://auth0.com/) for machine-to-machine authentication and authorization. We use Auth0's machine-to-machine service as we are not authenticating/authorizing users but applications (e.g., dApp frontends) that will use the Executor Service as a call delegation for their users' cross-subnet messages. diff --git a/package-lock.json b/package-lock.json index 1fafe46..5266fb3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,9 @@ "@nestjs/passport": "^9.0.0", "@nestjs/platform-express": "^9.4.0", "@nestjs/swagger": "^6.1.2", + "@opentelemetry/exporter-metrics-otlp-proto": "^0.44.0", + "@opentelemetry/exporter-trace-otlp-proto": "^0.44.0", + "@opentelemetry/sdk-node": "^0.44.0", "@topos-protocol/topos-smart-contracts": "^2.0.0", "bcrypt": "^5.1.0", "bull": "^4.10.1", @@ -1643,6 +1646,65 @@ "@ethersproject/strings": "^5.7.0" } }, + "node_modules/@grpc/grpc-js": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.7.tgz", + "integrity": "sha512-yMaA/cIsRhGzW3ymCNpdlPcInXcovztlgu/rirThj2b87u3RzWUszliOqZ/pldy7yhmJPS8uwog+kZSTa4A0PQ==", + "dependencies": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", + "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.4", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@grpc/proto-loader/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@grpc/proto-loader/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.9.5", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", @@ -2680,55 +2742,395 @@ "node": ">=8.0.0" } }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.44.0.tgz", + "integrity": "sha512-OctojdKGmXHKAJa4/Ml+Nf7MD9jtYXvZyP64xTh0pNTmtgaTdWW3FURri2DdB/+l7YxRy0tYYZS3/tYEM1pj3w==", + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.17.1.tgz", + "integrity": "sha512-up5I+RiQEkGrVEHtbAtmRgS+ZOnFh3shaDNHqZPBlGy+O92auL6yMmjzYpSKmJOGWowvs3fhVHePa8Exb5iHUg==", + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.7.0" + } + }, "node_modules/@opentelemetry/core": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.15.1.tgz", - "integrity": "sha512-V6GoRTY6aANMDDOQ9CiHOiLWEK2b2b3OGZK+zk05Li5merb9jadFeV5ooTSGtjxfxVNMpQUaQERO1cdbdbeEGg==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.17.1.tgz", + "integrity": "sha512-I6LrZvl1FF97FQXPR0iieWQmKnGxYtMbWA1GrAXnLUR+B1Hn2m8KqQNEIlZAucyv00GBgpWkpllmULmZfG8P3g==", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.7.0" + } + }, + "node_modules/@opentelemetry/exporter-jaeger": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-jaeger/-/exporter-jaeger-1.17.1.tgz", + "integrity": "sha512-NW4qm04q4bSmhU6es1AXBWt3itJ2gkrXbKLfwDleC+ZMp3bVV47stByDqhuJzic2f47Im+C733N9RMeBkyqKMQ==", + "dependencies": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/sdk-trace-base": "1.17.1", + "@opentelemetry/semantic-conventions": "1.17.1", + "jaeger-client": "^3.15.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-http": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.44.0.tgz", + "integrity": "sha512-OiEkP9XWbh5ufjnP+xe8EQ2LShMY5f1NYBm9W/BgLaHPtlMNZnR7JB1t6Ut4gaZ7LA/yFnyrB0TnZcxntpBZ3Q==", + "dependencies": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/otlp-exporter-base": "0.44.0", + "@opentelemetry/otlp-transformer": "0.44.0", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-metrics": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-proto": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-proto/-/exporter-metrics-otlp-proto-0.44.0.tgz", + "integrity": "sha512-GnxFAtb42OkE8sHmty5Ex5rEOfS+psAhCUq/Jod+7ZKMwUrxGvUWAa3nS9CkihhL2lj4rBU7o8SV8TO0Nn85/A==", + "dependencies": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/exporter-metrics-otlp-http": "0.44.0", + "@opentelemetry/otlp-exporter-base": "0.44.0", + "@opentelemetry/otlp-proto-exporter-base": "0.44.0", + "@opentelemetry/otlp-transformer": "0.44.0", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-metrics": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-grpc": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.44.0.tgz", + "integrity": "sha512-S1kT/9tVlgZDRYyVfCLYyWZoQTplPD9WcyX+qUPbhJTETORxzJVW9HN8mHwQsXaN7ngqwRLy5GW/nXHL8aqA0w==", + "dependencies": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "1.17.1", + "@opentelemetry/otlp-grpc-exporter-base": "0.44.0", + "@opentelemetry/otlp-transformer": "0.44.0", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-trace-base": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.44.0.tgz", + "integrity": "sha512-RkorGE6wf6PF5OjMUGBnbUDyaVgmN+vL7OgClJJUTxqbE7WqgbW8dkU04O+1mcB1znXZ1Aej1uDm0pS+eW/upA==", + "dependencies": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/otlp-exporter-base": "0.44.0", + "@opentelemetry/otlp-transformer": "0.44.0", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-trace-base": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-proto": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.44.0.tgz", + "integrity": "sha512-yVW0FXxiLaQOyE3MGr6BtK7ml0DaJH4Qx3yvQYUd/hsJUSZBhYYw2TRaMsaW7XMpe1AvU81qt0l8uLYmcmcLJA==", + "dependencies": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/otlp-exporter-base": "0.44.0", + "@opentelemetry/otlp-proto-exporter-base": "0.44.0", + "@opentelemetry/otlp-transformer": "0.44.0", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-trace-base": "1.17.1" + }, + "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==", + "dependencies": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-trace-base": "1.17.1", + "@opentelemetry/semantic-conventions": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "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==", + "dependencies": { + "@types/shimmer": "^1.0.2", + "import-in-the-middle": "1.4.2", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.44.0.tgz", + "integrity": "sha512-DKQqRrfVMe96aSLZiCgIesLcMLfnWH8d4bTpLB1JbU+SAQJ7nVCAfS9U36mjFCVhvNDD7gwfCNrxqFMCHq6FUw==", + "dependencies": { + "@opentelemetry/core": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/otlp-grpc-exporter-base": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.44.0.tgz", + "integrity": "sha512-RsYW2+ikNDDXM9rY4gCA3lJOu53o4CzCsUJ9DV6r78k/Y0ckWw2GM7R4I6yOmMe4jilxEaHorI3oTJFLD8KYug==", + "dependencies": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "1.17.1", + "@opentelemetry/otlp-exporter-base": "0.44.0", + "protobufjs": "^7.2.3" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/otlp-proto-exporter-base": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-proto-exporter-base/-/otlp-proto-exporter-base-0.44.0.tgz", + "integrity": "sha512-vgQvWEkXNk8X4BW93+j054TZBVs1ryguXQjeoLeHV/dzopdGuAypI0xC5OtSr+eRftuyPqPl2DVp4tjRq4z4dw==", "dependencies": { - "@opentelemetry/semantic-conventions": "1.15.1" + "@opentelemetry/core": "1.17.1", + "@opentelemetry/otlp-exporter-base": "0.44.0", + "protobufjs": "^7.2.3" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.5.0" + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.44.0.tgz", + "integrity": "sha512-1/KC+aHM1oGEsXyNy7QoxpvErxGdzt26bg9VHyNb4TDILkUFdwrnywnxPc6lXZ6h/8T8Mt718UWOKjNHC514kQ==", + "dependencies": { + "@opentelemetry/api-logs": "0.44.0", + "@opentelemetry/core": "1.17.1", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-logs": "0.44.0", + "@opentelemetry/sdk-metrics": "1.17.1", + "@opentelemetry/sdk-trace-base": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.7.0" + } + }, + "node_modules/@opentelemetry/propagator-b3": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-1.17.1.tgz", + "integrity": "sha512-XEbXYb81AM3ayJLlbJqITPIgKBQCuby45ZHiB9mchnmQOffh6ZJOmXONdtZAV7TWzmzwvAd28vGSUk57Aw/5ZA==", + "dependencies": { + "@opentelemetry/core": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.7.0" + } + }, + "node_modules/@opentelemetry/propagator-jaeger": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.17.1.tgz", + "integrity": "sha512-p+P4lf2pbqd3YMfZO15QCGsDwR2m1ke2q5+dq6YBLa/q0qiC2eq4cD/qhYBBed5/X4PtdamaVGHGsp+u3GXHDA==", + "dependencies": { + "@opentelemetry/core": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.7.0" } }, "node_modules/@opentelemetry/resources": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.15.1.tgz", - "integrity": "sha512-15JcpyKZHhFYQ1uiC08vR02sRY/2seSnqSJ0tIUhcdYDzOhd0FrqPYpLj3WkLhVdQP6vgJ+pelAmSaOrCxCpKA==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.17.1.tgz", + "integrity": "sha512-M2e5emqg5I7qRKqlzKx0ROkcPyF8PbcSaWEdsm72od9txP7Z/Pl8PDYOyu80xWvbHAWk5mDxOF6v3vNdifzclA==", "dependencies": { - "@opentelemetry/core": "1.15.1", - "@opentelemetry/semantic-conventions": "1.15.1" + "@opentelemetry/core": "1.17.1", + "@opentelemetry/semantic-conventions": "1.17.1" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.5.0" + "@opentelemetry/api": ">=1.0.0 <1.7.0" + } + }, + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.44.0.tgz", + "integrity": "sha512-UN3ofh9Jj54gIgrSXNRWAoaH6iPvrrjed5YAtqO9cW65U+5QPzk1Rv95vjAcY9VTrmMWvuqgEK1CYObG6Hu4OQ==", + "dependencies": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/resources": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.7.0", + "@opentelemetry/api-logs": ">=0.39.1" } }, "node_modules/@opentelemetry/sdk-metrics": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.15.1.tgz", - "integrity": "sha512-ojcrzexOQfto83NvKfIvsJap4SHH3ZvLjsDGhQ04AfvWWGR7mPcqLSlLedoSkEdIe0k1H6uBEsHBtIprkMpTHA==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.17.1.tgz", + "integrity": "sha512-eHdpsMCKhKhwznxvEfls8Wv3y4ZBWkkXlD3m7vtHIiWBqsMHspWSfie1s07mM45i/bBCf6YBMgz17FUxIXwmZA==", "dependencies": { - "@opentelemetry/core": "1.15.1", - "@opentelemetry/resources": "1.15.1", + "@opentelemetry/core": "1.17.1", + "@opentelemetry/resources": "1.17.1", "lodash.merge": "^4.6.2" }, "engines": { "node": ">=14" }, "peerDependencies": { - "@opentelemetry/api": ">=1.3.0 <1.5.0" + "@opentelemetry/api": ">=1.3.0 <1.7.0" + } + }, + "node_modules/@opentelemetry/sdk-node": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-node/-/sdk-node-0.44.0.tgz", + "integrity": "sha512-MkMJcUcqjNV/A5/y6quedSO3CIDXY17jM8sxQa0Hwmx77+/QiXJkSe4Zv0ysf37mV5+8QEt4rsq7adKg+LtaEg==", + "dependencies": { + "@opentelemetry/api-logs": "0.44.0", + "@opentelemetry/core": "1.17.1", + "@opentelemetry/exporter-jaeger": "1.17.1", + "@opentelemetry/exporter-trace-otlp-grpc": "0.44.0", + "@opentelemetry/exporter-trace-otlp-http": "0.44.0", + "@opentelemetry/exporter-trace-otlp-proto": "0.44.0", + "@opentelemetry/exporter-zipkin": "1.17.1", + "@opentelemetry/instrumentation": "0.44.0", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-logs": "0.44.0", + "@opentelemetry/sdk-metrics": "1.17.1", + "@opentelemetry/sdk-trace-base": "1.17.1", + "@opentelemetry/sdk-trace-node": "1.17.1", + "@opentelemetry/semantic-conventions": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.7.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==", + "dependencies": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/semantic-conventions": "1.17.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.7.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.17.1.tgz", + "integrity": "sha512-J56DaG4cusjw5crpI7x9rv4bxDF27DtKYGxXJF56KIvopbNKpdck5ZWXBttEyqgAVPDwHMAXWDL1KchHzF0a3A==", + "dependencies": { + "@opentelemetry/context-async-hooks": "1.17.1", + "@opentelemetry/core": "1.17.1", + "@opentelemetry/propagator-b3": "1.17.1", + "@opentelemetry/propagator-jaeger": "1.17.1", + "@opentelemetry/sdk-trace-base": "1.17.1", + "semver": "^7.5.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.7.0" } }, "node_modules/@opentelemetry/semantic-conventions": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.1.tgz", - "integrity": "sha512-n8Kur1/CZlYG32YCEj30CoUqA8R7UyDVZzoEU6SDP+13+kXDT2kFVu6MpcnEUTyGP3i058ID6Qjp5h6IJxdPPQ==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.17.1.tgz", + "integrity": "sha512-xbR2U+2YjauIuo42qmE8XyJK6dYeRMLJuOlUP5SO4auET4VtOHOzgkRVOq+Ik18N+Xf3YPcqJs9dZMiDddz1eQ==", "engines": { "node": ">=14" } @@ -2746,6 +3148,60 @@ "node": ">=10.13.0" } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, "node_modules/@sinonjs/commons": { "version": "1.8.6", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", @@ -3076,6 +3532,11 @@ "@types/node": "*" } }, + "node_modules/@types/shimmer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.0.4.tgz", + "integrity": "sha512-hsughtxFsdJ9+Gxd/qH8zHE+KT6YEAxx9hJLoSXhxTBKHMQ2NMhN23fRJ75M9RRn2hDMNn13H3gS1EktA9VgDA==" + }, "node_modules/@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -3768,6 +4229,14 @@ "ajv": "^6.9.1" } }, + "node_modules/ansi-color": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-color/-/ansi-color-0.2.1.tgz", + "integrity": "sha512-bF6xLaZBLpOQzgYUtYEhJx090nPSZk1BQ/q2oyBK9aMMcJHzx9uXGCjI2Y+LebsN4Jwoykr0V9whbPiogdyHoQ==", + "engines": { + "node": "*" + } + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -4307,6 +4776,20 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "node_modules/bufrw": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/bufrw/-/bufrw-1.4.0.tgz", + "integrity": "sha512-sWm8iPbqvL9+5SiYxXH73UOkyEbGQg7kyHQmReF89WJHQJw2eV4P/yZ0E+b71cczJ4pPobVhXxgQcmfSTgGHxQ==", + "dependencies": { + "ansi-color": "^0.2.1", + "error": "^7.0.0", + "hexer": "^1.5.0", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.10.x" + } + }, "node_modules/bull": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/bull/-/bull-4.10.1.tgz", @@ -5122,17 +5605,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/elastic-apm-node/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==", - "dependencies": { - "acorn": "^8.8.2", - "acorn-import-assertions": "^1.9.0", - "cjs-module-lexer": "^1.2.2", - "module-details-from-path": "^1.0.3" - } - }, "node_modules/elastic-apm-node/node_modules/lru-cache": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", @@ -5259,6 +5731,15 @@ "node": ">=10.13.0" } }, + "node_modules/error": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz", + "integrity": "sha512-UtVv4l5MhijsYUxPJo4390gzfZvAnTHreNnDjnTZaKIiZ/SemXxAhBkYSKtWa5RtBXbLP8tMgn/n0RUa/H7jXw==", + "dependencies": { + "string-template": "~0.2.1", + "xtend": "~4.0.0" + } + }, "node_modules/error-callsites": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/error-callsites/-/error-callsites-2.0.4.tgz", @@ -5375,7 +5856,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, "engines": { "node": ">=6" } @@ -6389,7 +6869,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -6661,6 +7140,23 @@ "minimalistic-assert": "^1.0.1" } }, + "node_modules/hexer": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/hexer/-/hexer-1.5.0.tgz", + "integrity": "sha512-dyrPC8KzBzUJ19QTIo1gXNqIISRXQ0NwteW6OeQHRN4ZuZeHkdODfj0zHBdOlHbRY8GqbqK57C9oWSvQZizFsg==", + "dependencies": { + "ansi-color": "^0.2.1", + "minimist": "^1.1.0", + "process": "^0.10.0", + "xtend": "^4.0.0" + }, + "bin": { + "hexer": "cli.js" + }, + "engines": { + "node": ">= 0.10.x" + } + }, "node_modules/hexoid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", @@ -6863,6 +7359,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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==", + "dependencies": { + "acorn": "^8.8.2", + "acorn-import-assertions": "^1.9.0", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -7441,6 +7948,21 @@ "node": ">=6" } }, + "node_modules/jaeger-client": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/jaeger-client/-/jaeger-client-3.19.0.tgz", + "integrity": "sha512-M0c7cKHmdyEUtjemnJyx/y9uX16XHocL46yQvyqDlPdvAcwPDbHrIbKjQdBqtiE4apQ/9dmr+ZLJYYPGnurgpw==", + "dependencies": { + "node-int64": "^0.4.0", + "opentracing": "^0.14.4", + "thriftrw": "^3.5.0", + "uuid": "^8.3.2", + "xorshift": "^1.1.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jest": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", @@ -8463,6 +8985,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, "node_modules/lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -8515,6 +9042,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -8973,8 +9505,7 @@ "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" }, "node_modules/node-releases": { "version": "2.0.12", @@ -9140,6 +9671,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/opentracing": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.7.tgz", + "integrity": "sha512-vz9iS7MJ5+Bp1URw8Khvdyw1H/hGvzHWlKQ7eRrQojSCDL1/SrWfrY9QebLw97n2deyRtzHRC3MkQfVNUCo91Q==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/optional-js": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/optional-js/-/optional-js-2.3.0.tgz", @@ -9662,6 +10201,14 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/process": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/process/-/process-0.10.1.tgz", + "integrity": "sha512-dyIett8dgGIZ/TXKUzeYExt7WA6ldDzys9vTDU/cCA9L17Ypme+KzS+NjQCjpn9xsvi/shbMC+yP/BcFMBz0NA==", + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -9685,6 +10232,29 @@ "node": ">= 6" } }, + "node_modules/protobufjs": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", + "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -9925,7 +10495,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -10349,6 +10918,11 @@ "node": ">=4" } }, + "node_modules/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -10542,6 +11116,11 @@ "integrity": "sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==", "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info." }, + "node_modules/string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==" + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -10915,6 +11494,30 @@ "real-require": "^0.2.0" } }, + "node_modules/thriftrw": { + "version": "3.11.4", + "resolved": "https://registry.npmjs.org/thriftrw/-/thriftrw-3.11.4.tgz", + "integrity": "sha512-UcuBd3eanB3T10nXWRRMwfwoaC6VMk7qe3/5YIWP2Jtw+EbHqJ0p1/K3x8ixiR5dozKSSfcg1W+0e33G1Di3XA==", + "dependencies": { + "bufrw": "^1.2.1", + "error": "7.0.2", + "long": "^2.4.0" + }, + "bin": { + "thrift2json": "thrift2json.js" + }, + "engines": { + "node": ">= 0.10.x" + } + }, + "node_modules/thriftrw/node_modules/long": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/long/-/long-2.4.0.tgz", + "integrity": "sha512-ijUtjmO/n2A5PaosNG9ZGDsQ3vxJg7ZW8vsY8Kp0f2yIZWhSJvjmegV7t+9RPQKxKrvj8yKGehhS+po14hPLGQ==", + "engines": { + "node": ">=0.6" + } + }, "node_modules/throat": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", @@ -11727,7 +12330,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -11790,6 +12392,11 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "node_modules/xorshift": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/xorshift/-/xorshift-1.2.0.tgz", + "integrity": "sha512-iYgNnGyeeJ4t6U11NpA/QiKy+PXn5Aa3Azg5qkwIFz1tBLllQrjjsk9yzD7IAK0naNU4JxdeDgqW9ov4u/hc4g==" + }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -11802,7 +12409,6 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, "engines": { "node": ">=10" } @@ -11843,7 +12449,6 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, "engines": { "node": ">=12" } @@ -12932,6 +13537,52 @@ "@ethersproject/strings": "^5.7.0" } }, + "@grpc/grpc-js": { + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.7.tgz", + "integrity": "sha512-yMaA/cIsRhGzW3ymCNpdlPcInXcovztlgu/rirThj2b87u3RzWUszliOqZ/pldy7yhmJPS8uwog+kZSTa4A0PQ==", + "requires": { + "@grpc/proto-loader": "^0.7.8", + "@types/node": ">=12.12.47" + } + }, + "@grpc/proto-loader": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz", + "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==", + "requires": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.4", + "yargs": "^17.7.2" + }, + "dependencies": { + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + } + } + }, "@humanwhocodes/config-array": { "version": "0.9.5", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", @@ -13658,37 +14309,260 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.4.1.tgz", "integrity": "sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA==" }, + "@opentelemetry/api-logs": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.44.0.tgz", + "integrity": "sha512-OctojdKGmXHKAJa4/Ml+Nf7MD9jtYXvZyP64xTh0pNTmtgaTdWW3FURri2DdB/+l7YxRy0tYYZS3/tYEM1pj3w==", + "requires": { + "@opentelemetry/api": "^1.0.0" + } + }, + "@opentelemetry/context-async-hooks": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-1.17.1.tgz", + "integrity": "sha512-up5I+RiQEkGrVEHtbAtmRgS+ZOnFh3shaDNHqZPBlGy+O92auL6yMmjzYpSKmJOGWowvs3fhVHePa8Exb5iHUg==", + "requires": {} + }, "@opentelemetry/core": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.15.1.tgz", - "integrity": "sha512-V6GoRTY6aANMDDOQ9CiHOiLWEK2b2b3OGZK+zk05Li5merb9jadFeV5ooTSGtjxfxVNMpQUaQERO1cdbdbeEGg==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.17.1.tgz", + "integrity": "sha512-I6LrZvl1FF97FQXPR0iieWQmKnGxYtMbWA1GrAXnLUR+B1Hn2m8KqQNEIlZAucyv00GBgpWkpllmULmZfG8P3g==", + "requires": { + "@opentelemetry/semantic-conventions": "1.17.1" + } + }, + "@opentelemetry/exporter-jaeger": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-jaeger/-/exporter-jaeger-1.17.1.tgz", + "integrity": "sha512-NW4qm04q4bSmhU6es1AXBWt3itJ2gkrXbKLfwDleC+ZMp3bVV47stByDqhuJzic2f47Im+C733N9RMeBkyqKMQ==", + "requires": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/sdk-trace-base": "1.17.1", + "@opentelemetry/semantic-conventions": "1.17.1", + "jaeger-client": "^3.15.0" + } + }, + "@opentelemetry/exporter-metrics-otlp-http": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.44.0.tgz", + "integrity": "sha512-OiEkP9XWbh5ufjnP+xe8EQ2LShMY5f1NYBm9W/BgLaHPtlMNZnR7JB1t6Ut4gaZ7LA/yFnyrB0TnZcxntpBZ3Q==", + "requires": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/otlp-exporter-base": "0.44.0", + "@opentelemetry/otlp-transformer": "0.44.0", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-metrics": "1.17.1" + } + }, + "@opentelemetry/exporter-metrics-otlp-proto": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-proto/-/exporter-metrics-otlp-proto-0.44.0.tgz", + "integrity": "sha512-GnxFAtb42OkE8sHmty5Ex5rEOfS+psAhCUq/Jod+7ZKMwUrxGvUWAa3nS9CkihhL2lj4rBU7o8SV8TO0Nn85/A==", + "requires": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/exporter-metrics-otlp-http": "0.44.0", + "@opentelemetry/otlp-exporter-base": "0.44.0", + "@opentelemetry/otlp-proto-exporter-base": "0.44.0", + "@opentelemetry/otlp-transformer": "0.44.0", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-metrics": "1.17.1" + } + }, + "@opentelemetry/exporter-trace-otlp-grpc": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.44.0.tgz", + "integrity": "sha512-S1kT/9tVlgZDRYyVfCLYyWZoQTplPD9WcyX+qUPbhJTETORxzJVW9HN8mHwQsXaN7ngqwRLy5GW/nXHL8aqA0w==", + "requires": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "1.17.1", + "@opentelemetry/otlp-grpc-exporter-base": "0.44.0", + "@opentelemetry/otlp-transformer": "0.44.0", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-trace-base": "1.17.1" + } + }, + "@opentelemetry/exporter-trace-otlp-http": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.44.0.tgz", + "integrity": "sha512-RkorGE6wf6PF5OjMUGBnbUDyaVgmN+vL7OgClJJUTxqbE7WqgbW8dkU04O+1mcB1znXZ1Aej1uDm0pS+eW/upA==", + "requires": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/otlp-exporter-base": "0.44.0", + "@opentelemetry/otlp-transformer": "0.44.0", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-trace-base": "1.17.1" + } + }, + "@opentelemetry/exporter-trace-otlp-proto": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.44.0.tgz", + "integrity": "sha512-yVW0FXxiLaQOyE3MGr6BtK7ml0DaJH4Qx3yvQYUd/hsJUSZBhYYw2TRaMsaW7XMpe1AvU81qt0l8uLYmcmcLJA==", + "requires": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/otlp-exporter-base": "0.44.0", + "@opentelemetry/otlp-proto-exporter-base": "0.44.0", + "@opentelemetry/otlp-transformer": "0.44.0", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-trace-base": "1.17.1" + } + }, + "@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==", + "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/instrumentation": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.44.0.tgz", + "integrity": "sha512-B6OxJTRRCceAhhnPDBshyQO7K07/ltX3quOLu0icEvPK9QZ7r9P1y0RQX8O5DxB4vTv4URRkxkg+aFU/plNtQw==", + "requires": { + "@types/shimmer": "^1.0.2", + "import-in-the-middle": "1.4.2", + "require-in-the-middle": "^7.1.1", + "semver": "^7.5.2", + "shimmer": "^1.2.1" + } + }, + "@opentelemetry/otlp-exporter-base": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.44.0.tgz", + "integrity": "sha512-DKQqRrfVMe96aSLZiCgIesLcMLfnWH8d4bTpLB1JbU+SAQJ7nVCAfS9U36mjFCVhvNDD7gwfCNrxqFMCHq6FUw==", + "requires": { + "@opentelemetry/core": "1.17.1" + } + }, + "@opentelemetry/otlp-grpc-exporter-base": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.44.0.tgz", + "integrity": "sha512-RsYW2+ikNDDXM9rY4gCA3lJOu53o4CzCsUJ9DV6r78k/Y0ckWw2GM7R4I6yOmMe4jilxEaHorI3oTJFLD8KYug==", + "requires": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "1.17.1", + "@opentelemetry/otlp-exporter-base": "0.44.0", + "protobufjs": "^7.2.3" + } + }, + "@opentelemetry/otlp-proto-exporter-base": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-proto-exporter-base/-/otlp-proto-exporter-base-0.44.0.tgz", + "integrity": "sha512-vgQvWEkXNk8X4BW93+j054TZBVs1ryguXQjeoLeHV/dzopdGuAypI0xC5OtSr+eRftuyPqPl2DVp4tjRq4z4dw==", + "requires": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/otlp-exporter-base": "0.44.0", + "protobufjs": "^7.2.3" + } + }, + "@opentelemetry/otlp-transformer": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.44.0.tgz", + "integrity": "sha512-1/KC+aHM1oGEsXyNy7QoxpvErxGdzt26bg9VHyNb4TDILkUFdwrnywnxPc6lXZ6h/8T8Mt718UWOKjNHC514kQ==", + "requires": { + "@opentelemetry/api-logs": "0.44.0", + "@opentelemetry/core": "1.17.1", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-logs": "0.44.0", + "@opentelemetry/sdk-metrics": "1.17.1", + "@opentelemetry/sdk-trace-base": "1.17.1" + } + }, + "@opentelemetry/propagator-b3": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-1.17.1.tgz", + "integrity": "sha512-XEbXYb81AM3ayJLlbJqITPIgKBQCuby45ZHiB9mchnmQOffh6ZJOmXONdtZAV7TWzmzwvAd28vGSUk57Aw/5ZA==", "requires": { - "@opentelemetry/semantic-conventions": "1.15.1" + "@opentelemetry/core": "1.17.1" + } + }, + "@opentelemetry/propagator-jaeger": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-1.17.1.tgz", + "integrity": "sha512-p+P4lf2pbqd3YMfZO15QCGsDwR2m1ke2q5+dq6YBLa/q0qiC2eq4cD/qhYBBed5/X4PtdamaVGHGsp+u3GXHDA==", + "requires": { + "@opentelemetry/core": "1.17.1" } }, "@opentelemetry/resources": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.15.1.tgz", - "integrity": "sha512-15JcpyKZHhFYQ1uiC08vR02sRY/2seSnqSJ0tIUhcdYDzOhd0FrqPYpLj3WkLhVdQP6vgJ+pelAmSaOrCxCpKA==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.17.1.tgz", + "integrity": "sha512-M2e5emqg5I7qRKqlzKx0ROkcPyF8PbcSaWEdsm72od9txP7Z/Pl8PDYOyu80xWvbHAWk5mDxOF6v3vNdifzclA==", + "requires": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/semantic-conventions": "1.17.1" + } + }, + "@opentelemetry/sdk-logs": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.44.0.tgz", + "integrity": "sha512-UN3ofh9Jj54gIgrSXNRWAoaH6iPvrrjed5YAtqO9cW65U+5QPzk1Rv95vjAcY9VTrmMWvuqgEK1CYObG6Hu4OQ==", "requires": { - "@opentelemetry/core": "1.15.1", - "@opentelemetry/semantic-conventions": "1.15.1" + "@opentelemetry/core": "1.17.1", + "@opentelemetry/resources": "1.17.1" } }, "@opentelemetry/sdk-metrics": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.15.1.tgz", - "integrity": "sha512-ojcrzexOQfto83NvKfIvsJap4SHH3ZvLjsDGhQ04AfvWWGR7mPcqLSlLedoSkEdIe0k1H6uBEsHBtIprkMpTHA==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.17.1.tgz", + "integrity": "sha512-eHdpsMCKhKhwznxvEfls8Wv3y4ZBWkkXlD3m7vtHIiWBqsMHspWSfie1s07mM45i/bBCf6YBMgz17FUxIXwmZA==", "requires": { - "@opentelemetry/core": "1.15.1", - "@opentelemetry/resources": "1.15.1", + "@opentelemetry/core": "1.17.1", + "@opentelemetry/resources": "1.17.1", "lodash.merge": "^4.6.2" } }, + "@opentelemetry/sdk-node": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-node/-/sdk-node-0.44.0.tgz", + "integrity": "sha512-MkMJcUcqjNV/A5/y6quedSO3CIDXY17jM8sxQa0Hwmx77+/QiXJkSe4Zv0ysf37mV5+8QEt4rsq7adKg+LtaEg==", + "requires": { + "@opentelemetry/api-logs": "0.44.0", + "@opentelemetry/core": "1.17.1", + "@opentelemetry/exporter-jaeger": "1.17.1", + "@opentelemetry/exporter-trace-otlp-grpc": "0.44.0", + "@opentelemetry/exporter-trace-otlp-http": "0.44.0", + "@opentelemetry/exporter-trace-otlp-proto": "0.44.0", + "@opentelemetry/exporter-zipkin": "1.17.1", + "@opentelemetry/instrumentation": "0.44.0", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/sdk-logs": "0.44.0", + "@opentelemetry/sdk-metrics": "1.17.1", + "@opentelemetry/sdk-trace-base": "1.17.1", + "@opentelemetry/sdk-trace-node": "1.17.1", + "@opentelemetry/semantic-conventions": "1.17.1" + } + }, + "@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==", + "requires": { + "@opentelemetry/core": "1.17.1", + "@opentelemetry/resources": "1.17.1", + "@opentelemetry/semantic-conventions": "1.17.1" + } + }, + "@opentelemetry/sdk-trace-node": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-1.17.1.tgz", + "integrity": "sha512-J56DaG4cusjw5crpI7x9rv4bxDF27DtKYGxXJF56KIvopbNKpdck5ZWXBttEyqgAVPDwHMAXWDL1KchHzF0a3A==", + "requires": { + "@opentelemetry/context-async-hooks": "1.17.1", + "@opentelemetry/core": "1.17.1", + "@opentelemetry/propagator-b3": "1.17.1", + "@opentelemetry/propagator-jaeger": "1.17.1", + "@opentelemetry/sdk-trace-base": "1.17.1", + "semver": "^7.5.2" + } + }, "@opentelemetry/semantic-conventions": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.1.tgz", - "integrity": "sha512-n8Kur1/CZlYG32YCEj30CoUqA8R7UyDVZzoEU6SDP+13+kXDT2kFVu6MpcnEUTyGP3i058ID6Qjp5h6IJxdPPQ==" + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.17.1.tgz", + "integrity": "sha512-xbR2U+2YjauIuo42qmE8XyJK6dYeRMLJuOlUP5SO4auET4VtOHOzgkRVOq+Ik18N+Xf3YPcqJs9dZMiDddz1eQ==" }, "@openzeppelin/contracts": { "version": "4.9.2", @@ -13700,6 +14574,60 @@ "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==" }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + }, "@sinonjs/commons": { "version": "1.8.6", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", @@ -14026,6 +14954,11 @@ "@types/node": "*" } }, + "@types/shimmer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.0.4.tgz", + "integrity": "sha512-hsughtxFsdJ9+Gxd/qH8zHE+KT6YEAxx9hJLoSXhxTBKHMQ2NMhN23fRJ75M9RRn2hDMNn13H3gS1EktA9VgDA==" + }, "@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -14551,6 +15484,11 @@ "dev": true, "requires": {} }, + "ansi-color": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-color/-/ansi-color-0.2.1.tgz", + "integrity": "sha512-bF6xLaZBLpOQzgYUtYEhJx090nPSZk1BQ/q2oyBK9aMMcJHzx9uXGCjI2Y+LebsN4Jwoykr0V9whbPiogdyHoQ==" + }, "ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -14956,6 +15894,17 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "bufrw": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/bufrw/-/bufrw-1.4.0.tgz", + "integrity": "sha512-sWm8iPbqvL9+5SiYxXH73UOkyEbGQg7kyHQmReF89WJHQJw2eV4P/yZ0E+b71cczJ4pPobVhXxgQcmfSTgGHxQ==", + "requires": { + "ansi-color": "^0.2.1", + "error": "^7.0.0", + "hexer": "^1.5.0", + "xtend": "^4.0.0" + } + }, "bull": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/bull/-/bull-4.10.1.tgz", @@ -15572,17 +16521,6 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, - "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==", - "requires": { - "acorn": "^8.8.2", - "acorn-import-assertions": "^1.9.0", - "cjs-module-lexer": "^1.2.2", - "module-details-from-path": "^1.0.3" - } - }, "lru-cache": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz", @@ -15692,6 +16630,15 @@ "tapable": "^2.2.0" } }, + "error": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz", + "integrity": "sha512-UtVv4l5MhijsYUxPJo4390gzfZvAnTHreNnDjnTZaKIiZ/SemXxAhBkYSKtWa5RtBXbLP8tMgn/n0RUa/H7jXw==", + "requires": { + "string-template": "~0.2.1", + "xtend": "~4.0.0" + } + }, "error-callsites": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/error-callsites/-/error-callsites-2.0.4.tgz", @@ -15789,8 +16736,7 @@ "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escape-html": { "version": "1.0.3", @@ -16561,8 +17507,7 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-intrinsic": { "version": "1.2.1", @@ -16743,6 +17688,17 @@ "minimalistic-assert": "^1.0.1" } }, + "hexer": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/hexer/-/hexer-1.5.0.tgz", + "integrity": "sha512-dyrPC8KzBzUJ19QTIo1gXNqIISRXQ0NwteW6OeQHRN4ZuZeHkdODfj0zHBdOlHbRY8GqbqK57C9oWSvQZizFsg==", + "requires": { + "ansi-color": "^0.2.1", + "minimist": "^1.1.0", + "process": "^0.10.0", + "xtend": "^4.0.0" + } + }, "hexoid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", @@ -16889,6 +17845,17 @@ "resolve-from": "^4.0.0" } }, + "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==", + "requires": { + "acorn": "^8.8.2", + "acorn-import-assertions": "^1.9.0", + "cjs-module-lexer": "^1.2.2", + "module-details-from-path": "^1.0.3" + } + }, "import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", @@ -17294,6 +18261,18 @@ "resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz", "integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==" }, + "jaeger-client": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/jaeger-client/-/jaeger-client-3.19.0.tgz", + "integrity": "sha512-M0c7cKHmdyEUtjemnJyx/y9uX16XHocL46yQvyqDlPdvAcwPDbHrIbKjQdBqtiE4apQ/9dmr+ZLJYYPGnurgpw==", + "requires": { + "node-int64": "^0.4.0", + "opentracing": "^0.14.4", + "thriftrw": "^3.5.0", + "uuid": "^8.3.2", + "xorshift": "^1.1.1" + } + }, "jest": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", @@ -18092,6 +19071,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + }, "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -18138,6 +19122,11 @@ "is-unicode-supported": "^0.1.0" } }, + "long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -18502,8 +19491,7 @@ "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==" }, "node-releases": { "version": "2.0.12", @@ -18630,6 +19618,11 @@ "mimic-fn": "^2.1.0" } }, + "opentracing": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.7.tgz", + "integrity": "sha512-vz9iS7MJ5+Bp1URw8Khvdyw1H/hGvzHWlKQ7eRrQojSCDL1/SrWfrY9QebLw97n2deyRtzHRC3MkQfVNUCo91Q==" + }, "optional-js": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/optional-js/-/optional-js-2.3.0.tgz", @@ -19008,6 +20001,11 @@ } } }, + "process": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/process/-/process-0.10.1.tgz", + "integrity": "sha512-dyIett8dgGIZ/TXKUzeYExt7WA6ldDzys9vTDU/cCA9L17Ypme+KzS+NjQCjpn9xsvi/shbMC+yP/BcFMBz0NA==" + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -19028,6 +20026,25 @@ "sisteransi": "^1.0.5" } }, + "protobufjs": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz", + "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + } + }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -19210,8 +20227,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" }, "require-from-string": { "version": "2.0.2", @@ -19515,6 +20531,11 @@ "rechoir": "^0.6.2" } }, + "shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + }, "side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -19682,6 +20703,11 @@ "resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-4.0.4.tgz", "integrity": "sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==" }, + "string-template": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", + "integrity": "sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==" + }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -19945,6 +20971,23 @@ "real-require": "^0.2.0" } }, + "thriftrw": { + "version": "3.11.4", + "resolved": "https://registry.npmjs.org/thriftrw/-/thriftrw-3.11.4.tgz", + "integrity": "sha512-UcuBd3eanB3T10nXWRRMwfwoaC6VMk7qe3/5YIWP2Jtw+EbHqJ0p1/K3x8ixiR5dozKSSfcg1W+0e33G1Di3XA==", + "requires": { + "bufrw": "^1.2.1", + "error": "7.0.2", + "long": "^2.4.0" + }, + "dependencies": { + "long": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/long/-/long-2.4.0.tgz", + "integrity": "sha512-ijUtjmO/n2A5PaosNG9ZGDsQ3vxJg7ZW8vsY8Kp0f2yIZWhSJvjmegV7t+9RPQKxKrvj8yKGehhS+po14hPLGQ==" + } + } + }, "throat": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", @@ -20523,7 +21566,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -20566,6 +21608,11 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, + "xorshift": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/xorshift/-/xorshift-1.2.0.tgz", + "integrity": "sha512-iYgNnGyeeJ4t6U11NpA/QiKy+PXn5Aa3Azg5qkwIFz1tBLllQrjjsk9yzD7IAK0naNU4JxdeDgqW9ov4u/hc4g==" + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -20574,8 +21621,7 @@ "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" }, "yallist": { "version": "4.0.0", @@ -20614,8 +21660,7 @@ "yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" }, "yn": { "version": "3.1.1", diff --git a/package.json b/package.json index 8427a9a..1e85d7c 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,9 @@ "@nestjs/passport": "^9.0.0", "@nestjs/platform-express": "^9.4.0", "@nestjs/swagger": "^6.1.2", + "@opentelemetry/exporter-metrics-otlp-proto": "^0.44.0", + "@opentelemetry/exporter-trace-otlp-proto": "^0.44.0", + "@opentelemetry/sdk-node": "^0.44.0", "@topos-protocol/topos-smart-contracts": "^2.0.0", "bcrypt": "^5.1.0", "bull": "^4.10.1", diff --git a/src/apm/apm.module.ts b/src/apm/apm.module.ts deleted file mode 100644 index 29fba92..0000000 --- a/src/apm/apm.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common' -import { ConfigModule } from '@nestjs/config' - -import { ApmService } from './apm.service' - -@Module({ - imports: [ConfigModule], - exports: [ApmService], - providers: [ApmService], -}) -export class ApmModule {} diff --git a/src/apm/apm.service.ts b/src/apm/apm.service.ts deleted file mode 100644 index 8ebe249..0000000 --- a/src/apm/apm.service.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Injectable } from '@nestjs/common' -import { ConfigService } from '@nestjs/config' -import * as ElasticAPM from 'elastic-apm-node' - -export const SERVICE_NAME = - process.env.TRACING_SERVICE_NAME || 'executor-service' -export const SERVICE_VERSION = process.env.TRACING_SERVICE_VERSION || 'unknown' -export const ELASTIC_APM_ENDPOINT = process.env.ELASTIC_APM_ENDPOINT || '' -export const ELASTIC_APM_TOKEN = process.env.ELASTIC_APM_TOKEN || '' - -@Injectable() -export class ApmService { - private _apm: ElasticAPM.Agent - - constructor(private configService: ConfigService) { - this._apm = ElasticAPM.start({ - serviceName: - this.configService.get('TRACING_SERVICE_NAME') || 'executor-service', - secretToken: this.configService.get('ELASTIC_APM_TOKEN') || '', - serverUrl: this.configService.get('ELASTIC_APM_ENDPOINT') || '', - environment: this.configService.get('SERVICE_VERSION') || 'unknown', - opentelemetryBridgeEnabled: true, - captureBody: 'all', - }) - } - - startTransaction(name: string, traceparent?: string) { - return this._apm.startTransaction( - name, - traceparent - ? { - childOf: traceparent, - } - : undefined - ) - } - - captureError(error: string) { - this._apm.captureError(error) - } -} diff --git a/src/app.module.ts b/src/app.module.ts index 484d786..ff64432 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -2,10 +2,12 @@ import { Module } from '@nestjs/common' import { ConfigModule, ConfigService } from '@nestjs/config' import { BullModule } from '@nestjs/bull' +import { TelemetryModule } from './telemetry/telemetry.module' import { ExecuteModuleV1 } from './execute/execute.module' @Module({ imports: [ + TelemetryModule, ConfigModule.forRoot(), BullModule.forRootAsync({ imports: [ConfigModule], diff --git a/src/execute/execute.controller.spec.ts b/src/execute/execute.controller.spec.ts index 62e1068..81a69ec 100644 --- a/src/execute/execute.controller.spec.ts +++ b/src/execute/execute.controller.spec.ts @@ -1,10 +1,10 @@ import { Test, TestingModule } from '@nestjs/testing' +import { Observable } from 'rxjs' import { ExecuteControllerV1 } from './execute.controller' import { ExecuteDto } from './execute.dto' import { QUEUE_ERRORS } from './execute.errors' import { ExecuteServiceV1 } from './execute.service' -import { Observable } from 'rxjs' const validExecuteDto: ExecuteDto = { logIndexes: [], @@ -28,7 +28,7 @@ describe('ExecuteController', () => { return { execute: jest.fn().mockResolvedValue({}), getJobById: jest.fn().mockResolvedValue({}), - subscribeToJobById: jest.fn().mockResolvedValue({}), + subscribeToJobById: jest.fn().mockReturnValue({ pipe: jest.fn() }), } } }) diff --git a/src/execute/execute.controller.ts b/src/execute/execute.controller.ts index 3c90245..710bdd2 100644 --- a/src/execute/execute.controller.ts +++ b/src/execute/execute.controller.ts @@ -1,5 +1,4 @@ import { - BadRequestException, Body, Controller, Get, @@ -10,13 +9,31 @@ import { UseGuards, } from '@nestjs/common' import { ApiBearerAuth, ApiParam, ApiTags } from '@nestjs/swagger' +import { + context, + metrics, + propagation, + SpanStatusCode, + trace, +} from '@opentelemetry/api' +import { tap } from 'rxjs' +import { JwtAuthGuard } from '../auth/jwt-auth.guard' +import { getErrorMessage } from '../utils' import { ExecuteDto } from './execute.dto' import { ExecuteServiceV1, TracingOptions } from './execute.service' -import { JwtAuthGuard } from '../auth/jwt-auth.guard' @Controller({ version: '1' }) export class ExecuteControllerV1 { + private _tracer = trace.getTracer('ExecuteController') + private _meter = metrics.getMeter('ExecuteController') + private _counterExecute = this._meter.createCounter( + 'execute_controller.execute.counter' + ) + private _counterGetJob = this._meter.createCounter('getJob.counter') + private _counterSubscribeToJob = this._meter.createCounter( + 'subscribeToJob.counter' + ) constructor(private executeService: ExecuteServiceV1) {} @ApiTags('execute') @@ -25,14 +42,35 @@ export class ExecuteControllerV1 { @UseGuards(JwtAuthGuard) async executeV1( @Body() executeDto: ExecuteDto, - @Headers('traceparent') traceparent?: string + // rootTracingOptions is optional and allows the job consumer work to be + // attached to a root trace, while the local tracing options can only be + // used for the work of adding the job to the queue + @Headers('rootTraceparent') rootTraceparent?: string, + @Headers('rootTracestate') rootTracestate?: string, + @Headers('traceparent') traceparent?: string, + @Headers('tracestate') tracestate?: string ) { - const args: [ExecuteDto, TracingOptions?] = [executeDto] - if (traceparent) { - args.push({ traceparent }) + this._counterExecute.add(1) + + const activeContext = propagation.extract(context.active(), { + traceparent, + tracestate, + }) + + const rootTracingOptions: TracingOptions = { + traceparent: rootTraceparent, + tracestate: rootTracestate, } - return this.executeService.execute(...args).catch((error) => { - throw new BadRequestException(error.message) + + return context.with(activeContext, async () => { + return this._tracer.startActiveSpan('execute', async (span) => { + const job = await this.executeService.execute( + executeDto, + rootTracingOptions + ) + span.end() + return job + }) }) } @@ -42,6 +80,7 @@ export class ExecuteControllerV1 { @UseGuards(JwtAuthGuard) @ApiParam({ name: 'jobId' }) async getJob(@Param('jobId') jobId: string) { + this._counterGetJob.add(1) return this.executeService.getJobById(jobId) } @@ -52,12 +91,36 @@ export class ExecuteControllerV1 { @ApiParam({ name: 'jobId' }) async subscribeToJob( @Param('jobId') jobId: string, - @Headers('traceparent') traceparent?: string + @Headers('traceparent') traceparent?: string, + @Headers('tracestate') tracestate?: string ) { - const args: [string, TracingOptions?] = [jobId] - if (traceparent) { - args.push({ traceparent }) - } - return this.executeService.subscribeToJobById(...args) + this._counterSubscribeToJob.add(1) + + const activeContext = propagation.extract(context.active(), { + traceparent, + tracestate, + }) + + return context.with(activeContext, async () => { + return this._tracer.startActiveSpan('subscribeToJob', async (span) => { + const observable = this.executeService.subscribeToJobById(jobId) + return observable.pipe( + tap({ + error: (error) => { + const message = getErrorMessage(error) + span.setStatus({ + code: SpanStatusCode.ERROR, + message, + }) + span.end() + }, + complete: () => { + span.setStatus({ code: SpanStatusCode.OK }) + span.end() + }, + }) + ) + }) + }) } } diff --git a/src/execute/execute.module.ts b/src/execute/execute.module.ts index 2f348ab..bf08ebb 100644 --- a/src/execute/execute.module.ts +++ b/src/execute/execute.module.ts @@ -2,7 +2,6 @@ import { BullModule } from '@nestjs/bull' import { Module } from '@nestjs/common' import { ConfigService } from '@nestjs/config' -import { ApmModule } from '../apm/apm.module' import { AuthModule } from '../auth/auth.module' import { ExecuteControllerV1 } from './execute.controller' import { ExecutionProcessorV1 } from './execute.processor' @@ -10,7 +9,7 @@ import { ExecuteServiceV1 } from './execute.service' @Module({ controllers: [ExecuteControllerV1], - imports: [BullModule.registerQueue({ name: 'execute' }), ApmModule, AuthModule], + imports: [BullModule.registerQueue({ name: 'execute' }), AuthModule], providers: [ExecutionProcessorV1, ExecuteServiceV1, ConfigService], }) export class ExecuteModuleV1 {} diff --git a/src/execute/execute.processor.spec.ts b/src/execute/execute.processor.spec.ts index 1e638a8..30e4a8e 100644 --- a/src/execute/execute.processor.spec.ts +++ b/src/execute/execute.processor.spec.ts @@ -4,7 +4,6 @@ import { Job } from 'bull' import { ethers } from 'ethers' import { EventEmitter } from 'stream' -import { ApmService } from '../apm/apm.service' import { ExecuteDto } from './execute.dto' import { ExecutionProcessorV1 } from './execute.processor' import { TracingOptions } from './execute.service' @@ -15,15 +14,21 @@ const TOPOS_CORE_PROXY_CONTRACT_ADDRESS = '0x1D7b9f9b1FF6cf0A3BEB0F84fA6F8628E540E97F' const TOPOS_SUBNET_ENDPOINT_WS = 'ws://topos-subnet-endpoint/ws' -const validExecuteJob: Partial> = { +const validExecuteJob: Partial< + Job +> = { data: { logIndexes: [], messagingContractAddress: '', receiptTrieRoot: '', receiptTrieMerkleProof: '', subnetId: 'id', - traceparent: '', + tracingOptions: { + traceparent: '', + tracestate: '', + }, }, + moveToFailed: jest.fn(), progress: jest.fn(), } @@ -37,7 +42,7 @@ const contractMock = { execute: jest.fn().mockResolvedValue(transactionMock), networkSubnetId: jest.fn().mockResolvedValue(''), subnets: jest.fn().mockResolvedValue(subnetMock), - txRootToCertId: jest.fn().mockResolvedValue(''), + receiptRootToCertId: jest.fn().mockResolvedValue(''), } describe('ExecuteProcessor', () => { @@ -50,8 +55,9 @@ describe('ExecuteProcessor', () => { }) .useMocker((token) => { if (token === ConfigService) { - return { - get: jest.fn().mockImplementation((key: string) => { + const configGetterMock = jest + .fn() + .mockImplementation((key: string) => { switch (key) { case 'PRIVATE_KEY': return VALID_PRIVATE_KEY @@ -60,19 +66,10 @@ describe('ExecuteProcessor', () => { case 'TOPOS_SUBNET_ENDPOINT_WS': return TOPOS_SUBNET_ENDPOINT_WS } - }), - } - } - - if (token === ApmService) { + }) return { - captureError: jest.fn(), - startTransaction: jest.fn().mockReturnValue({ - end: jest.fn(), - startSpan: jest - .fn() - .mockReturnValue({ addLabels: jest.fn(), end: jest.fn() }), - }), + get: configGetterMock, + getOrThrow: configGetterMock, } } }) @@ -94,7 +91,9 @@ describe('ExecuteProcessor', () => { jest.spyOn(ethers, 'Contract').mockReturnValue(contractMock) await executeProcessor.execute( - validExecuteJob as unknown as Job + validExecuteJob as unknown as Job< + ExecuteDto & { tracingOptions: TracingOptions } + > ) expect(ethersProviderMock).toHaveBeenCalledWith(TOPOS_SUBNET_ENDPOINT_WS) @@ -104,7 +103,7 @@ describe('ExecuteProcessor', () => { providerMock ) - expect(contractMock.txRootToCertId).toHaveBeenCalled() + expect(contractMock.receiptRootToCertId).toHaveBeenCalled() expect(validExecuteJob.progress).toHaveBeenCalledWith(50) diff --git a/src/execute/execute.processor.ts b/src/execute/execute.processor.ts index 01b4d6e..3a68aa0 100644 --- a/src/execute/execute.processor.ts +++ b/src/execute/execute.processor.ts @@ -11,6 +11,13 @@ import { } from '@nestjs/bull' import { Logger } from '@nestjs/common' import { ConfigService } from '@nestjs/config' +import { + context, + metrics, + propagation, + SpanStatusCode, + trace, +} from '@opentelemetry/api' import * as ToposCoreJSON from '@topos-protocol/topos-smart-contracts/artifacts/contracts/topos-core/ToposCore.sol/ToposCore.json' import * as ToposMessagingJSON from '@topos-protocol/topos-smart-contracts/artifacts/contracts/topos-core/ToposMessaging.sol/ToposMessaging.json' import * as SubnetRegistratorJSON from '@topos-protocol/topos-smart-contracts/artifacts/contracts/topos-core/SubnetRegistrator.sol/SubnetRegistrator.json' @@ -20,9 +27,9 @@ import { ToposMessaging, } from '@topos-protocol/topos-smart-contracts/typechain-types/contracts/topos-core' import { Job } from 'bull' -import { ethers, providers } from 'ethers' +import { Contract, ethers, providers } from 'ethers' -import { ApmService } from '../apm/apm.service' +import { getErrorMessage } from '../utils' import { ExecuteDto } from './execute.dto' import { CONTRACT_ERRORS, @@ -37,100 +44,115 @@ const UNDEFINED_CERTIFICATE_ID = @Processor('execute') export class ExecutionProcessorV1 { + private _tracer = trace.getTracer('ExecuteProcessor') + private _meter = metrics.getMeter('ExecuteProcessor') + private _counterExecute = this._meter.createCounter( + 'execute_processor.execute.counter' + ) private readonly logger = new Logger(ExecutionProcessorV1.name) - constructor( - private configService: ConfigService, - private apmService: ApmService - ) {} + constructor(private configService: ConfigService) {} @Process('execute') - async execute(job: Job) { - const { - logIndexes, - messagingContractAddress, - receiptTrieMerkleProof, - receiptTrieRoot, - subnetId, - traceparent, - } = job.data - - const apmTransaction = this.apmService.startTransaction( - 'root-processor', - traceparent - ) - const executeSpan = apmTransaction.startSpan(`execute`) - executeSpan.addLabels({ data: JSON.stringify(job.data) }) - - const toposCoreProxyContractAddress = this.configService.get( - 'TOPOS_CORE_PROXY_CONTRACT_ADDRESS' + async execute(job: Job) { + const activeContext = propagation.extract( + context.active(), + job.data.tracingOptions ) - executeSpan.addLabels({ toposCoreProxyContractAddress }) - - const receivingSubnetEndpoint = - await this._getReceivingSubnetEndpointFromId(subnetId) - executeSpan.addLabels({ receivingSubnetEndpoint }) - - const provider = await this._createProvider(receivingSubnetEndpoint) - this.logger.debug(`ReceivingSubnet: ${receivingSubnetEndpoint}`) - executeSpan.addLabels({ provider: JSON.stringify(provider) }) - - const wallet = this._createWallet(provider) - - const toposCoreContract = (await this._getContract( - provider, - toposCoreProxyContractAddress, - ToposCoreJSON.abi, - wallet - )) as ToposCore - - const messagingContract = (await this._getContract( - provider, - messagingContractAddress, - ToposMessagingJSON.abi, - wallet - )) as ToposMessaging - - this.logger.debug(`Trie root: ${receiptTrieRoot}`) - - let certId = UNDEFINED_CERTIFICATE_ID - let i = 1 - - while (certId == UNDEFINED_CERTIFICATE_ID && i < 40) { - this.logger.debug(`Waiting for cert to be imported (${i})`) - certId = await toposCoreContract.receiptRootToCertId(receiptTrieRoot) - this.logger.debug(`Cert id: ${certId}`) - await new Promise((r) => setTimeout(r, 1000)) - i++ - } - - if (certId == UNDEFINED_CERTIFICATE_ID) { - await job.moveToFailed({ message: JOB_ERRORS.MISSING_CERTIFICATE }) - this.apmService.captureError(JOB_ERRORS.MISSING_CERTIFICATE) - return - } - - executeSpan.addLabels({ certId }) - await job.progress(50) - - const tx = await messagingContract.execute( - logIndexes, - receiptTrieMerkleProof, - receiptTrieRoot, - { - gasLimit: 4_000_000, - } - ) - - executeSpan.addLabels({ tx: JSON.stringify(tx) }) - - return tx.wait().then(async (receipt) => { - executeSpan.addLabels({ receipt: JSON.stringify(receipt) }) - executeSpan.end() - apmTransaction.end() - await job.progress(100) - return receipt + return context.with(activeContext, async () => { + return this._tracer.startActiveSpan('execute', async (span) => { + try { + this._counterExecute.add(1) + const { + logIndexes, + messagingContractAddress, + receiptTrieMerkleProof, + receiptTrieRoot, + subnetId, + } = job.data + + span.setAttribute('data', JSON.stringify(job.data)) + + const toposCoreProxyContractAddress = this.configService.get( + 'TOPOS_CORE_PROXY_CONTRACT_ADDRESS' + ) + span.setAttribute( + 'toposCoreProxyContractAddress', + toposCoreProxyContractAddress + ) + + const receivingSubnetEndpoint = + await this._getReceivingSubnetEndpointFromId(subnetId) + span.addEvent('got receiving subnet endpoint from id', { + subnetId, + receivingSubnetEndpoint, + }) + + const provider = await this._createProvider(receivingSubnetEndpoint) + this.logger.debug(`ReceivingSubnet: ${receivingSubnetEndpoint}`) + span.addEvent('got provider', { + provider: JSON.stringify(provider), + }) + + const wallet = this._createWallet(provider) + + const toposCoreContract = (await this._getContract( + provider, + toposCoreProxyContractAddress, + ToposCoreJSON.abi, + wallet + )) as ToposCore + + const messagingContract = (await this._getContract( + provider, + messagingContractAddress, + ToposMessagingJSON.abi, + wallet + )) as ToposMessaging + + this.logger.debug(`Trie root: ${receiptTrieRoot}`) + + const certId = await this._findMatchingCertificate( + toposCoreContract, + receiptTrieRoot + ) + span.addEvent('got matching certificate id', { certId }) + + await job.progress(50) + + const tx = await messagingContract.execute( + logIndexes, + receiptTrieMerkleProof, + receiptTrieRoot, + { + gasLimit: 4_000_000, + } + ) + span.addEvent('got execute tx', { + tx: JSON.stringify(tx), + }) + + const receipt = await tx.wait() + span.addEvent('got execute tx receipt', { + receipt: JSON.stringify(receipt), + }) + + job.progress(100) + span.setStatus({ code: SpanStatusCode.OK }) + span.end() + return receipt + } catch (error) { + const message = getErrorMessage(error) + span.setStatus({ + code: SpanStatusCode.ERROR, + message, + }) + span.end() + this.logger.debug('sync error', error) + await job.moveToFailed({ message }) + } + }) }) } @@ -195,14 +217,8 @@ export class ExecutionProcessorV1 { private _createWallet( provider: providers.WebSocketProvider | providers.JsonRpcProvider ) { - try { - return new ethers.Wallet( - this.configService.get('PRIVATE_KEY'), - provider - ) - } catch (error) { - throw new Error(WALLET_ERRORS.INVALID_PRIVATE_KEY) - } + const privateKey = this.configService.getOrThrow('PRIVATE_KEY') + return new ethers.Wallet(privateKey, provider) } private async _getContract( @@ -228,6 +244,29 @@ export class ExecutionProcessorV1 { } } + private async _findMatchingCertificate( + toposCoreContract: ToposCore, + receiptTrieRoot: string + ) { + let certId = UNDEFINED_CERTIFICATE_ID + let i = 1 + const maxTries = 40 + + while (certId == UNDEFINED_CERTIFICATE_ID && i < maxTries) { + this.logger.debug(`Waiting for cert to be imported (${i})`) + certId = await toposCoreContract.receiptRootToCertId(receiptTrieRoot) + this.logger.debug(`Cert id: ${certId}`) + await new Promise((r) => setTimeout(r, 1000)) + i++ + } + + if (certId == UNDEFINED_CERTIFICATE_ID) { + throw new Error(JOB_ERRORS.MISSING_CERTIFICATE) + } + + return certId + } + @OnGlobalQueueError() onGlobalQueueError(error: Error) { this.logger.error(error) diff --git a/src/execute/execute.service.spec.ts b/src/execute/execute.service.spec.ts index 46815cf..d2f7347 100644 --- a/src/execute/execute.service.spec.ts +++ b/src/execute/execute.service.spec.ts @@ -4,7 +4,6 @@ import { Test, TestingModule } from '@nestjs/testing' import { Job } from 'bull' import { first, firstValueFrom, lastValueFrom } from 'rxjs' -import { ApmService } from '../apm/apm.service' import { ExecuteDto } from './execute.dto' import { ExecuteServiceV1, TracingOptions } from './execute.service' @@ -18,6 +17,7 @@ const validExecuteDto: ExecuteDto = { const validTracingOptions: TracingOptions = { traceparent: '', + tracestate: '', } const VALID_PRIVATE_KEY = @@ -67,18 +67,6 @@ describe('ExecuteService', () => { }), } } - - if (token === ApmService) { - return { - captureError: jest.fn(), - startTransaction: jest.fn().mockReturnValue({ - end: jest.fn(), - startSpan: jest - .fn() - .mockReturnValue({ addLabels: jest.fn(), end: jest.fn() }), - }), - } - } }) .overrideProvider(getQueueToken('execute')) .useValue(executeQueueMock) @@ -93,7 +81,7 @@ describe('ExecuteService', () => { expect(executeQueueMock.add).toHaveBeenCalledWith('execute', { ...validExecuteDto, - ...validTracingOptions, + tracingOptions: validTracingOptions, }) }) }) @@ -112,7 +100,7 @@ describe('ExecuteService', () => { it('should retrieve the correct job', () => { const jobId = '1' executeService - .subscribeToJobById(jobId, validTracingOptions) + .subscribeToJobById(jobId) .pipe(first()) .subscribe(() => { expect(executeQueueMock.getJob).toHaveBeenCalledWith(jobId) @@ -123,9 +111,7 @@ describe('ExecuteService', () => { it('should first next some progress', async () => { const jobId = '1' await expect( - firstValueFrom( - executeService.subscribeToJobById(jobId, validTracingOptions) - ) + firstValueFrom(executeService.subscribeToJobById(jobId)) ).resolves.toStrictEqual({ data: { payload: '', type: 'progress' }, }) @@ -134,9 +120,7 @@ describe('ExecuteService', () => { it('should then complete', async () => { const jobId = '1' await expect( - lastValueFrom( - executeService.subscribeToJobById(jobId, validTracingOptions) - ) + lastValueFrom(executeService.subscribeToJobById(jobId)) ).resolves.toStrictEqual({ data: { payload: {}, type: 'completed' }, }) @@ -158,9 +142,7 @@ describe('ExecuteService', () => { ) await expect( - lastValueFrom( - executeService.subscribeToJobById(jobId, validTracingOptions) - ) + lastValueFrom(executeService.subscribeToJobById(jobId)) ).rejects.toStrictEqual('errorMock') }) }) diff --git a/src/execute/execute.service.ts b/src/execute/execute.service.ts index efb7be8..d3c09f0 100644 --- a/src/execute/execute.service.ts +++ b/src/execute/execute.service.ts @@ -1,126 +1,151 @@ import { InjectQueue } from '@nestjs/bull' import { Injectable, Logger, MessageEvent } from '@nestjs/common' import { ConfigService } from '@nestjs/config' +import { context, propagation, SpanStatusCode, trace } from '@opentelemetry/api' import { Queue } from 'bull' import { ethers } from 'ethers' import { Observable } from 'rxjs' -import { ApmService } from '../apm/apm.service' import { ExecuteDto } from './execute.dto' import { QUEUE_ERRORS, WALLET_ERRORS } from './execute.errors' +import { getErrorMessage } from '../utils' export interface TracingOptions { - traceparent?: string + traceparent: string + tracestate: string } @Injectable() export class ExecuteServiceV1 { + private _tracer = trace.getTracer('ExecuteService') private readonly logger = new Logger(ExecuteServiceV1.name) constructor( private configService: ConfigService, - private apmService: ApmService, @InjectQueue('execute') private readonly executionQueue: Queue ) { this._verifyPrivateKey() this._verifyRedisAvailability() } - async execute(executeDto: ExecuteDto, tracingOptions: TracingOptions) { - const traceparent = tracingOptions?.traceparent - - const apmTransaction = this.apmService.startTransaction( - 'root-execute', - traceparent - ) - const span = apmTransaction.startSpan(`add-execution-job`) - - const { id, timestamp, ...rest } = await this._addExecutionJob(executeDto, { - traceparent, + async execute(executeDto: ExecuteDto, rootTracingOptions?: TracingOptions) { + // rootTracingOptions is optional and allows the job consumer work to be + // attached to a root trace, while the local tracing options can only be + // used for the work of adding the job to the queue + return this._tracer.startActiveSpan('execute', (span) => { + this.logger.debug(rootTracingOptions) + + return this._addExecutionJob(executeDto, rootTracingOptions) + .then(({ id, timestamp }) => { + span.setStatus({ code: SpanStatusCode.OK }) + return { id, timestamp } + }) + .catch((error) => { + const message = getErrorMessage(error) + span.setStatus({ + code: SpanStatusCode.ERROR, + message, + }) + }) + .finally(() => { + span.end() + }) }) - span.addLabels({ id, timestamp }) - - span.end() - apmTransaction.end() - return { id, timestamp } } async getJobById(jobId: string) { - const job = await this.executionQueue.getJob(jobId) + return this._tracer.startActiveSpan('getJobById', async (span) => { + const job = await this.executionQueue.getJob(jobId) - if (!job) { - const failedJob = (await this.executionQueue.getFailed()).find( - (j) => j.id === jobId - ) + if (!job) { + const failedJob = (await this.executionQueue.getFailed()).find( + (j) => j.id === jobId + ) - if (!failedJob) { - throw new Error(QUEUE_ERRORS.JOB_NOT_FOUND) - } + if (!failedJob) { + span.setStatus({ + code: SpanStatusCode.ERROR, + message: QUEUE_ERRORS.JOB_NOT_FOUND, + }) + span.end() + throw new Error(QUEUE_ERRORS.JOB_NOT_FOUND) + } - return failedJob - } + span.setStatus({ + code: SpanStatusCode.ERROR, + message: failedJob.failedReason, + }) + span.end() + return failedJob + } - return job + span.setAttribute('job', JSON.stringify(job)) + span.setStatus({ code: SpanStatusCode.OK }) + span.end() + return job + }) } - subscribeToJobById(jobId: string, tracingOptions: TracingOptions) { - return new Observable((subscriber) => { - const traceparent = tracingOptions?.traceparent - const apmTransaction = this.apmService.startTransaction( - 'root-subscribe', - traceparent - ) - const span = apmTransaction.startSpan(`subscribe-to-job`) - span.addLabels({ jobId }) - - this.getJobById(jobId) - .then((job) => { - const progressListener = (job, progress) => { - if (job.id === jobId) { - this.logger.debug(`Job progress: ${progress}`) - subscriber.next({ data: { payload: progress, type: 'progress' } }) - } - } - - this.executionQueue.on('progress', progressListener) - job - .finished() - .then((payload) => { - this.logger.debug(`Job completed!`) - this.executionQueue.removeListener('progress', progressListener) - subscriber.next({ data: { payload, type: 'completed' } }) - subscriber.complete() + subscribeToJobById(jobId: string) { + return this._tracer.startActiveSpan('subscribeToJobById', (span) => { + return new Observable((subscriber) => { + span.setAttribute('jobId', jobId) + + context.with(trace.setSpan(context.active(), span), async () => { + this.getJobById(jobId) + .then((job) => { + const progressListener = (job, progress) => { + if (job.id === jobId) { + this.logger.debug(`Job progress: ${progress}`) + span.addEvent('got progress update', { progress }) + subscriber.next({ + data: { payload: progress, type: 'progress' }, + }) + } + } + + this.executionQueue.on('progress', progressListener) + job + .finished() + .then((payload) => { + this.logger.debug(`Job completed!`) + this.executionQueue.removeListener( + 'progress', + progressListener + ) + span.setStatus({ code: SpanStatusCode.OK }) + subscriber.next({ data: { payload, type: 'completed' } }) + subscriber.complete() + }) + .catch((error) => { + this.logger.debug(`Job failed!`) + this.logger.debug(error) + span.setStatus({ code: SpanStatusCode.ERROR, message: error }) + subscriber.error(error) + subscriber.complete() + }) + .finally(() => { + span.end() + }) }) .catch((error) => { - this.apmService.captureError(error) - this.logger.debug(`Job failed!`) + this.logger.debug(`Job not found!`) this.logger.debug(error) + span.setStatus({ code: SpanStatusCode.ERROR, message: error }) + span.end() subscriber.error(error) subscriber.complete() }) - .finally(() => { - span.end() - }) - }) - .catch((error) => { - this.apmService.captureError(error) - this.logger.debug(`Job not found!`) - this.logger.debug(error) - subscriber.error(error) - subscriber.complete() }) + }) }) } private async _addExecutionJob( executeDto: ExecuteDto, - { traceparent }: TracingOptions + tracingOptions?: TracingOptions ) { - try { - return this.executionQueue.add('execute', { ...executeDto, traceparent }) - } catch (error) { - this.logger.error(error) - } + return this.executionQueue.add('execute', { ...executeDto, tracingOptions }) } private _verifyPrivateKey() { diff --git a/src/telemetry/telemetry.module.ts b/src/telemetry/telemetry.module.ts new file mode 100644 index 0000000..2d443c0 --- /dev/null +++ b/src/telemetry/telemetry.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common' + +import { TelemetryService } from './telemetry.service' + +@Module({ + exports: [TelemetryService], + providers: [TelemetryService], +}) +export class TelemetryModule {} diff --git a/src/telemetry/telemetry.service.ts b/src/telemetry/telemetry.service.ts new file mode 100644 index 0000000..ccfbad6 --- /dev/null +++ b/src/telemetry/telemetry.service.ts @@ -0,0 +1,49 @@ +import { Injectable } from '@nestjs/common' + +// Uncomment to get otlp logs +// import { +// diag, +// DiagConsoleLogger, +// DiagLogLevel, +// metrics, +// } from '@opentelemetry/api' +import { NodeSDK } from '@opentelemetry/sdk-node' +import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto' +import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-proto' +import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics' + +const OTEL_EXPORTER_OTLP_ENDPOINT = + process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318' + +@Injectable() +export class TelemetryService { + constructor() { + // Uncomment to get otlp logs + // diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG) + + const otelSDK = new NodeSDK({ + traceExporter: new OTLPTraceExporter({ + url: `${OTEL_EXPORTER_OTLP_ENDPOINT}/v1/traces`, + }), + metricReader: new PeriodicExportingMetricReader({ + exporter: new OTLPMetricExporter({ + url: `${OTEL_EXPORTER_OTLP_ENDPOINT}/v1/metrics`, + }), + }), + instrumentations: [], + }) + + otelSDK.start() + + // gracefully shut down the SDK on process exit + process.on('SIGTERM', () => { + otelSDK + .shutdown() + .then( + () => console.log('SDK shut down successfully'), + (err) => console.log('Error shutting down SDK', err) + ) + .finally(() => process.exit(0)) + }) + } +} diff --git a/src/utils/index.ts b/src/utils/index.ts index e69de29..6c9efe5 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -0,0 +1,3 @@ +export function getErrorMessage(error: unknown) { + return error instanceof Error ? error.message : String(error) +} diff --git a/test/execute.e2e-spec.ts b/test/execute.e2e-spec.ts index 8a209ad..2c67b1a 100644 --- a/test/execute.e2e-spec.ts +++ b/test/execute.e2e-spec.ts @@ -3,7 +3,6 @@ import { Test } from '@nestjs/testing' import { INestApplication, ValidationPipe } from '@nestjs/common' import { AppModule } from '../src/app.module' -import { ApmService } from '../src/apm/apm.service' import { JwtAuthGuard } from '../src/auth/jwt-auth.guard' import { ExecuteDto } from '../src/execute/execute.dto' import { ExecuteServiceV1 } from '../src/execute/execute.service' @@ -19,14 +18,11 @@ const validExecuteDto: ExecuteDto = { describe('Execute with ❌ auth (e2e)', () => { let app: INestApplication let authGuard = { canActivate: jest.fn().mockReturnValue(false) } - let apmService = {} beforeAll(async () => { const moduleFixture = await Test.createTestingModule({ imports: [AppModule], }) - .overrideProvider(ApmService) - .useValue(apmService) .overrideGuard(JwtAuthGuard) .useValue(authGuard) .compile()