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
8 changes: 8 additions & 0 deletions controlplane/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,11 @@ PROMETHEUS_ENABLED="false"
PROMETHEUS_HTTP_PATH="/metrics"
PROMETHEUS_PORT="8088"
PROMETHEUS_HOST="localhost"

# Sentry integration
SENTRY_ENABLED="false"
SENTRY_DSN=""
SENTRY_SEND_DEFAULT_PII="false"
Comment thread
miklosbarabas marked this conversation as resolved.
SENTRY_TRACES_SAMPLE_RATE="1.0"
SENTRY_PROFILE_SESSION_SAMPLE_RATE="1.0"
SENTRY_EVENT_LOOP_BLOCK_THRESHOLD_MS="100"
Comment thread
miklosbarabas marked this conversation as resolved.
5 changes: 4 additions & 1 deletion controlplane/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@
"@graphql-tools/utils": "^10.1.2",
"@keycloak/keycloak-admin-client": "^25.0.2",
"@octokit/webhooks-types": "^7.6.1",
"@sentry/node": "^10.11.0",
"@sentry/node-native": "^10.11.0",
"@sentry/profiling-node": "^10.11.0",
"@tiptap/core": "^2.1.13",
"@wundergraph/composition": "workspace:*",
"@wundergraph/cosmo-connect": "workspace:*",
Expand Down Expand Up @@ -116,4 +119,4 @@
"typescript": "5.5.2",
"vitest": "^3.2.4"
}
}
}
17 changes: 17 additions & 0 deletions controlplane/src/core/env.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,23 @@ export const envVariables = z
* Admission Webhook
*/
AUTH_ADMISSION_JWT_SECRET: z.string(),

/**
* Sentry
*/
SENTRY_ENABLED: z
.string()
.optional()
.transform((val) => val === 'true')
.default('false'),
SENTRY_DSN: z.string().optional(),
SENTRY_SEND_DEFAULT_PII: z
.string()
.optional()
.transform((val) => val === 'true'),
Comment thread
endigma marked this conversation as resolved.
Outdated
SENTRY_TRACES_SAMPLE_RATE: z.coerce.number().optional().default(1),
SENTRY_PROFILE_SESSION_SAMPLE_RATE: z.coerce.number().optional().default(1),
SENTRY_EVENT_LOOP_BLOCK_THRESHOLD_MS: z.coerce.number().optional().default(100),
})
.refine((input) => {
if (input.STRIPE_WEBHOOK_SECRET && !input.STRIPE_SECRET_KEY) {
Expand Down
31 changes: 31 additions & 0 deletions controlplane/src/core/sentry.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// sentry.config.ts
import * as Sentry from '@sentry/node';

import { nodeProfilingIntegration } from '@sentry/profiling-node';
import { eventLoopBlockIntegration } from '@sentry/node-native';

export interface SentryConfig {
sentry: {
enabled: boolean;
dsn: string;
eventLoopBlockIntegrationThresholdMs?: number;
profileSessionSampleRate?: number;
sendDefaultPii?: boolean;
tracesSampleRate?: number;
};
}

export function init(opts: SentryConfig) {
if (opts.sentry.enabled) {
Sentry.init({
dsn: opts.sentry.dsn,
integrations: [
eventLoopBlockIntegration({ threshold: opts.sentry.eventLoopBlockIntegrationThresholdMs }),
nodeProfilingIntegration(),
],
profileSessionSampleRate: opts.sentry.profileSessionSampleRate,
sendDefaultPii: opts.sentry.sendDefaultPii,
tracesSampleRate: opts.sentry.tracesSampleRate,
});
}
}
25 changes: 25 additions & 0 deletions controlplane/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ 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 @@ -66,6 +67,12 @@ const {
REDIS_PASSWORD,
AUTH_ADMISSION_JWT_SECRET,
CDN_BASE_URL,
SENTRY_ENABLED,
SENTRY_DSN,
SENTRY_SEND_DEFAULT_PII,
SENTRY_TRACES_SAMPLE_RATE,
SENTRY_PROFILE_SESSION_SAMPLE_RATE,
SENTRY_EVENT_LOOP_BLOCK_THRESHOLD_MS,
} = envVariables.parse(process.env);
Comment thread
endigma marked this conversation as resolved.

const options: BuildConfig = {
Expand Down Expand Up @@ -170,6 +177,24 @@ 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,
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');
}
}
Comment thread
endigma marked this conversation as resolved.

const app = await build(options);

await app.listen({
Expand Down
Loading
Loading