Files
at-mintel/packages/observability/README.md
Marc Mintel 61e78ea672
All checks were successful
Monorepo Pipeline / 🧪 Quality Assurance (push) Successful in 3m50s
Monorepo Pipeline / 🚀 Release (push) Successful in 3m38s
Monorepo Pipeline / 🐳 Build & Push Images (push) Successful in 7m6s
feat: integrate observability
2026-02-07 10:23:51 +01:00

124 lines
2.9 KiB
Markdown

# @mintel/observability
Standardized observability package for the Mintel ecosystem, providing Umami analytics and Sentry/GlitchTip error tracking with a focus on privacy and ad-blocker resilience.
## Features
- **Umami Smart Proxy**: Track analytics without external scripts and hide your Website ID.
- **Sentry Relay**: Bypass ad-blockers for error tracking by relaying envelopes through your own server.
- **Unified API**: consistent interface for tracking across multiple projects.
## Installation
```bash
pnpm add @mintel/observability @sentry/nextjs
```
## Usage
### 1. Unified Environment (via @mintel/next-utils)
Define the following environment variables:
```bash
# Analytics
UMAMI_WEBSITE_ID=your-website-id
UMAMI_API_ENDPOINT=https://analytics.infra.mintel.me
# Error Tracking
SENTRY_DSN=your-sentry-dsn
```
Note: No `NEXT_PUBLIC_` prefix is required for these anymore, as they are handled by server-side proxies.
### 2. Analytics Setup
In your root layout:
```tsx
import {
AnalyticsContextProvider,
AnalyticsAutoTracker,
UmamiAnalyticsService,
} from "@mintel/observability";
const analytics = new UmamiAnalyticsService({
enabled: true,
websiteId: process.env.UMAMI_WEBSITE_ID, // Server-side
apiEndpoint:
typeof window === "undefined" ? process.env.UMAMI_API_ENDPOINT : "/stats",
});
export default function Layout({ children }) {
return (
<AnalyticsContextProvider service={analytics}>
<AnalyticsAutoTracker />
{children}
</AnalyticsContextProvider>
);
}
```
### 3. Route Handlers
Create a proxy for Umami:
`app/stats/api/send/route.ts`
```ts
import { createUmamiProxyHandler } from "@mintel/observability";
export const POST = await createUmamiProxyHandler({
websiteId: process.env.UMAMI_WEBSITE_ID,
apiEndpoint: process.env.UMAMI_API_ENDPOINT,
});
```
Create a relay for Sentry:
`app/errors/api/relay/route.ts`
```ts
import { createSentryRelayHandler } from "@mintel/observability";
export const POST = await createSentryRelayHandler({
dsn: process.env.SENTRY_DSN,
});
```
### 4. Notification Setup (Server-side)
```ts
import { GotifyNotificationService } from "@mintel/observability";
const notifications = new GotifyNotificationService({
enabled: true,
url: process.env.GOTIFY_URL,
token: process.env.GOTIFY_TOKEN,
});
await notifications.notify({
title: "Lead Capture",
message: "New contact form submission",
priority: 5,
});
```
### 5. Sentry Configuration
Use `initSentry` in your `sentry.server.config.ts` and `sentry.client.config.ts`.
On the client, use the tunnel:
```ts
initSentry({
dsn: "https://public@errors.infra.mintel.me/1", // Placeholder
tunnel: "/errors/api/relay",
});
```
## Architecture
This package implements the **Smart Proxy** pattern:
- The client NEVER knows the real `UMAMI_WEBSITE_ID`.
- Tracking events are sent to your own domain (`/stats/api/send`).
- Your server injects the secret ID and forwards to Umami.
- This bypasses ad-blockers and keeps your configuration secure.