Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions controlplane/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@
"@graphql-tools/utils": "^10.1.2",
"@keycloak/keycloak-admin-client": "26.2.5",
"@octokit/webhooks-types": "^7.6.1",
"@sentry/node": "^10.11.0",
"@sentry/node-native": "^10.11.0",
"@sentry/profiling-node": "^10.11.0",
"@sentry/node": "^10.19.0",
"@sentry/node-native": "^10.19.0",
"@sentry/profiling-node": "^10.19.0",
"@tiptap/core": "^2.1.13",
"@wundergraph/composition": "workspace:*",
"@wundergraph/cosmo-connect": "workspace:*",
Expand Down
5 changes: 5 additions & 0 deletions controlplane/src/core/env.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,11 @@ export const envVariables = z
SENTRY_PROFILE_SESSION_SAMPLE_RATE: z.coerce.number().optional().default(1),
SENTRY_PROFILE_LIFECYCLE: z.enum(['manual', 'trace']).optional().default('manual'),
SENTRY_EVENT_LOOP_BLOCK_THRESHOLD_MS: z.coerce.number().optional().default(100),
SENTRY_ENABLE_LOGS: z
.string()
.optional()
.transform((val) => val === 'true')
.default('false'),
})
.refine((input) => {
if (input.STRIPE_WEBHOOK_SECRET && !input.STRIPE_SECRET_KEY) {
Expand Down
57 changes: 28 additions & 29 deletions controlplane/src/core/sentry.config.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
// sentry.config.ts
import * as Sentry from '@sentry/node';

import { nodeProfilingIntegration } from '@sentry/profiling-node';
import { eventLoopBlockIntegration } from '@sentry/node-native';
import { fastifyIntegration } from '@sentry/node';
import { fastifyIntegration, pinoIntegration } from '@sentry/node';
import { envVariables } from "./env.schema.js";

export interface SentryConfig {
sentry: {
enabled: boolean;
dsn: string;
eventLoopBlockIntegrationThresholdMs?: number;
profileSessionSampleRate?: number;
profileLifecycle?: 'manual' | 'trace';
sendDefaultPii?: boolean;
tracesSampleRate?: number;
};
}
const {
SENTRY_ENABLED,
SENTRY_DSN,
SENTRY_SEND_DEFAULT_PII,
SENTRY_TRACES_SAMPLE_RATE,
SENTRY_PROFILE_SESSION_SAMPLE_RATE,
SENTRY_PROFILE_LIFECYCLE,
SENTRY_EVENT_LOOP_BLOCK_THRESHOLD_MS,
SENTRY_ENABLE_LOGS
} = envVariables.parse(process.env);

export function init(opts: SentryConfig) {
if (opts.sentry.enabled) {
Sentry.init({
dsn: opts.sentry.dsn,
integrations: [
fastifyIntegration(),
eventLoopBlockIntegration({ threshold: opts.sentry.eventLoopBlockIntegrationThresholdMs }),
nodeProfilingIntegration(),
],
profileSessionSampleRate: opts.sentry.profileSessionSampleRate,
sendDefaultPii: opts.sentry.sendDefaultPii,
tracesSampleRate: opts.sentry.tracesSampleRate,
profileLifecycle: opts.sentry.profileLifecycle,
});
}
if (SENTRY_ENABLED && SENTRY_DSN) {
Sentry.init({
dsn: SENTRY_DSN,
integrations: [
fastifyIntegration(),
eventLoopBlockIntegration({ threshold: SENTRY_EVENT_LOOP_BLOCK_THRESHOLD_MS }),
nodeProfilingIntegration(),
pinoIntegration({ log: { levels: ['info', 'warn', 'error'] } }),
],
profileSessionSampleRate: SENTRY_PROFILE_SESSION_SAMPLE_RATE,
sendDefaultPii: SENTRY_SEND_DEFAULT_PII,
tracesSampleRate: SENTRY_TRACES_SAMPLE_RATE,
profileLifecycle: SENTRY_PROFILE_LIFECYCLE,
enableLogs: SENTRY_ENABLE_LOGS,
});
console.log('Sentry is initialized.');
}
31 changes: 5 additions & 26 deletions controlplane/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import './core/sentry.config.js';
import * as process from 'node:process';
import * as Sentry from '@sentry/node';
import pino from 'pino';

import 'dotenv/config';

import build, { BuildConfig } from './core/build-server.js';
import { envVariables } from './core/env.schema.js';
import { SentryConfig } from './core/sentry.config.js';

const {
LOG_LEVEL,
Expand Down Expand Up @@ -70,11 +71,6 @@ const {
CDN_BASE_URL,
SENTRY_ENABLED,
SENTRY_DSN,
SENTRY_SEND_DEFAULT_PII,
SENTRY_TRACES_SAMPLE_RATE,
SENTRY_PROFILE_SESSION_SAMPLE_RATE,
SENTRY_PROFILE_LIFECYCLE,
SENTRY_EVENT_LOOP_BLOCK_THRESHOLD_MS,
} = envVariables.parse(process.env);

const options: BuildConfig = {
Expand Down Expand Up @@ -180,27 +176,10 @@ if (STRIPE_SECRET_KEY) {
};
}

if (SENTRY_ENABLED) {
if (SENTRY_DSN) {
const sentryConfig: SentryConfig = {
sentry: {
enabled: SENTRY_ENABLED,
dsn: SENTRY_DSN,
eventLoopBlockIntegrationThresholdMs: SENTRY_EVENT_LOOP_BLOCK_THRESHOLD_MS,
profileSessionSampleRate: SENTRY_PROFILE_SESSION_SAMPLE_RATE,
profileLifecycle: SENTRY_PROFILE_LIFECYCLE,
sendDefaultPii: SENTRY_SEND_DEFAULT_PII,
tracesSampleRate: SENTRY_TRACES_SAMPLE_RATE,
},
};
await import('./core/sentry.config.js').then((sentry) => sentry.init(sentryConfig));
} else {
throw new Error('SENTRY_ENABLED is set but SENTRY_DSN is not');
}
}

const app = await build(options);

if (SENTRY_ENABLED && SENTRY_DSN) {
Sentry.setupFastifyErrorHandler(app);
}
await app.listen({
host: HOST,
port: PORT,
Expand Down
Loading
Loading