close sentry

This commit is contained in:
Tsuki 2025-08-25 00:35:25 +08:00
parent 19d020faec
commit 0e3640c0ce
11 changed files with 226 additions and 192 deletions

View File

@ -1,12 +1,13 @@
"use client"; "use client";
import * as Sentry from "@sentry/nextjs"; // import * as Sentry from "@sentry/nextjs";
import NextError from "next/error"; import NextError from "next/error";
import { useEffect } from "react"; import { useEffect } from "react";
export default function GlobalError({ error }: { error: Error & { digest?: string } }) { export default function GlobalError({ error }: { error: Error & { digest?: string } }) {
useEffect(() => { useEffect(() => {
Sentry.captureException(error); // Sentry.captureException(error);
console.error('Global error:', error);
}, [error]); }, [error]);
return ( return (

View File

@ -4,7 +4,7 @@ import React, { createContext, useContext, useRef, useState, ReactNode, useEffec
import { Map } from 'maplibre-gl'; import { Map } from 'maplibre-gl';
import { gql, useSubscription } from '@apollo/client'; import { gql, useSubscription } from '@apollo/client';
import { subscribeToConnectionState, reconnectWebSocket, WSConnectionState } from '@/lib/apollo-client'; import { subscribeToConnectionState, reconnectWebSocket, WSConnectionState } from '@/lib/apollo-client';
import * as Sentry from '@sentry/nextjs'; // import * as Sentry from '@sentry/nextjs';
// 定义WSContext的类型 // 定义WSContext的类型
interface WSContextType { interface WSContextType {
@ -58,7 +58,8 @@ export function WSProvider({ children }: MapProviderProps) {
const { data, loading, error, restart } = useSubscription(SUBSCRIPTION_QUERY, { const { data, loading, error, restart } = useSubscription(SUBSCRIPTION_QUERY, {
errorPolicy: 'all', errorPolicy: 'all',
onError: (error) => { onError: (error) => {
Sentry.captureException(error); // Sentry.captureException(error);
console.error('WebSocket subscription error:', error);
} }
}); });
@ -134,13 +135,14 @@ export function WSProvider({ children }: MapProviderProps) {
}, [loading, error, data, isOnline, restart, wsStatus, connectionState.status]); }, [loading, error, data, isOnline, restart, wsStatus, connectionState.status]);
const forceReconnect = () => { const forceReconnect = () => {
Sentry.startSpan({ // Sentry.startSpan({
op: 'websocket.manual-reconnect', // op: 'websocket.manual-reconnect',
name: 'Manual WebSocket Reconnection' // name: 'Manual WebSocket Reconnection'
}, () => { // }, () => {
console.log('Force reconnecting WebSocket...');
reconnectWebSocket(); reconnectWebSocket();
restart(); restart();
}); // });
}; };
const value: WSContextType = { const value: WSContextType = {

View File

@ -11,7 +11,7 @@ import { useRadarTile } from '@/hooks/use-radartile'
import { format, formatInTimeZone } from 'date-fns-tz' import { format, formatInTimeZone } from 'date-fns-tz'
import vertexSource from '@/app/glsl/radar/verx.glsl' import vertexSource from '@/app/glsl/radar/verx.glsl'
import fragmentSource from '@/app/glsl/radar/frag.glsl' import fragmentSource from '@/app/glsl/radar/frag.glsl'
import * as Sentry from '@sentry/nextjs' // import * as Sentry from '@sentry/nextjs'
import { logger, logWebGLError, logMapEvent, logPerformanceMetric } from '@/lib/logger' import { logger, logWebGLError, logMapEvent, logPerformanceMetric } from '@/lib/logger'
interface MapComponentProps { interface MapComponentProps {
@ -68,14 +68,14 @@ export function MapComponent({
useEffect(() => { useEffect(() => {
if (!mapContainer.current) return if (!mapContainer.current) return
const span = Sentry.startInactiveSpan({ // const span = Sentry.startInactiveSpan({
op: "ui.component.load", // op: "ui.component.load",
name: "Map Component Initialization", // name: "Map Component Initialization",
}); // });
span.setAttribute("map.style", style); // span.setAttribute("map.style", style);
span.setAttribute("map.center", `${location.center[0]},${location.center[1]}`); // span.setAttribute("map.center", `${location.center[0]},${location.center[1]}`);
span.setAttribute("map.zoom", location.zoom); // span.setAttribute("map.zoom", location.zoom);
const map = new maplibregl.Map({ const map = new maplibregl.Map({
container: mapContainer.current, container: mapContainer.current,
@ -127,7 +127,7 @@ export function MapComponent({
const shader = gl.createShader(type); const shader = gl.createShader(type);
if (!shader) { if (!shader) {
const error = new Error('Failed to create WebGL shader'); const error = new Error('Failed to create WebGL shader');
Sentry.captureException(error); // Sentry.captureException(error);
logWebGLError('shader_creation', 'Failed to create WebGL shader', { shaderType: type === gl.VERTEX_SHADER ? 'vertex' : 'fragment' }); logWebGLError('shader_creation', 'Failed to create WebGL shader', { shaderType: type === gl.VERTEX_SHADER ? 'vertex' : 'fragment' });
return null; return null;
} }
@ -138,10 +138,10 @@ export function MapComponent({
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
const errorLog = gl.getShaderInfoLog(shader) || 'Unknown shader compilation error'; const errorLog = gl.getShaderInfoLog(shader) || 'Unknown shader compilation error';
const error = new Error(`Shader compilation failed: ${errorLog}`); const error = new Error(`Shader compilation failed: ${errorLog}`);
Sentry.captureException(error, { // Sentry.captureException(error, {
tags: { component: 'MapComponent', operation: 'shader_compilation' }, // tags: { component: 'MapComponent', operation: 'shader_compilation' },
extra: { shaderType: type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', source } // extra: { shaderType: type === gl.VERTEX_SHADER ? 'vertex' : 'fragment', source }
}); // });
logWebGLError('shader_compilation', errorLog, { shaderType: type === gl.VERTEX_SHADER ? 'vertex' : 'fragment' }); logWebGLError('shader_compilation', errorLog, { shaderType: type === gl.VERTEX_SHADER ? 'vertex' : 'fragment' });
gl.deleteShader(shader); gl.deleteShader(shader);
return null; return null;
@ -166,10 +166,10 @@ export function MapComponent({
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
const errorLog = gl.getProgramInfoLog(program) || 'Unknown program linking error'; const errorLog = gl.getProgramInfoLog(program) || 'Unknown program linking error';
const error = new Error(`WebGL program linking failed: ${errorLog}`); const error = new Error(`WebGL program linking failed: ${errorLog}`);
Sentry.captureException(error, { // Sentry.captureException(error, {
tags: { component: 'MapComponent', operation: 'program_linking' }, // tags: { component: 'MapComponent', operation: 'program_linking' },
extra: { programLog: errorLog } // extra: { programLog: errorLog }
}); // });
logWebGLError('program_linking', errorLog); logWebGLError('program_linking', errorLog);
return; return;
} }
@ -184,9 +184,9 @@ export function MapComponent({
if (!tex) { if (!tex) {
const error = new Error('Failed to create WebGL texture'); const error = new Error('Failed to create WebGL texture');
Sentry.captureException(error, { // Sentry.captureException(error, {
tags: { component: 'MapComponent', operation: 'texture_creation' } // tags: { component: 'MapComponent', operation: 'texture_creation' }
}); // });
logWebGLError('texture_creation', 'Failed to create WebGL texture'); logWebGLError('texture_creation', 'Failed to create WebGL texture');
return; return;
} }
@ -482,7 +482,7 @@ export function MapComponent({
} }
// 结束Sentry span // 结束Sentry span
span.end(); // span.end();
} }
}, [mapContainer]) }, [mapContainer])
@ -549,14 +549,14 @@ export function MapComponent({
// 拖动事件处理函数 // 拖动事件处理函数
const handleMouseDown = (e: React.MouseEvent) => { const handleMouseDown = (e: React.MouseEvent) => {
Sentry.startSpan( // Sentry.startSpan(
{ // {
op: "ui.interaction", // op: "ui.interaction",
name: "Colorbar Drag Start", // name: "Colorbar Drag Start",
}, // },
(span: any) => { // (span: any) => {
span.setAttribute("colorbar.position.x", colorbarPosition.x); // span.setAttribute("colorbar.position.x", colorbarPosition.x);
span.setAttribute("colorbar.position.y", colorbarPosition.y); // span.setAttribute("colorbar.position.y", colorbarPosition.y);
e.preventDefault() e.preventDefault()
setIsDragging(true) setIsDragging(true)
@ -568,8 +568,8 @@ export function MapComponent({
startPositionX: colorbarPosition.x, startPositionX: colorbarPosition.x,
startPositionY: colorbarPosition.y startPositionY: colorbarPosition.y
} }
} // }
); // );
} }
// 全局鼠标事件监听 // 全局鼠标事件监听

View File

@ -2,33 +2,33 @@
// The added config here will be used whenever a users loads a page in their browser. // The added config here will be used whenever a users loads a page in their browser.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/ // https://docs.sentry.io/platforms/javascript/guides/nextjs/
import * as Sentry from "@sentry/nextjs"; // import * as Sentry from "@sentry/nextjs";
Sentry.init({ // Sentry.init({
dsn: "https://109bcfcc2d1cdd643e0af61409016900@o4505647824109568.ingest.us.sentry.io/4509868655181824", // dsn: "https://109bcfcc2d1cdd643e0af61409016900@o4505647824109568.ingest.us.sentry.io/4509868655181824",
// Add optional integrations for additional features // // Add optional integrations for additional features
integrations: [ // integrations: [
Sentry.replayIntegration(), // Sentry.replayIntegration(),
// send console.log, console.warn, and console.error calls as logs to Sentry // // send console.log, console.warn, and console.error calls as logs to Sentry
Sentry.consoleLoggingIntegration({ levels: ["log", "warn", "error"] }), // Sentry.consoleLoggingIntegration({ levels: ["log", "warn", "error"] }),
], // ],
// Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control. // // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.
tracesSampleRate: 1, // tracesSampleRate: 1,
// Enable logs to be sent to Sentry // // Enable logs to be sent to Sentry
enableLogs: true, // enableLogs: true,
// Define how likely Replay events are sampled. // // Define how likely Replay events are sampled.
// This sets the sample rate to be 10%. You may want this to be 100% while // // This sets the sample rate to be 10%. You may want this to be 100% while
// in development and sample at a lower rate in production // // in development and sample at a lower rate in production
replaysSessionSampleRate: 0.1, // replaysSessionSampleRate: 0.1,
// Define how likely Replay events are sampled when an error occurs. // // Define how likely Replay events are sampled when an error occurs.
replaysOnErrorSampleRate: 1.0, // replaysOnErrorSampleRate: 1.0,
// Setting this option to true will print useful information to the console while you're setting up Sentry. // // Setting this option to true will print useful information to the console while you're setting up Sentry.
debug: false, // debug: false,
}); // });
export const onRouterTransitionStart = Sentry.captureRouterTransitionStart; // export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;

View File

@ -1,13 +1,13 @@
import * as Sentry from '@sentry/nextjs'; // import * as Sentry from '@sentry/nextjs';
export async function register() { export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') { // if (process.env.NEXT_RUNTIME === 'nodejs') {
await import('./sentry.server.config'); // await import('./sentry.server.config');
} // }
if (process.env.NEXT_RUNTIME === 'edge') { // if (process.env.NEXT_RUNTIME === 'edge') {
await import('./sentry.edge.config'); // await import('./sentry.edge.config');
} // }
} }
export const onRequestError = Sentry.captureRequestError; // export const onRequestError = Sentry.captureRequestError;

View File

@ -3,7 +3,7 @@ import { getMainDefinition } from '@apollo/client/utilities';
import { setContext } from '@apollo/client/link/context'; import { setContext } from '@apollo/client/link/context';
import { GraphQLWsLink } from '@apollo/client/link/subscriptions'; import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
import { createClient, Client } from 'graphql-ws'; import { createClient, Client } from 'graphql-ws';
import * as Sentry from '@sentry/nextjs'; // import * as Sentry from '@sentry/nextjs';
const TOKEN_KEY = 'auth_token'; const TOKEN_KEY = 'auth_token';
@ -44,6 +44,8 @@ let wsClient: Client | null = null;
const createWSClient = () => { const createWSClient = () => {
const wsUrl = process.env.NEXT_PUBLIC_GRAPHQL_BACKEND_URL?.replace('/graphql', '/ws')?.replace('http://', 'ws://') || 'ws://localhost:3050/ws'; const wsUrl = process.env.NEXT_PUBLIC_GRAPHQL_BACKEND_URL?.replace('/graphql', '/ws')?.replace('http://', 'ws://') || 'ws://localhost:3050/ws';
// console.log('Creating WebSocket client with URL:', wsUrl);
return createClient({ return createClient({
url: wsUrl, url: wsUrl,
connectionParams: () => { connectionParams: () => {
@ -58,50 +60,54 @@ const createWSClient = () => {
reconnectAttempts: attempt + 1 reconnectAttempts: attempt + 1
}); });
Sentry.startSpan({ // Sentry.startSpan({
op: 'websocket.reconnect', // op: 'websocket.reconnect',
name: 'WebSocket Reconnection Attempt' // name: 'WebSocket Reconnection Attempt'
}, (span) => { // }, (span) => {
span.setAttribute('attempt', attempt + 1); // span.setAttribute('attempt', attempt + 1);
span.setAttribute('delay', delay); // span.setAttribute('delay', delay);
}); // });
await new Promise(resolve => setTimeout(resolve, delay)); await new Promise(resolve => setTimeout(resolve, delay));
}, },
on: { on: {
connecting: () => { connecting: () => {
// console.log('WebSocket connecting...');
updateConnectionState({ status: 'connecting' }); updateConnectionState({ status: 'connecting' });
}, },
opened: () => { opened: () => {
// console.log('WebSocket connection opened successfully');
updateConnectionState({ updateConnectionState({
status: 'connected', status: 'connected',
error: undefined, error: undefined,
reconnectAttempts: 0 reconnectAttempts: 0
}); });
Sentry.startSpan({ // Sentry.startSpan({
op: 'websocket.connect', // op: 'websocket.connect',
name: 'WebSocket Connection Established' // name: 'WebSocket Connection Established'
}, () => { }); // }, () => { });
}, },
closed: (event: any) => { closed: (event: any) => {
// console.log('WebSocket connection closed:', event.code, event.reason);
const error = event.reason ? new Error(event.reason) : undefined; const error = event.reason ? new Error(event.reason) : undefined;
updateConnectionState({ updateConnectionState({
status: 'disconnected', status: 'disconnected',
error error
}); });
if (error) { // if (error) {
Sentry.captureException(error); // Sentry.captureException(error);
} // }
}, },
error: (error) => { error: (error) => {
console.error('WebSocket error:', error);
updateConnectionState({ updateConnectionState({
status: 'disconnected', status: 'disconnected',
error: error instanceof Error ? error : new Error('WebSocket error') error: error instanceof Error ? error : new Error('WebSocket error')
}); });
Sentry.captureException(error); // Sentry.captureException(error);
} }
} }
}); });

View File

@ -1,7 +1,7 @@
import { gql, GraphQLClient } from "graphql-request"; import { gql, GraphQLClient } from "graphql-request";
import type { PageData } from "@/types/page"; import type { PageData } from "@/types/page";
import { getBaseUrl } from "./gr-client"; import { getBaseUrl } from "./gr-client";
import * as Sentry from "@sentry/nextjs"; // import * as Sentry from "@sentry/nextjs";
const PageQuery = gql/* GraphQL */ ` const PageQuery = gql/* GraphQL */ `
@ -28,14 +28,14 @@ const BlockQuery = gql/* GraphQL */ `
export async function fetchPage(slug: string, jwt?: string): Promise<PageData | null> { export async function fetchPage(slug: string, jwt?: string): Promise<PageData | null> {
return Sentry.startSpan( // return Sentry.startSpan(
{ // {
op: "http.client", // op: "http.client",
name: `GraphQL fetchPage: ${slug}`, // name: `GraphQL fetchPage: ${slug}`,
}, // },
async (span) => { // async (span) => {
span.setAttribute("page.slug", slug); // span.setAttribute("page.slug", slug);
span.setAttribute("auth.hasJwt", !!jwt); // span.setAttribute("auth.hasJwt", !!jwt);
const client = new GraphQLClient(getBaseUrl()); const client = new GraphQLClient(getBaseUrl());
@ -45,34 +45,38 @@ export async function fetchPage(slug: string, jwt?: string): Promise<PageData |
try { try {
// 获取页面基本信息 // 获取页面基本信息
const pageResponse: any = await Sentry.startSpan( const pageResponse: any = await client.request(PageQuery, { slug });
{ // const pageResponse: any = await Sentry.startSpan(
op: "http.client", // {
name: "GraphQL PageQuery", // op: "http.client",
}, // name: "GraphQL PageQuery",
() => client.request(PageQuery, { slug }) // },
); // () => client.request(PageQuery, { slug })
// );
if (!pageResponse?.pageBySlug) { if (!pageResponse?.pageBySlug) {
throw new Error('Page not found'); throw new Error('Page not found');
} }
// 获取页面块数据 // 获取页面块数据
const blocksResponse: any = await Sentry.startSpan( const blocksResponse: any = await client.request(BlockQuery, {
{ pageId: pageResponse.pageBySlug.id
op: "http.client", });
name: "GraphQL BlockQuery", // const blocksResponse: any = await Sentry.startSpan(
}, // {
() => client.request(BlockQuery, { // op: "http.client",
pageId: pageResponse.pageBySlug.id // name: "GraphQL BlockQuery",
}) // },
); // () => client.request(BlockQuery, {
// pageId: pageResponse.pageBySlug.id
// })
// );
if (!blocksResponse?.pageBlocks) { if (!blocksResponse?.pageBlocks) {
throw new Error('Failed to fetch page blocks'); throw new Error('Failed to fetch page blocks');
} }
span.setAttribute("page.blocksCount", blocksResponse.pageBlocks.length); // span.setAttribute("page.blocksCount", blocksResponse.pageBlocks.length);
// 合并数据 // 合并数据
return { return {
@ -81,27 +85,27 @@ export async function fetchPage(slug: string, jwt?: string): Promise<PageData |
}; };
} catch (error) { } catch (error) {
Sentry.captureException(error, { // Sentry.captureException(error, {
tags: { operation: 'fetchPage' }, // tags: { operation: 'fetchPage' },
extra: { slug, hasJwt: !!jwt } // extra: { slug, hasJwt: !!jwt }
}); // });
console.error('Failed to fetch page:', error); console.error('Failed to fetch page:', error);
return null; return null;
} }
} // }
); // );
} }
export async function getSiteConfigs() { export async function getSiteConfigs() {
return Sentry.startSpan( // return Sentry.startSpan(
{ // {
op: "http.client", // op: "http.client",
name: "Fetch Site Configs", // name: "Fetch Site Configs",
}, // },
async (span) => { // async (span) => {
try { try {
const baseUrl = process.env.NEXTAUTH_URL || 'http://localhost:3000'; const baseUrl = process.env.NEXTAUTH_URL || 'http://localhost:3000';
span.setAttribute("api.baseUrl", baseUrl); // span.setAttribute("api.baseUrl", baseUrl);
const siteConfigs = await fetch(`${baseUrl}/api/site`, { const siteConfigs = await fetch(`${baseUrl}/api/site`, {
headers: { headers: {
@ -111,30 +115,30 @@ export async function getSiteConfigs() {
signal: AbortSignal.timeout(5000) signal: AbortSignal.timeout(5000)
}); });
span.setAttribute("http.status_code", siteConfigs.status); // span.setAttribute("http.status_code", siteConfigs.status);
if (!siteConfigs.ok) { if (!siteConfigs.ok) {
const error = new Error(`Failed to fetch site configs: ${siteConfigs.status} ${siteConfigs.statusText}`); const error = new Error(`Failed to fetch site configs: ${siteConfigs.status} ${siteConfigs.statusText}`);
Sentry.captureException(error, { // Sentry.captureException(error, {
tags: { operation: 'getSiteConfigs' }, // tags: { operation: 'getSiteConfigs' },
extra: { status: siteConfigs.status, statusText: siteConfigs.statusText } // extra: { status: siteConfigs.status, statusText: siteConfigs.statusText }
}); // });
console.warn(`Failed to fetch site configs: ${siteConfigs.status} ${siteConfigs.statusText}`); console.warn(`Failed to fetch site configs: ${siteConfigs.status} ${siteConfigs.statusText}`);
return getDefaultSiteConfigs(); return getDefaultSiteConfigs();
} }
const data = await siteConfigs.json(); const data = await siteConfigs.json();
span.setAttribute("configs.count", data.length); // span.setAttribute("configs.count", data.length);
return data; return data;
} catch (error) { } catch (error) {
Sentry.captureException(error, { // Sentry.captureException(error, {
tags: { operation: 'getSiteConfigs' } // tags: { operation: 'getSiteConfigs' }
}); // });
console.warn('Failed to fetch site configs, using defaults:', error); console.warn('Failed to fetch site configs, using defaults:', error);
return getDefaultSiteConfigs(); return getDefaultSiteConfigs();
} }
} // }
); // );
} }
function getDefaultSiteConfigs() { function getDefaultSiteConfigs() {

View File

@ -1,9 +1,28 @@
import * as Sentry from "@sentry/nextjs"; // import * as Sentry from "@sentry/nextjs";
// 获取Sentry logger实例 // 获取Sentry logger实例
const { logger } = Sentry; // const { logger } = Sentry;
// 导出logger以便在其他文件中使用 // 导出logger以便在其他文件中使用
// export { logger };
// Fallback logger when Sentry is disabled
const logger = {
trace: (message: string, context?: Record<string, any>) => console.log(`[TRACE] ${message}`, context),
debug: (message: string, context?: Record<string, any>) => console.log(`[DEBUG] ${message}`, context),
info: (message: string, context?: Record<string, any>) => console.log(`[INFO] ${message}`, context),
warn: (message: string, context?: Record<string, any>) => console.warn(`[WARN] ${message}`, context),
error: (message: string, context?: Record<string, any>) => console.error(`[ERROR] ${message}`, context),
fatal: (message: string, context?: Record<string, any>) => console.error(`[FATAL] ${message}`, context),
fmt: (strings: TemplateStringsArray, ...values: any[]) => {
let result = strings[0];
for (let i = 0; i < values.length; i++) {
result += values[i] + strings[i + 1];
}
return result;
}
};
export { logger }; export { logger };
// 示例用法的辅助函数 // 示例用法的辅助函数

View File

@ -1,4 +1,4 @@
import {withSentryConfig} from "@sentry/nextjs"; // import {withSentryConfig} from "@sentry/nextjs";
import type { NextConfig } from "next"; import type { NextConfig } from "next";
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
@ -14,35 +14,37 @@ const nextConfig: NextConfig = {
} }
}; };
export default withSentryConfig(nextConfig, { export default nextConfig;
// For all available options, see:
// https://www.npmjs.com/package/@sentry/webpack-plugin#options
org: "lix-nr", // export default withSentryConfig(nextConfig, {
// // For all available options, see:
// // https://www.npmjs.com/package/@sentry/webpack-plugin#options
project: "lidar", // org: "lix-nr",
// Only print logs for uploading source maps in CI // project: "lidar",
silent: !process.env.CI,
// For all available options, see: // // Only print logs for uploading source maps in CI
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/ // silent: !process.env.CI,
// Upload a larger set of source maps for prettier stack traces (increases build time) // // For all available options, see:
widenClientFileUpload: true, // // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
// Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers. // // Upload a larger set of source maps for prettier stack traces (increases build time)
// This can increase your server load as well as your hosting bill. // widenClientFileUpload: true,
// Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-
// side errors will fail.
// tunnelRoute: "/monitoring",
// Automatically tree-shake Sentry logger statements to reduce bundle size // // Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.
disableLogger: true, // // This can increase your server load as well as your hosting bill.
// // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-
// // side errors will fail.
// // tunnelRoute: "/monitoring",
// Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.) // // Automatically tree-shake Sentry logger statements to reduce bundle size
// See the following for more information: // disableLogger: true,
// https://docs.sentry.io/product/crons/
// https://vercel.com/docs/cron-jobs // // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)
automaticVercelMonitors: true // // See the following for more information:
}); // // https://docs.sentry.io/product/crons/
// // https://vercel.com/docs/cron-jobs
// automaticVercelMonitors: true
// });

View File

@ -3,22 +3,22 @@
// Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally. // Note that this config is unrelated to the Vercel Edge Runtime and is also required when running locally.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/ // https://docs.sentry.io/platforms/javascript/guides/nextjs/
import * as Sentry from "@sentry/nextjs"; // import * as Sentry from "@sentry/nextjs";
Sentry.init({ // Sentry.init({
dsn: "https://109bcfcc2d1cdd643e0af61409016900@o4505647824109568.ingest.us.sentry.io/4509868655181824", // dsn: "https://109bcfcc2d1cdd643e0af61409016900@o4505647824109568.ingest.us.sentry.io/4509868655181824",
integrations: [ // integrations: [
// send console.log, console.warn, and console.error calls as logs to Sentry // // send console.log, console.warn, and console.error calls as logs to Sentry
Sentry.consoleLoggingIntegration({ levels: ["log", "warn", "error"] }), // Sentry.consoleLoggingIntegration({ levels: ["log", "warn", "error"] }),
], // ],
// Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control. // // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.
tracesSampleRate: 1, // tracesSampleRate: 1,
// Enable logs to be sent to Sentry // // Enable logs to be sent to Sentry
enableLogs: true, // enableLogs: true,
// Setting this option to true will print useful information to the console while you're setting up Sentry. // // Setting this option to true will print useful information to the console while you're setting up Sentry.
debug: false, // debug: false,
}); // });

View File

@ -2,22 +2,22 @@
// The config you add here will be used whenever the server handles a request. // The config you add here will be used whenever the server handles a request.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/ // https://docs.sentry.io/platforms/javascript/guides/nextjs/
import * as Sentry from "@sentry/nextjs"; // import * as Sentry from "@sentry/nextjs";
Sentry.init({ // Sentry.init({
dsn: "https://109bcfcc2d1cdd643e0af61409016900@o4505647824109568.ingest.us.sentry.io/4509868655181824", // dsn: "https://109bcfcc2d1cdd643e0af61409016900@o4505647824109568.ingest.us.sentry.io/4509868655181824",
integrations: [ // integrations: [
// send console.log, console.warn, and console.error calls as logs to Sentry // // send console.log, console.warn, and console.error calls as logs to Sentry
Sentry.consoleLoggingIntegration({ levels: ["log", "warn", "error"] }), // Sentry.consoleLoggingIntegration({ levels: ["log", "warn", "error"] }),
], // ],
// Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control. // // Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.
tracesSampleRate: 1, // tracesSampleRate: 1,
// Enable logs to be sent to Sentry // // Enable logs to be sent to Sentry
enableLogs: true, // enableLogs: true,
// Setting this option to true will print useful information to the console while you're setting up Sentry. // // Setting this option to true will print useful information to the console while you're setting up Sentry.
debug: false, // debug: false,
}); // });