SKILL.md
Clerk Observability
Overview
Implement monitoring, logging, and observability for Clerk authentication. Covers structured auth logging, middleware performance tracking, webhook event monitoring, Sentry integration, and health check endpoints.
Prerequisites
- Clerk integration working
- Monitoring platform (Sentry, DataDog, or Pino logger at minimum)
- Logging infrastructure (structured JSON logs recommended)
Instructions
Step 1: Structured Authentication Event Logging
// lib/auth-logger.ts
import pino from 'pino'
const logger = pino({
level: process.env.LOG_LEVEL || 'info',
transport: process.env.NODE_ENV === 'development' ? { target: 'pino-pretty' } : undefined,
})
export function logAuthEvent(event: {
type: 'sign_in' | 'sign_out' | 'sign_up' | 'permission_denied' | 'session_expired'
userId?: string | null
orgId?: string | null
path: string
metadata?: Record<string, any>
}) {
logger.info({
category: 'auth',
...event,
timestamp: new Date().toISOString(),
})
}
export function logAuthError(error: Error, context: { userId?: string; path: string }) {
logger.error({
category: 'auth',
error: error.message,
stack: error.stack,
...context,
timestamp: new Date().toISOString(),
})
}
Step 2: Middleware Performance Monitoring
// middleware.ts
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'
const isPublicRoute = createRouteMatcher(['/', '/sign-in(.*)', '/sign-up(.*)'])
export default clerkMiddleware(async (auth, req) => {
const start = Date.now()
if (!isPublicRoute(req)) {
await auth.protect()
}
const duration = Date.now() - start
const { userId } = await auth()
// Log slow auth checks
if (duration > 100) {
console.warn(`[Auth Perf] ${req.nextUrl.pathname} took ${duration}ms`, {
userId: userId || 'anonymous',
method: req.method,
})
}
// Add timing header for debugging
const response = new Response(null, { status: 200 })
response.headers.set('X-Auth-Duration', `${duration}ms`)
})
