feat: set sentry
This commit is contained in:
parent
0fa950dd8e
commit
3483b022e8
|
|
@ -11,10 +11,13 @@ import { AgentModule } from '@gitroom/nestjs-libraries/agent/agent.module';
|
|||
import { McpModule } from '@gitroom/backend/mcp/mcp.module';
|
||||
import { ThirdPartyModule } from '@gitroom/nestjs-libraries/3rdparties/thirdparty.module';
|
||||
import { VideoModule } from '@gitroom/nestjs-libraries/videos/video.module';
|
||||
import { SentryModule } from "@sentry/nestjs/setup";
|
||||
import { FILTER } from '@gitroom/nestjs-libraries/sentry/sentry.exception';
|
||||
|
||||
@Global()
|
||||
@Module({
|
||||
imports: [
|
||||
SentryModule.forRoot(),
|
||||
BullMqModule,
|
||||
DatabaseModule,
|
||||
ApiModule,
|
||||
|
|
@ -32,6 +35,7 @@ import { VideoModule } from '@gitroom/nestjs-libraries/videos/video.module';
|
|||
],
|
||||
controllers: [],
|
||||
providers: [
|
||||
FILTER,
|
||||
{
|
||||
provide: APP_GUARD,
|
||||
useClass: ThrottlerBehindProxyGuard,
|
||||
|
|
@ -39,7 +43,7 @@ import { VideoModule } from '@gitroom/nestjs-libraries/videos/video.module';
|
|||
{
|
||||
provide: APP_GUARD,
|
||||
useClass: PoliciesGuard,
|
||||
},
|
||||
}
|
||||
],
|
||||
exports: [
|
||||
BullMqModule,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ import { AppModule } from './app.module';
|
|||
import { SubscriptionExceptionFilter } from '@gitroom/backend/services/auth/permissions/subscription.exception';
|
||||
import { HttpExceptionFilter } from '@gitroom/nestjs-libraries/services/exception.filter';
|
||||
import { ConfigurationChecker } from '@gitroom/helpers/configuration/configuration.checker';
|
||||
import { initializeSentry } from '@gitroom/nestjs-libraries/sentry/initialize.sentry';
|
||||
|
||||
initializeSentry();
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.create(AppModule, {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,20 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
import { ScheduleModule } from '@nestjs/schedule';
|
||||
import { CheckStars } from '@gitroom/cron/tasks/check.stars';
|
||||
import { DatabaseModule } from '@gitroom/nestjs-libraries/database/prisma/database.module';
|
||||
import { SyncTrending } from '@gitroom/cron/tasks/sync.trending';
|
||||
import { BullMqModule } from '@gitroom/nestjs-libraries/bull-mq-transport-new/bull.mq.module';
|
||||
import { SentryModule } from '@sentry/nestjs/setup';
|
||||
import { FILTER } from '@gitroom/nestjs-libraries/sentry/sentry.exception';
|
||||
|
||||
@Module({
|
||||
imports: [DatabaseModule, ScheduleModule.forRoot(), BullMqModule],
|
||||
imports: [
|
||||
SentryModule.forRoot(),
|
||||
DatabaseModule,
|
||||
ScheduleModule.forRoot(),
|
||||
BullMqModule,
|
||||
],
|
||||
controllers: [],
|
||||
providers: [...(!process.env.IS_GENERAL ? [CheckStars, SyncTrending] : [])],
|
||||
providers: [
|
||||
FILTER
|
||||
],
|
||||
})
|
||||
export class CronModule {}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import { NestFactory } from '@nestjs/core';
|
||||
import { CronModule } from './cron.module';
|
||||
import { initializeSentry } from '@gitroom/nestjs-libraries/sentry/initialize.sentry';
|
||||
|
||||
initializeSentry();
|
||||
|
||||
async function bootstrap() {
|
||||
// some comment again
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { Cron } from '@nestjs/schedule';
|
||||
import { StarsService } from '@gitroom/nestjs-libraries/database/prisma/stars/stars.service';
|
||||
import { BullMqClient } from '@gitroom/nestjs-libraries/bull-mq-transport-new/client';
|
||||
|
||||
@Injectable()
|
||||
export class CheckStars {
|
||||
constructor(
|
||||
private _starsService: StarsService,
|
||||
private _workerServiceProducer: BullMqClient
|
||||
) {}
|
||||
@Cron('30 0 * * *')
|
||||
async checkStars() {
|
||||
const allGitHubRepositories =
|
||||
await this._starsService.getAllGitHubRepositories();
|
||||
|
||||
for (const repository of allGitHubRepositories) {
|
||||
this._workerServiceProducer.emit('check_stars', {
|
||||
payload: { login: repository.login },
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
import { Injectable } from '@nestjs/common';
|
||||
import { Cron } from '@nestjs/schedule';
|
||||
import { BullMqClient } from '@gitroom/nestjs-libraries/bull-mq-transport-new/client';
|
||||
|
||||
@Injectable()
|
||||
export class SyncTrending {
|
||||
constructor(private _workerServiceProducer: BullMqClient) {}
|
||||
@Cron('0 * * * *')
|
||||
async syncTrending() {
|
||||
this._workerServiceProducer.emit('sync_trending', {}).subscribe();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
// @ts-check
|
||||
import { withSentryConfig } from '@sentry/nextjs';
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
experimental: {
|
||||
|
|
@ -40,4 +42,10 @@ const nextConfig = {
|
|||
];
|
||||
},
|
||||
};
|
||||
export default nextConfig;
|
||||
export default !!process.env.SENTRY_ORG
|
||||
? withSentryConfig(nextConfig, {
|
||||
org: process.env.SENTRY_ORG,
|
||||
project: process.env.SENTRY_PROJECT,
|
||||
authToken: process.env.SENTRY_AUTH_TOKEN,
|
||||
})
|
||||
: nextConfig;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { SentryComponent } from '@gitroom/frontend/components/layout/sentry.component';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
import '../global.scss';
|
||||
import 'react-tooltip/dist/react-tooltip.css';
|
||||
|
|
@ -33,7 +35,9 @@ export default async function AppLayout({ children }: { children: ReactNode }) {
|
|||
<head>
|
||||
<link rel="icon" href="/favicon.ico" sizes="any" />
|
||||
</head>
|
||||
<body className={clsx(jakartaSans.className, 'dark text-primary !bg-primary')}>
|
||||
<body
|
||||
className={clsx(jakartaSans.className, 'dark text-primary !bg-primary')}
|
||||
>
|
||||
<HtmlComponent />
|
||||
<VariableContextComponent
|
||||
storageProvider={
|
||||
|
|
@ -56,6 +60,7 @@ export default async function AppLayout({ children }: { children: ReactNode }) {
|
|||
isSecured={!process.env.NOT_SECURED}
|
||||
disableImageCompression={!!process.env.DISABLE_IMAGE_COMPRESSION}
|
||||
disableXAnalytics={!!process.env.DISABLE_X_ANALYTICS}
|
||||
sentryDsn={process.env.NEXT_PUBLIC_SENTRY_DSN!}
|
||||
language={allHeaders.get(headerName)}
|
||||
transloadit={
|
||||
process.env.TRANSLOADIT_AUTH && process.env.TRANSLOADIT_TEMPLATE
|
||||
|
|
@ -66,21 +71,23 @@ export default async function AppLayout({ children }: { children: ReactNode }) {
|
|||
: []
|
||||
}
|
||||
>
|
||||
<ToltScript />
|
||||
<FacebookComponent />
|
||||
<Plausible
|
||||
domain={!!process.env.IS_GENERAL ? 'postiz.com' : 'gitroom.com'}
|
||||
>
|
||||
<PHProvider
|
||||
phkey={process.env.NEXT_PUBLIC_POSTHOG_KEY}
|
||||
host={process.env.NEXT_PUBLIC_POSTHOG_HOST}
|
||||
<SentryComponent>
|
||||
<ToltScript />
|
||||
<FacebookComponent />
|
||||
<Plausible
|
||||
domain={!!process.env.IS_GENERAL ? 'postiz.com' : 'gitroom.com'}
|
||||
>
|
||||
<LayoutContext>
|
||||
<UtmSaver />
|
||||
{children}
|
||||
</LayoutContext>
|
||||
</PHProvider>
|
||||
</Plausible>
|
||||
<PHProvider
|
||||
phkey={process.env.NEXT_PUBLIC_POSTHOG_KEY}
|
||||
host={process.env.NEXT_PUBLIC_POSTHOG_HOST}
|
||||
>
|
||||
<LayoutContext>
|
||||
<UtmSaver />
|
||||
{children}
|
||||
</LayoutContext>
|
||||
</PHProvider>
|
||||
</Plausible>
|
||||
</SentryComponent>
|
||||
</VariableContextComponent>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ export default async function AppLayout({ children }: { children: ReactNode }) {
|
|||
isSecured={!process.env.NOT_SECURED}
|
||||
disableImageCompression={!!process.env.DISABLE_IMAGE_COMPRESSION}
|
||||
disableXAnalytics={!!process.env.DISABLE_X_ANALYTICS}
|
||||
sentryDsn={process.env.NEXT_PUBLIC_SENTRY_DSN!}
|
||||
transloadit={
|
||||
process.env.TRANSLOADIT_AUTH && process.env.TRANSLOADIT_TEMPLATE
|
||||
? [
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
'use client';
|
||||
import * as Sentry from '@sentry/nextjs';
|
||||
import NextError from 'next/error';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
export default function GlobalError({
|
||||
error,
|
||||
}: {
|
||||
error: Error & { digest?: string };
|
||||
}) {
|
||||
useEffect(() => {
|
||||
Sentry.captureException(error);
|
||||
}, [error]);
|
||||
return (
|
||||
<html>
|
||||
<body>
|
||||
<NextError statusCode={0} />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
'use client';
|
||||
|
||||
import { FC, ReactNode, useEffect } from 'react';
|
||||
import { useVariables } from '@gitroom/react/helpers/variable.context';
|
||||
import { initializeSentryClient } from '@gitroom/react/sentry/initialize.sentry.client';
|
||||
|
||||
export const SentryComponent: FC<{ children: ReactNode }> = ({ children }) => {
|
||||
const { sentryDsn: dsn } = useVariables();
|
||||
|
||||
useEffect(() => {
|
||||
if (!dsn) {
|
||||
return ;
|
||||
}
|
||||
|
||||
try {
|
||||
initializeSentryClient(dsn);
|
||||
} catch (error) {
|
||||
console.error('[Sentry] Configuration error:', error);
|
||||
}
|
||||
}, [dsn]);
|
||||
|
||||
// Always render children - don't block the app
|
||||
return <>{children}</>;
|
||||
};
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
export async function register() {
|
||||
if (!process.env.NEXT_PUBLIC_SENTRY_DSN) {
|
||||
return;
|
||||
}
|
||||
if (process.env.NEXT_RUNTIME === 'nodejs') {
|
||||
await import('./sentry.server.config');
|
||||
}
|
||||
if (process.env.NEXT_RUNTIME === 'edge') {
|
||||
await import('./sentry.edge.config');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import { initializeSentryServer } from '@gitroom/react/sentry/initialize.sentry.server';
|
||||
|
||||
initializeSentryServer(process.env.NEXT_PUBLIC_SENTRY_DSN);
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import { initializeSentryServer } from '@gitroom/react/sentry/initialize.sentry.server';
|
||||
|
||||
initializeSentryServer(process.env.NEXT_PUBLIC_SENTRY_DSN);
|
||||
|
|
@ -1,17 +1,15 @@
|
|||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { DatabaseModule } from '@gitroom/nestjs-libraries/database/prisma/database.module';
|
||||
import { TrendingService } from '@gitroom/nestjs-libraries/services/trending.service';
|
||||
import { PostsController } from '@gitroom/workers/app/posts.controller';
|
||||
import { BullMqModule } from '@gitroom/nestjs-libraries/bull-mq-transport-new/bull.mq.module';
|
||||
import { PlugsController } from '@gitroom/workers/app/plugs.controller';
|
||||
import { SentryModule } from '@sentry/nestjs/setup';
|
||||
import { FILTER } from '@gitroom/nestjs-libraries/sentry/sentry.exception';
|
||||
|
||||
@Module({
|
||||
imports: [DatabaseModule, BullMqModule],
|
||||
controllers: [
|
||||
PostsController,
|
||||
PlugsController,
|
||||
],
|
||||
providers: [TrendingService],
|
||||
imports: [SentryModule.forRoot(), DatabaseModule, BullMqModule],
|
||||
controllers: [PostsController, PlugsController],
|
||||
providers: [FILTER],
|
||||
})
|
||||
export class AppModule {}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ import { NestFactory } from '@nestjs/core';
|
|||
import { AppModule } from './app/app.module';
|
||||
import { MicroserviceOptions } from '@nestjs/microservices';
|
||||
import { BullMqServer } from '@gitroom/nestjs-libraries/bull-mq-transport-new/strategy';
|
||||
import { initializeSentry } from '@gitroom/nestjs-libraries/sentry/initialize.sentry';
|
||||
|
||||
initializeSentry();
|
||||
|
||||
async function bootstrap() {
|
||||
process.env.IS_WORKER = 'true';
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
import * as Sentry from '@sentry/nestjs';
|
||||
import { nodeProfilingIntegration } from "@sentry/profiling-node";
|
||||
|
||||
export const initializeSentry = () => {
|
||||
if (!process.env.NEXT_PUBLIC_SENTRY_DSN) {
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log('loading sentry');
|
||||
Sentry.init({
|
||||
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
|
||||
integrations: [
|
||||
// Add our Profiling integration
|
||||
nodeProfilingIntegration(),
|
||||
],
|
||||
tracesSampleRate: 1.0,
|
||||
profilesSampleRate: 1.0,
|
||||
});
|
||||
|
||||
return true;
|
||||
};
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import { APP_FILTER } from "@nestjs/core";
|
||||
import { SentryGlobalFilter } from "@sentry/nestjs/setup";
|
||||
|
||||
export const FILTER = {
|
||||
provide: APP_FILTER,
|
||||
useClass: SentryGlobalFilter,
|
||||
};
|
||||
|
|
@ -22,6 +22,7 @@ interface VariableContextInterface {
|
|||
language: string;
|
||||
tolt: string;
|
||||
transloadit: string[];
|
||||
sentryDsn: string;
|
||||
}
|
||||
const VariableContext = createContext({
|
||||
billingEnabled: false,
|
||||
|
|
@ -44,6 +45,7 @@ const VariableContext = createContext({
|
|||
language: '',
|
||||
tolt: '',
|
||||
transloadit: [],
|
||||
sentryDsn: '',
|
||||
} as VariableContextInterface);
|
||||
export const VariableContextComponent: FC<
|
||||
VariableContextInterface & {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
import * as Sentry from '@sentry/nextjs';
|
||||
import { initializeSentryBasic } from '@gitroom/react/sentry/initialize.sentry.next.basic';
|
||||
|
||||
export const initializeSentryClient = (dsn: string) =>
|
||||
initializeSentryBasic(dsn, {
|
||||
integrations: [
|
||||
// Add default integrations back
|
||||
Sentry.browserTracingIntegration(),
|
||||
Sentry.replayIntegration({
|
||||
maskAllText: true,
|
||||
maskAllInputs: true,
|
||||
}),
|
||||
],
|
||||
replaysSessionSampleRate:
|
||||
process.env.NODE_ENV === 'development' ? 1.0 : 0.1,
|
||||
replaysOnErrorSampleRate: 1.0,
|
||||
});
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import * as Sentry from '@sentry/nextjs';
|
||||
|
||||
export const initializeSentryBasic = (dsn: string, extension: any) => {
|
||||
if (!dsn) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sentry.init({
|
||||
initialScope: {
|
||||
tags: {
|
||||
service: 'frontend',
|
||||
component: 'nextjs',
|
||||
replaysEnabled: 'true',
|
||||
},
|
||||
contexts: {
|
||||
app: {
|
||||
name: 'Postiz Frontend',
|
||||
version: process.env.NEXT_PUBLIC_APP_VERSION || '0.0.0',
|
||||
},
|
||||
},
|
||||
},
|
||||
dsn,
|
||||
sendDefaultPii: true,
|
||||
...extension,
|
||||
debug: process.env.NODE_ENV === 'development',
|
||||
tracesSampleRate: process.env.NODE_ENV === 'development' ? 1.0 : 0.1,
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import * as Sentry from '@sentry/nextjs';
|
||||
import { initializeSentryBasic } from '@gitroom/react/sentry/initialize.sentry.next.basic';
|
||||
|
||||
export const initializeSentryServer = (dsn: string) =>
|
||||
initializeSentryBasic(dsn, {});
|
||||
|
|
@ -73,6 +73,9 @@
|
|||
"@neynar/react": "^0.9.7",
|
||||
"@postiz/wallets": "^0.0.1",
|
||||
"@prisma/client": "^6.5.0",
|
||||
"@sentry/nestjs": "^9.43.0",
|
||||
"@sentry/nextjs": "^9.43.0",
|
||||
"@sentry/profiling-node": "^9.43.0",
|
||||
"@solana/wallet-adapter-react": "^0.15.35",
|
||||
"@solana/wallet-adapter-react-ui": "^0.9.35",
|
||||
"@swc/helpers": "0.5.13",
|
||||
|
|
|
|||
1190
pnpm-lock.yaml
1190
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue