Monitoring & Logs

Track performance and debug issues in production

📊 What is Monitoring?

Monitoring tracks your Next.js app's performance, errors, and user behavior in production. Logging captures detailed information about requests, errors, and system events, helping you debug issues and optimize performance for better user experience.


// Basic logging example
console.log('User logged in:', userId)
console.error('Payment failed:', error)
                                    

Monitoring Types

Performance

Track speed and load times

Page Load API Response Core Web Vitals
🐛

Error Tracking

Catch and log errors

Exceptions Stack Traces User Context
👥

User Analytics

Understand user behavior

Page Views Events Conversions
📝

Application Logs

Record system events

Requests Database Custom Events

🔹 Basic Console Logging

Use console methods to log information during development and production. Different log levels help categorize messages by severity. Console logs appear in server logs for server components and browser console for client components.

// app/api/users/route.ts
export async function GET() {
  console.log('Fetching users...') // Info
  console.warn('Cache is stale') // Warning
  console.error('Database connection failed') // Error
  
  try {
    const users = await fetchUsers()
    console.log('Users fetched:', users.length)
    return Response.json(users)
  } catch (error) {
    console.error('Error fetching users:', error)
    return Response.json({ error: 'Failed' }, { status: 500 })
  }
}

🔹 Structured Logging

Create structured logs with consistent formatting for easier parsing and analysis. Include timestamps, request IDs, and context information. This makes it easier to search and filter logs in production environments.

// lib/logger.ts
type LogLevel = 'info' | 'warn' | 'error'

export function log(level: LogLevel, message: string, meta?: any) {
  const logEntry = {
    timestamp: new Date().toISOString(),
    level,
    message,
    ...meta,
  }
  
  console.log(JSON.stringify(logEntry))
}

// Usage in your app
import { log } from '@/lib/logger'

log('info', 'User logged in', { userId: '123', email: '[email protected]' })
log('error', 'Payment failed', { orderId: '456', error: 'Card declined' })

🔹 Error Tracking with Sentry

Sentry automatically captures errors, provides stack traces, and tracks error frequency. It helps you identify and fix issues quickly by showing exactly where errors occur and how often they happen in production.

# Install Sentry
npm install @sentry/nextjs
// sentry.client.config.js
import * as Sentry from '@sentry/nextjs'

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  tracesSampleRate: 1.0,
  environment: process.env.NODE_ENV,
})

// sentry.server.config.js
import * as Sentry from '@sentry/nextjs'

Sentry.init({
  dsn: process.env.SENTRY_DSN,
  tracesSampleRate: 1.0,
})
// app/api/checkout/route.ts
import * as Sentry from '@sentry/nextjs'

export async function POST(request: Request) {
  try {
    const result = await processPayment()
    return Response.json(result)
  } catch (error) {
    // Automatically sent to Sentry
    Sentry.captureException(error)
    return Response.json({ error: 'Payment failed' }, { status: 500 })
  }
}

🔹 Performance Monitoring

Track Core Web Vitals and custom performance metrics. Next.js provides built-in performance monitoring through the Web Vitals API. Monitor page load times, API response times, and user interactions to optimize performance.

// app/layout.tsx
import { Analytics } from '@vercel/analytics/react'
import { SpeedInsights } from '@vercel/speed-insights/next'

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Analytics />
        <SpeedInsights />
      </body>
    </html>
  )
}
// app/components/web-vitals.tsx
'use client'

import { useReportWebVitals } from 'next/web-vitals'

export function WebVitals() {
  useReportWebVitals((metric) => {
    console.log(metric)
    // Send to analytics service
    if (metric.label === 'web-vital') {
      // Track: LCP, FID, CLS, FCP, TTFB
      fetch('/api/analytics', {
        method: 'POST',
        body: JSON.stringify(metric),
      })
    }
  })
  
  return null
}

🔹 Custom Event Tracking

Track user interactions and business events. Monitor button clicks, form submissions, purchases, and other important actions. This data helps you understand user behavior and improve your application.

// lib/analytics.ts
export function trackEvent(eventName: string, properties?: any) {
  // Send to your analytics service
  console.log('Event:', eventName, properties)
  
  // Example: Send to Google Analytics
  if (typeof window !== 'undefined' && window.gtag) {
    window.gtag('event', eventName, properties)
  }
}

// Usage in components
'use client'

import { trackEvent } from '@/lib/analytics'

export default function CheckoutButton() {
  const handleClick = () => {
    trackEvent('checkout_started', {
      value: 99.99,
      currency: 'USD',
      items: ['product-1', 'product-2'],
    })
  }
  
  return <button onClick={handleClick}>Checkout</button>
}

🔹 Request Logging Middleware

Log all incoming requests with details like method, URL, response time, and status code. Middleware runs on every request, making it perfect for centralized logging and monitoring of your API routes.

// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  const start = Date.now()
  
  // Log request
  console.log({
    method: request.method,
    url: request.url,
    timestamp: new Date().toISOString(),
  })
  
  const response = NextResponse.next()
  
  // Log response time
  const duration = Date.now() - start
  console.log({
    url: request.url,
    duration: `${duration}ms`,
    status: response.status,
  })
  
  return response
}

export const config = {
  matcher: '/api/:path*',
}

🔹 Monitoring Best Practices

Follow these guidelines for effective monitoring and logging:

Key Practices:

  • Log levels: Use appropriate levels (info, warn, error)
  • Structured logs: Use JSON format for easy parsing
  • Context: Include user ID, request ID, timestamps
  • Sensitive data: Never log passwords or tokens
  • Performance: Monitor Core Web Vitals regularly
  • Alerts: Set up notifications for critical errors
  • Retention: Define log retention policies

🧠 Test Your Knowledge

Which Vercel package tracks Core Web Vitals?