# Monitoring Overview

> Current monitoring behavior in the Next.js Drizzle SaaS Kit.

*Canonical: https://makerkit.dev/docs/nextjs-drizzle/monitoring/overview*

---

The monitoring layer in this repo is extensible, but the checked-in runtime currently supports one built-in provider: Sentry.

## Current State

- `@kit/monitoring-core` provides the base service types and console fallback
- `@kit/monitoring` provides provider selection, hooks, server helpers, and the instrumentation entrypoints
- `@kit/sentry` is the only registered concrete provider in the repo
- If `NEXT_PUBLIC_MONITORING_PROVIDER` is unset, the app falls back to console logging

## Architecture

Errors enter monitoring through three paths, each provider-agnostic:

- **`apps/web/instrumentation.ts`** — calls `registerMonitoringInstrumentation()` on boot, then forwards `onRequestError` to the configured provider. Server errors from RSC, Server Actions, and Route Handlers are captured here, with Next.js context (route, method, headers).
- **`apps/web/instrumentation-client.ts`** — calls `registerClientMonitoringInstrumentation()`, which installs the kit's own `window.onerror` and `unhandledrejection` handlers, lazily loads the provider chunk in parallel with hydration, and buffers any errors that fire before init resolves.
- **`useCaptureException` / `useMonitoring` / `getServerMonitoringService`** — manual capture from your code (see [Capturing Errors](./capturing-errors)).

### Dedup invariant

Next.js attaches `error.digest` only to errors that originated server-side. The kit's `error.tsx` skips capture when a digest is present, on the assumption that the configured provider's `onRequestError` already recorded it. Custom providers must honor this contract.

### Capturing outside the provider tree

`global-error.tsx` replaces the root layout, so the React `MonitoringContext` isn't available. Use `captureClientException` from `@kit/monitoring/instrumentation-client` in that shell.

## Supported Provider Values

Current runtime support:

- `sentry`
- empty / unset value for console fallback

Other provider names are not registered by default in this repository.

## Quick Start

```bash {% title="apps/web/.env.local" %}
NEXT_PUBLIC_MONITORING_PROVIDER=sentry
NEXT_PUBLIC_SENTRY_DSN=https://xxxxx@xxxxx.ingest.sentry.io/xxxxx
```

## Manual Capture

Client-side:

```tsx
import { useMonitoring } from '@kit/monitoring/hooks';

function MyComponent() {
  const monitoring = useMonitoring();

  async function onSubmit() {
    try {
      await submitForm();
    } catch (error) {
      monitoring.captureException(error as Error, {
        context: 'form_submission',
      });
    }
  }
}
```

Server-side:

```typescript
import { getServerMonitoringService } from '@kit/monitoring/server';

export async function processPayment() {
  const monitoring = await getServerMonitoringService();

  try {
    // ...
  } catch (error) {
    await monitoring.captureException(error as Error);
    throw error;
  }
}
```

## Extending Monitoring

You can add more providers, but they are not prewired in this repo. A new provider requires registration in the client provider component, the server service, and both instrumentation registries (client + server). See [Custom Monitoring Provider](./custom-monitoring-provider) for the full pattern.

## Topics

1. [Sentry](./sentry)
2. [Custom Monitoring Provider](./custom-monitoring-provider)
3. [Capturing Errors](./capturing-errors)
