Sentry + Turbopack fixes (#28)

* Updated packages

Updated all packages to the latest versions

* Refactor Sentry monitoring configuration and services

The Sentry monitoring configuration and services have been refactored to simplify the setup process. In addition, unnecessary files or exports have been removed from the Sentry package. These changes should make the process of initializing and using the Sentry monitoring services in both the client and server more straightforward and efficient.

* Refactor server-side Sentry instrumentation code

The conditional logic responsible for checking the runtime environment and the enabled status of the monitoring instrumentation has been adjusted. This refactoring simplifies the code, making it more readable, by clearly separating the conditions and nesting the environment-specific operations. A typo in the environment variable name "ENABLE_MONITORING_INSTRMENTATION" was also corrected to "ENABLE_MONITORING_INSTRUMENTATION".

* Rename environment variable for monitoring instrumentation

The environment variable controlling monitoring instrumentation has been renamed from 'MONITORING_INSTRUMENTATION_ENABLED' to 'ENABLE_MONITORING_INSTRUMENTATION'. It affects both the README and .env.production files within the monitoring/api and apps/web directories respectively.
This commit is contained in:
Giancarlo Buomprisco
2024-05-28 15:17:56 +07:00
committed by GitHub
parent 1e047463c8
commit c495335fd5
26 changed files with 581 additions and 301 deletions

View File

@@ -13,4 +13,4 @@ NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=
# MONITORING
NEXT_PUBLIC_MONITORING_PROVIDER=
MONITORING_INSTRUMENTATION_ENABLED=false
ENABLE_MONITORING_INSTRUMENTATION=false

View File

@@ -2,18 +2,12 @@
* This file is used to register monitoring instrumentation
* for your Next.js application.
*/
export async function register() {
// only run in nodejs runtime
if (
process.env.NEXT_RUNTIME === 'nodejs' &&
process.env.MONITORING_INSTRUMENTATION_ENABLED === 'true'
) {
const { registerMonitoringInstrumentation } = await import(
'@kit/monitoring/instrumentation'
);
// Register monitoring instrumentation based on the MONITORING_PROVIDER environment variable.
return registerMonitoringInstrumentation();
}
// Register monitoring instrumentation
// based on the MONITORING_PROVIDER environment variable.
await registerMonitoringInstrumentation();
}

View File

@@ -55,7 +55,7 @@
"@marsidev/react-turnstile": "^0.6.1",
"@radix-ui/react-icons": "^1.3.0",
"@supabase/supabase-js": "^2.43.4",
"@tanstack/react-query": "5.39.0",
"@tanstack/react-query": "5.40.0",
"@tanstack/react-query-next-experimental": "^5.39.0",
"@tanstack/react-table": "^8.17.3",
"date-fns": "^3.6.0",
@@ -86,7 +86,7 @@
"dotenv-cli": "^7.4.2",
"eslint": "^8.57.0",
"prettier": "^3.2.5",
"supabase": "^1.167.4",
"supabase": "^1.169.6",
"tailwindcss": "3.4.3",
"typescript": "^5.4.5"
},

View File

@@ -34,7 +34,7 @@
"@kit/ui": "workspace:^",
"@radix-ui/react-icons": "^1.3.0",
"@supabase/supabase-js": "^2.43.4",
"@tanstack/react-query": "5.39.0",
"@tanstack/react-query": "5.40.0",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"lucide-react": "^0.379.0",

View File

@@ -21,7 +21,7 @@
"@makerkit/data-loader-supabase-core": "^0.0.8",
"@makerkit/data-loader-supabase-nextjs": "^1.2.3",
"@supabase/supabase-js": "^2.43.4",
"@tanstack/react-query": "5.39.0",
"@tanstack/react-query": "5.40.0",
"@tanstack/react-table": "^8.17.3",
"@types/react": "^18.3.3",
"lucide-react": "^0.379.0",

View File

@@ -29,7 +29,7 @@
"@marsidev/react-turnstile": "^0.6.1",
"@radix-ui/react-icons": "^1.3.0",
"@supabase/supabase-js": "^2.43.4",
"@tanstack/react-query": "5.39.0",
"@tanstack/react-query": "5.40.0",
"@types/react": "^18.3.3",
"lucide-react": "^0.379.0",
"next": "14.2.3",

View File

@@ -21,7 +21,7 @@
"@kit/tsconfig": "workspace:*",
"@kit/ui": "workspace:*",
"@supabase/supabase-js": "^2.43.4",
"@tanstack/react-query": "5.39.0",
"@tanstack/react-query": "5.40.0",
"@types/react": "^18.3.3",
"lucide-react": "^0.379.0",
"react": "18.3.1",

View File

@@ -32,7 +32,7 @@
"@kit/tsconfig": "workspace:*",
"@kit/ui": "workspace:^",
"@supabase/supabase-js": "^2.43.4",
"@tanstack/react-query": "5.39.0",
"@tanstack/react-query": "5.40.0",
"@tanstack/react-table": "^8.17.3",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",

View File

@@ -21,7 +21,7 @@
"@kit/shared": "workspace:^",
"@kit/tailwind-config": "workspace:*",
"@kit/tsconfig": "workspace:*",
"@tanstack/react-query": "5.39.0",
"@tanstack/react-query": "5.40.0",
"react-i18next": "^14.1.2"
},
"dependencies": {

View File

@@ -4,7 +4,7 @@ Please set the following environment variable to your preferred monitoring provi
```
NEXT_PUBLIC_MONITORING_PROVIDER=
MONITORING_INSTRUMENTATION_ENABLED=true
ENABLE_MONITORING_INSTRUMENTATION=true
```
## Available Providers
@@ -32,8 +32,8 @@ NEXT_PUBLIC_MONITORING_PROVIDER=sentry
## Instrumentation
To enable instrumentation, set the `MONITORING_INSTRUMENTATION_ENABLED` environment variable to `true`.
To enable instrumentation, set the `ENABLE_MONITORING_INSTRUMENTATION` environment variable to `true`.
```
MONITORING_INSTRUMENTATION_ENABLED=true
ENABLE_MONITORING_INSTRUMENTATION=true
```

View File

@@ -28,11 +28,9 @@ export async function getServerMonitoringService() {
}
case InstrumentationProvider.Sentry: {
const { SentryServerMonitoringService } = await import(
'@kit/sentry/server'
);
const { SentryMonitoringService } = await import('@kit/sentry');
return new SentryServerMonitoringService();
return new SentryMonitoringService();
}
default: {

View File

@@ -5,6 +5,10 @@
* Please set the MONITORING_PROVIDER environment variable to 'baselime' to register Baselime instrumentation.
*/
export async function registerInstrumentation() {
if (!process.env.ENABLE_MONITORING_INSTRUMENTATION) {
return;
}
const serviceName = process.env.INSTRUMENTATION_SERVICE_NAME;
if (!serviceName) {
@@ -14,9 +18,9 @@ export async function registerInstrumentation() {
`);
}
const { BaselimeSDK, BetterHttpInstrumentation, VercelPlugin } = await import(
'@baselime/node-opentelemetry'
);
if (process.env.NEXT_RUNTIME === 'nodejs') {
const { BaselimeSDK, BetterHttpInstrumentation, VercelPlugin } =
await import('@baselime/node-opentelemetry');
const sdk = new BaselimeSDK({
serverless: true,
@@ -29,4 +33,5 @@ export async function registerInstrumentation() {
});
sdk.start();
}
}

View File

@@ -11,19 +11,17 @@
"prettier": "@kit/prettier-config",
"exports": {
".": "./src/index.ts",
"./server": "./src/server.ts",
"./provider": "./src/components/provider.tsx",
"./instrumentation": "./src/instrumentation.ts",
"./config/client": "./src/config/sentry.client.config.ts",
"./config/server": "./src/config/sentry.server.config.ts",
"./config/edge": "./src/config/sentry.edge.config.ts"
"./config/client": "./src/sentry.client.config.ts",
"./config/server": "./src/sentry.client.server.ts"
},
"dependencies": {
"@opentelemetry/exporter-jaeger": "1.24.1",
"@opentelemetry/resources": "1.24.1",
"@opentelemetry/sdk-node": "0.51.1",
"@opentelemetry/semantic-conventions": "^1.24.1",
"@sentry/nextjs": "^8.4.0",
"@sentry/nextjs": "^8.5.0",
"@sentry/opentelemetry-node": "^7.114.0"
},
"devDependencies": {

View File

@@ -2,14 +2,14 @@ import { useRef } from 'react';
import { MonitoringContext } from '@kit/monitoring-core';
import { SentryServerMonitoringService } from '../services/sentry-server-monitoring.service';
import { SentryMonitoringService } from '../services/sentry-monitoring.service';
export function SentryProvider({ children }: React.PropsWithChildren) {
return <MonitoringProvider>{children}</MonitoringProvider>;
}
function MonitoringProvider(props: React.PropsWithChildren) {
const service = useRef(new SentryServerMonitoringService());
const service = useRef(new SentryMonitoringService());
return (
<MonitoringContext.Provider value={service.current}>

View File

@@ -1,23 +0,0 @@
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
// Replay may only be enabled for the client-side
integrations: [Sentry.replayIntegration()],
// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for performance monitoring.
// We recommend adjusting this value in production
tracesSampleRate: 1.0,
// Capture Replay for 10% of all sessions,
// plus for 100% of sessions with an error
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
// ...
// Note: if you want to override the automatic release value, do not set a
// `release` value here - use the environment variable `SENTRY_RELEASE`, so
// that it will also get attached to your source maps
});

View File

@@ -1,6 +0,0 @@
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
tracesSampleRate: 1.0,
});

View File

@@ -1,6 +0,0 @@
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
tracesSampleRate: 1.0,
});

View File

@@ -0,0 +1 @@
export * from './services/sentry-monitoring.service';

View File

@@ -5,6 +5,19 @@
* Please set the MONITORING_PROVIDER environment variable to 'sentry' to register Sentry instrumentation.
*/
export async function registerInstrumentation() {
const { initializeSentryServerClient } = await import(
'./sentry.server.config'
);
// initialize the Sentry client in the server
void initializeSentryServerClient();
if (!process.env.ENABLE_MONITORING_INSTRUMENTATION) {
return;
}
// make sure the instrumentation is only run in a Node.js environment
if (process.env.NEXT_RUNTIME === 'nodejs') {
const serviceName = process.env.INSTRUMENTATION_SERVICE_NAME;
if (!serviceName) {
@@ -33,4 +46,5 @@ export async function registerInstrumentation() {
});
sdk.start();
}
}

View File

@@ -0,0 +1,39 @@
import * as Sentry from '@sentry/nextjs';
type Parameters<T extends (args: never) => unknown> = T extends (
...args: infer P
) => unknown
? P
: never;
/**
* @name initializeSentryBrowserClient
* @description Initialize the Sentry client
* @param props
*/
export function initializeSentryBrowserClient(
props: Parameters<typeof Sentry.init>[0] = {},
) {
return Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
// Replay may only be enabled for the client-side
integrations: [Sentry.replayIntegration()],
// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for performance monitoring.
// We recommend adjusting this value in production
tracesSampleRate: props?.tracesSampleRate ?? 1.0,
// Capture Replay for 10% of all sessions,
// plus for 100% of sessions with an error
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
// ...
// Note: if you want to override the automatic release value, do not set a
// `release` value here - use the environment variable `SENTRY_RELEASE`, so
// that it will also get attached to your source maps,
...props,
});
}

View File

@@ -0,0 +1,27 @@
import * as Sentry from '@sentry/nextjs';
type Parameters<T extends (args: never) => unknown> = T extends (
...args: infer P
) => unknown
? P
: never;
/**
* @name initializeSentryServerClient
* @description Initialize the Sentry client in the server
* @param props
*/
export function initializeSentryServerClient(
props: Parameters<typeof Sentry.init>[0] = {},
) {
return Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
// ...
// Note: if you want to override the automatic release value, do not set a
// `release` value here - use the environment variable `SENTRY_RELEASE`, so
// that it will also get attached to your source maps,
...props,
});
}

View File

@@ -1 +0,0 @@
export * from './services/sentry-server-monitoring.service';

View File

@@ -7,7 +7,11 @@ import { MonitoringService } from '@kit/monitoring-core';
* @implements {MonitoringService}
* ServerSentryMonitoringService is responsible for capturing exceptions and identifying users using the Sentry monitoring service.
*/
export class SentryServerMonitoringService implements MonitoringService {
export class SentryMonitoringService implements MonitoringService {
constructor() {
void this.initialize();
}
captureException(error: Error | null) {
return Sentry.captureException(error);
}
@@ -22,4 +26,18 @@ export class SentryServerMonitoringService implements MonitoringService {
identifyUser(user: Sentry.User) {
Sentry.setUser(user);
}
private initialize() {
return this.initializeIfBrowser();
}
private async initializeIfBrowser() {
if (typeof document !== 'undefined') {
const { initializeSentryBrowserClient } = await import(
'../sentry.client.config'
);
initializeSentryBrowserClient();
}
}
}

View File

@@ -29,7 +29,7 @@
"@supabase/gotrue-js": "2.62.2",
"@supabase/ssr": "^0.3.0",
"@supabase/supabase-js": "^2.43.4",
"@tanstack/react-query": "5.39.0",
"@tanstack/react-query": "5.40.0",
"@types/react": "^18.3.3",
"next": "14.2.3",
"react": "18.3.1",

604
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -16,12 +16,12 @@
"@next/eslint-plugin-next": "^14.2.3",
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
"@types/eslint": "^8.56.10",
"@typescript-eslint/eslint-plugin": "^7.9.0",
"@typescript-eslint/parser": "^7.9.0",
"@typescript-eslint/eslint-plugin": "^7.11.0",
"@typescript-eslint/parser": "^7.11.0",
"eslint-config-prettier": "^9.1.0",
"eslint-config-turbo": "^1.13.3",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-react": "^7.34.1",
"eslint-plugin-react": "^7.34.2",
"eslint-plugin-react-hooks": "^4.6.2"
},
"devDependencies": {