Skip to content

Commit

Permalink
chore: add sentry to keep-ui (#2416)
Browse files Browse the repository at this point in the history
Co-authored-by: Tal <[email protected]>
  • Loading branch information
Kiryous and talboren authored Nov 13, 2024
1 parent 76dbd7b commit 48f5a54
Show file tree
Hide file tree
Showing 26 changed files with 4,820 additions and 4,353 deletions.
3 changes: 2 additions & 1 deletion docker-compose.common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ services:
- NEXTAUTH_URL=http://localhost:3000
- NEXT_PUBLIC_API_URL=http://localhost:8080
- POSTHOG_KEY=phc_muk9qE3TfZsX3SZ9XxX52kCGJBclrjhkP9JxAQcm1PZ
- POSTHOG_HOST=https://app.posthog.com
- POSTHOG_HOST=https://ingest.keephq.dev
- NEXT_PUBLIC_SENTRY_DSN=https://0d4d59e3105ffe8afa27dcb95a222009@o4505515398922240.ingest.us.sentry.io/4508258058764288
- PUSHER_HOST=localhost
- PUSHER_PORT=6001
- PUSHER_APP_KEY=keepappkey
Expand Down
1 change: 1 addition & 0 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ services:
service: keep-frontend-common
environment:
- API_URL=http://keep-backend-dev:8080
- SENTRY_DISABLED=true
build:
dockerfile: docker/Dockerfile.dev.ui
volumes:
Expand Down
3 changes: 2 additions & 1 deletion docker/Dockerfile.ui
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,11 @@ EXPOSE 3000

ENV PORT 3000
ENV POSTHOG_KEY=phc_muk9qE3TfZsX3SZ9XxX52kCGJBclrjhkP9JxAQcm1PZ
ENV POSTHOG_HOST=https://app.posthog.com
ENV POSTHOG_HOST=https://ingest.keephq.dev
ENV PUSHER_HOST=localhost
ENV PUSHER_PORT=6001
ENV PUSHER_APP_KEY=keepappkey
ENV NEXT_PUBLIC_SENTRY_DSN=https://0d4d59e3105ffe8afa27dcb95a222009@o4505515398922240.ingest.us.sentry.io/4508258058764288


ENTRYPOINT ["/app/entrypoint.sh"]
9 changes: 9 additions & 0 deletions docs/deployment/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,15 @@ Posthog configuration controls Keep's integration with the Posthog analytics pla
| **POSTHOG_API_KEY** | API key for PostHog analytics | No | "phc_muk9qE3TfZsX3SZ9XxX52kCGJBclrjhkP9JxAQcm1PZ" | Valid PostHog API key |
| **POSTHOG_DISABLED** | Disables PostHog integration | No | "false" | "true" or "false" |

### Sentry
<Info>
Sentry configuration controls Keep's integration with Sentry for error monitoring and reporting. These settings are important for maintaining the stability and reliability of your Keep instance.
</Info>

| Env var | Purpose | Required | Default Value | Valid options |
|:-------------------:|:-------:|:----------:|:-------------:|:-------------:|
| **SENTRY_DISABLED** | Disables Sentry integration | No | "false" | "true" or "false" |

### Ngrok
<Info>
Ngrok configuration enables secure tunneling to your Keep instance. These settings are particularly useful for development or when you need to expose your local Keep instance to the internet securely.
Expand Down
3 changes: 3 additions & 0 deletions keep-ui/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,6 @@ jspm_packages

app/topology/mock-topology-data.tsx
.vercel

# Sentry Config File
.env.sentry-build-plugin
9 changes: 6 additions & 3 deletions keep-ui/app/error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import "./error.css";
import { useEffect } from "react";
import { Title, Subtitle } from "@tremor/react";
import { Button, Text } from "@tremor/react";
import { signOut } from "next-auth/react";
import { KeepApiError } from "@/shared/lib/KeepApiError";
import * as Sentry from "@sentry/nextjs";
import { useSignOut } from "@/shared/lib/useSignOut";

export default function ErrorComponent({
error,
Expand All @@ -19,8 +20,10 @@ export default function ErrorComponent({
error: Error | KeepApiError;
reset: () => void;
}) {
const signOut = useSignOut();

useEffect(() => {
console.error(error);
Sentry.captureException(error);
}, [error]);

return (
Expand Down Expand Up @@ -48,7 +51,7 @@ export default function ErrorComponent({
</div>
{error instanceof KeepApiError && error.statusCode === 401 ? (
<Button
onClick={() => signOut()}
onClick={signOut}
color="orange"
variant="secondary"
className="mt-4 border border-orange-500 text-orange-500"
Expand Down
23 changes: 23 additions & 0 deletions keep-ui/app/global-error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"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` is the default Next.js error page component. Its type
definition requires a `statusCode` prop. However, since the App Router
does not expose status codes for errors, we simply pass 0 to render a
generic error message. */}
<NextError statusCode={0} />
</body>
</html>
);
}
3 changes: 2 additions & 1 deletion keep-ui/components/navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import { MinimizeMenuButton } from "components/navbar/MinimizeMenuButton";
import { authOptions } from "pages/api/auth/[...nextauth]";
import { DashboardLinks } from "@/components/navbar/DashboardLinks";
import { IncidentsLinks } from "@/components/navbar/IncidentLinks";
import { SetSentryUser } from "./SetSentryUser";
import "./Navbar.css";

export default async function NavbarInner() {
const session = await getServerSession(authOptions);

return (
<>
<Menu>
Expand All @@ -26,6 +26,7 @@ export default async function NavbarInner() {
<UserInfo session={session} />
</Menu>
<MinimizeMenuButton />
<SetSentryUser session={session} />
</>
);
}
9 changes: 9 additions & 0 deletions keep-ui/components/navbar/SetSentryUser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"use client";

import { Session } from "next-auth";
import { useSetSentryUser } from "@/shared/lib/useSetSentryUser";

export function SetSentryUser({ session }: { session: Session | null }) {
useSetSentryUser({ session });
return null;
}
6 changes: 4 additions & 2 deletions keep-ui/components/navbar/UserInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import { Menu } from "@headlessui/react";
import { LinkWithIcon } from "components/LinkWithIcon";
import { Session } from "next-auth";
import { signOut } from "next-auth/react";
import { useConfig } from "utils/hooks/useConfig";
import { AuthenticationType } from "utils/authenticationType";
import Link from "next/link";
Expand All @@ -17,6 +16,8 @@ import UserAvatar from "./UserAvatar";
import * as Frigade from "@frigade/react";
import { useState } from "react";
import Onboarding from "./Onboarding";
import { useSignOut } from "@/shared/lib/useSignOut";
import { useSetSentryUser } from "@/shared/lib/useSetSentryUser";

type UserDropdownProps = {
session: Session;
Expand All @@ -27,6 +28,7 @@ const UserDropdown = ({ session }: UserDropdownProps) => {
const { name, image, email } = user;

const { data: configData } = useConfig();
const signOut = useSignOut();
const { refs, floatingStyles } = useFloating({
placement: "right-end",
strategy: "fixed",
Expand Down Expand Up @@ -70,7 +72,7 @@ const UserDropdown = ({ session }: UserDropdownProps) => {
<Menu.Item
as="button"
className="ui-active:bg-orange-400 ui-active:text-white ui-not-active:text-gray-900 group flex w-full items-center rounded-md px-2 py-2 text-sm"
onClick={() => signOut()}
onClick={signOut}
>
Sign out
</Menu.Item>
Expand Down
22 changes: 22 additions & 0 deletions keep-ui/instrumentation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// @ts-nocheck
import * as Sentry from "@sentry/nextjs";

export async function register() {
if (
process.env.SENTRY_DISABLED === "true" ||
process.env.NODE_ENV === "development"
) {
return;
}

if (process.env.NEXT_RUNTIME === "nodejs") {
await import("./sentry.server.config");
}

if (process.env.NEXT_RUNTIME === "edge") {
await import("./sentry.edge.config");
}
}

// We need NextJS 15 to use this
export const onRequestError = Sentry.captureRequestError;
2 changes: 1 addition & 1 deletion keep-ui/middleware.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,6 @@ export default withAuth(

export const config = {
matcher: [
"/((?!keep_big\\.svg$|gnip\\.webp|signin$|api/aws-marketplace$).*)",
"/((?!keep_big\\.svg$|gnip\\.webp|signin$|api/aws-marketplace$|monitoring).*)",
], // Adjust as needed
};
65 changes: 60 additions & 5 deletions keep-ui/next.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const { withSentryConfig } = require("@sentry/nextjs");

/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: false,
Expand Down Expand Up @@ -34,7 +36,8 @@ const nextConfig = {
: process.env.REMOVE_CONSOLE === "true",
},
output: "standalone",
productionBrowserSourceMaps: process.env.ENV === "development",
productionBrowserSourceMaps:
process.env.ENV === "development" || process.env.SENTRY_DISABLED !== "true",
async redirects() {
return process.env.DISABLE_REDIRECTS === "true"
? []
Expand Down Expand Up @@ -66,8 +69,60 @@ const nextConfig = {
},
};

const withBundleAnalyzer = require("@next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true",
});
const sentryConfig = {
// For all available options, see:
// https://github.com/getsentry/sentry-webpack-plugin#options

org: "keep-hq",
project: "keep-ui",

// Only print logs for uploading source maps in CI
silent: !process.env.CI,

// For all available options, see:
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/

// Automatically annotate React components to show their full name in breadcrumbs and session replay
reactComponentAnnotation: {
enabled: true,
},

// Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.
// 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",

// Hides source maps from generated client bundles
hideSourceMaps: true,

// Automatically tree-shake Sentry logger statements to reduce bundle size
disableLogger: true,

// Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)
// See the following for more information:
// https://docs.sentry.io/product/crons/
// https://vercel.com/docs/cron-jobs
automaticVercelMonitors: true,
};

const isSentryDisabled =
process.env.SENTRY_DISABLED === "true" ||
process.env.NODE_ENV === "development";

// Compose the final config
let config = nextConfig;

// Add Sentry if enabled
if (!isSentryDisabled) {
config = withSentryConfig(config, sentryConfig);
}

// Add Bundle Analyzer only when analysis is requested
if (process.env.ANALYZE === "true") {
config = require("@next/bundle-analyzer")({
enabled: true,
})(config);
}

module.exports = withBundleAnalyzer(nextConfig);
module.exports = config;
Loading

0 comments on commit 48f5a54

Please sign in to comment.