diff --git a/config/custom-environment-variables.json b/config/custom-environment-variables.json index a99c296aed3..6d1b3a91e63 100644 --- a/config/custom-environment-variables.json +++ b/config/custom-environment-variables.json @@ -216,6 +216,7 @@ "sentry": { "dsn": "SENTRY_DSN", "tracesSampleRate": "SENTRY_TRACES_SAMPLE_RATE", + "profilesSampleRate": "SENTRY_PROFILES_SAMPLE_RATE", "minExecutionTimeToSample": "SENTRY_MIN_EXECUTION_TIME_TO_SAMPLE" }, "ledger": { diff --git a/config/default.json b/config/default.json index 2e720647bd2..cb726173765 100644 --- a/config/default.json +++ b/config/default.json @@ -209,6 +209,7 @@ }, "sentry": { "tracesSampleRate": 0, + "profilesSampleRate": 0, "minExecutionTimeToSample": 800 }, "ledger": { diff --git a/config/production.json b/config/production.json index 0e187f7cfa6..434d0bf1e2d 100644 --- a/config/production.json +++ b/config/production.json @@ -52,7 +52,8 @@ "fetchHostTransactionsCsv": true }, "sentry": { - "tracesSampleRate": 0.01 + "tracesSampleRate": 0.01, + "profilesSampleRate": 0.02 }, "graphql": { "cache": { diff --git a/config/staging.json b/config/staging.json index dfc78b7c89c..71c8e6f1351 100644 --- a/config/staging.json +++ b/config/staging.json @@ -37,7 +37,8 @@ "fetchTransactionsReceipts": true }, "sentry": { - "tracesSampleRate": 0.01 + "tracesSampleRate": 0.01, + "profilesSampleRate": 0.02 }, "restService": { "fetchCollectiveTransactionsCsv": true, diff --git a/package-lock.json b/package-lock.json index 0b5245fb27b..41062e6707c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "@peculiar/asn1-schema": "2.3.13", "@peculiar/asn1-x509": "2.3.13", "@sentry/node": "7.119.2", + "@sentry/profiling-node": "7.120.2", "@sentry/types": "7.119.2", "@shopify/address": "4.3.0", "@simplewebauthn/server": "11.0.0", @@ -6202,9 +6203,9 @@ } }, "node_modules/@opentelemetry/api": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.7.0.tgz", - "integrity": "sha512-AdY5wvN0P2vXBi3b29hxZgSFvdhdxPB9+f0B6s//P9Q8nibRWeA3cHm8UmLpio9ABigkVHJ5NMPk+Mz8VCCyrw==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", + "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "engines": { "node": ">=8.0.0" } @@ -10872,6 +10873,22 @@ "node": ">=8" } }, + "node_modules/@sentry/profiling-node": { + "version": "7.120.2", + "resolved": "https://registry.npmjs.org/@sentry/profiling-node/-/profiling-node-7.120.2.tgz", + "integrity": "sha512-dMnRYKrrVog3F4A9QFTB95zYTett2u5OjUmsRsJswR5r8tqC5Pg9KCiRYQdwFWm5llODt+Fx3ghlUQJcZBN6+w==", + "hasInstallScript": true, + "dependencies": { + "detect-libc": "^2.0.2", + "node-abi": "^3.61.0" + }, + "bin": { + "sentry-prune-profiler-binaries": "scripts/prune-profiler-binaries.js" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/@sentry/types": { "version": "7.119.2", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.119.2.tgz", @@ -18580,11 +18597,10 @@ } }, "node_modules/import-in-the-middle": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.11.0.tgz", - "integrity": "sha512-5DimNQGoe0pLUHbR9qK84iWaWjjbsxiqXnw6Qz64+azRgleqv9k2kTt5fw7QsOpmaGYtuxxursnPPsnTKEx10Q==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.12.0.tgz", + "integrity": "sha512-yAgSE7GmtRcu4ZUSFX/4v69UGXwugFFSdIQJ14LHPOPPQrWv8Y7O9PHsw8Ovk7bKCLe4sjXMbZFqGFcLHpZ89w==", "dev": true, - "license": "Apache-2.0", "dependencies": { "acorn": "^8.8.2", "acorn-import-attributes": "^1.9.5", @@ -21616,6 +21632,28 @@ "node": ">= 10.13" } }, + "node_modules/node-abi": { + "version": "3.71.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.71.0.tgz", + "integrity": "sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/node-abort-controller": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", diff --git a/package.json b/package.json index 5b0ce930f3a..3897c94764d 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "@peculiar/asn1-schema": "2.3.13", "@peculiar/asn1-x509": "2.3.13", "@sentry/node": "7.119.2", + "@sentry/profiling-node": "7.120.2", "@sentry/types": "7.119.2", "@shopify/address": "4.3.0", "@simplewebauthn/server": "11.0.0", diff --git a/server/lib/sentry.ts b/server/lib/sentry.ts index 9631ed8aaeb..8b4580d0ded 100644 --- a/server/lib/sentry.ts +++ b/server/lib/sentry.ts @@ -9,10 +9,11 @@ import '../env'; import { ApolloServerPlugin } from '@apollo/server'; import * as Sentry from '@sentry/node'; +import { nodeProfilingIntegration } from '@sentry/profiling-node'; import type { SeverityLevel } from '@sentry/types'; import axios, { AxiosError } from 'axios'; import config from 'config'; -import { cloneDeep, get, isEmpty, isEqual, pick } from 'lodash'; +import { cloneDeep, compact, get, isEmpty, isEqual, pick } from 'lodash'; import FEATURE from '../constants/feature'; import { User } from '../models'; @@ -22,6 +23,7 @@ import { safeJsonStringify, sanitizeObjectForJSON } from './safe-json-stringify' import * as utils from './utils'; const TRACES_SAMPLE_RATE = parseFloat(config.sentry.tracesSampleRate) || 0; +const PROFILES_SAMPLE_RATE = parseFloat(config.sentry.profilesSampleRate) || 0; const MIN_EXECUTION_TIME_TO_SAMPLE = parseInt(config.sentry.minExecutionTimeToSample); const checkIfSentryConfigured = () => Boolean(config.sentry?.dsn); @@ -64,6 +66,7 @@ Sentry.init({ }, dsn: config.sentry.dsn, environment: config.env, + integrations: compact([TRACES_SAMPLE_RATE > 0 && nodeProfilingIntegration()]), attachStacktrace: true, enabled: config.env !== 'test', tracesSampler: samplingContext => { @@ -75,10 +78,12 @@ Sentry.init({ return TRACES_SAMPLE_RATE; } }, + // Relative to tracesSampler + profilesSampleRate: PROFILES_SAMPLE_RATE, }); if (checkIfSentryConfigured()) { - logger.info('Initializing Sentry'); + logger.info(`Initializing Sentry in ${config.env} environment `); // Catch all errors that haven't been caught anywhere else process