nuxt-monitoring

A Nuxt module for observability: debug server, health checks, and Prometheus metrics collection
4,816 7
Install
npm install nuxt-monitoring
Latest Version:1.3.0
Vue:3
License:MIT
Last Updated:Mar 22, 2026
Links: GitHub  ·  npm
Maintainer: nzweb

nuxt-monitoring

npm version npm downloads License Nuxt

A comprehensive Nuxt module for application observability providing debug server, health checks, and Prometheus metrics collection with CORS support.

Features

  • 🐞  Debug Server - Separate port for monitoring endpoints with CORS support
  • 🩺  Health Checks - /health endpoint with programmatic state management
  • 🚀  Readiness Probes - /ready endpoint for container orchestration
  • 📊  Prometheus Metrics - Comprehensive HTTP and Node.js runtime metrics
  • 🌐  CORS Support - Built-in cross-origin headers for all monitoring endpoints
  • 🔧  TypeScript - Full type safety and IntelliSense support
  • 🎯  Programmatic API - Manage health state from your application code
  • ✨  Custom Metrics - Extend with your own application-specific metrics

Installation

Install the module via npm, yarn, or pnpm:

# npm
npm install nuxt-monitoring

# yarn
yarn add nuxt-monitoring

# pnpm
pnpm add nuxt-monitoring

Add the module to your nuxt.config.ts:

export default defineNuxtConfig({
  modules: ['nuxt-monitoring']
})

⚠️ Important: By default, all endpoints are disabled. You need to explicitly enable the ones you want to use:

// Minimal setup - enable health checks only
export default defineNuxtConfig({
  modules: ['nuxt-monitoring'],
  monitoring: {
    healthCheck: { enabled: true }
  }
})

// Full setup - enable all endpoints
export default defineNuxtConfig({
  modules: ['nuxt-monitoring'],
  monitoring: {
    metrics: { enabled: true },
    healthCheck: { enabled: true },
    readyCheck: { enabled: true }
  }
})

Configuration

🔒 Security by Design: All monitoring endpoints are disabled by default. This ensures your application doesn't expose monitoring data accidentally. You must explicitly enable each endpoint you want to use.

Basic Configuration

Important: All monitoring endpoints are disabled by default. You must explicitly enable the endpoints you need:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['nuxt-monitoring'],
  monitoring: {
    // Metrics endpoint configuration
    metrics: {
      enabled: true,        // Must be explicitly enabled (default: false)
      path: '/metrics'      // Endpoint path for Prometheus metrics
    },

    // Health check endpoint configuration
    healthCheck: {
      enabled: true,        // Must be explicitly enabled (default: false)
      path: '/health'       // Endpoint path for health checks
    },

    // Readiness probe configuration
    readyCheck: {
      enabled: true,        // Must be explicitly enabled (default: false)
      path: '/ready'        // Endpoint path for readiness probes
    },

    // Debug server configuration (optional)
    debugServer: {
      enabled: false,       // Default: false
      port: 3001           // Port for debug server
    }
  }
})

Default Values

All configuration options have the following defaults:

{
  metrics: { enabled: false, path: '/metrics' },
  healthCheck: { enabled: false, path: '/health' },
  readyCheck: { enabled: false, path: '/ready' },
  debugServer: { enabled: false, port: 3001 }
}

Debug Server Mode

Enable the debug server to run monitoring endpoints on a separate port:

export default defineNuxtConfig({
  modules: ['nuxt-monitoring'],
  monitoring: {
    // Enable the endpoints you need
    metrics: { enabled: true },
    healthCheck: { enabled: true },
    readyCheck: { enabled: true },

    // Enable debug server
    debugServer: {
      enabled: true,
      port: 3001          // Monitoring endpoints available at http://localhost:3001
    }
  }
})

Benefits of Debug Server:

  • Isolates monitoring traffic from application traffic
  • Allows separate security policies for monitoring endpoints
  • Enables monitoring even when main application is unresponsive
  • Built-in CORS support for cross-origin monitoring dashboards

Custom Endpoint Paths

Configure custom paths for monitoring endpoints:

export default defineNuxtConfig({
  modules: ['nuxt-monitoring'],
  monitoring: {
    metrics: {
      path: '/custom-metrics'
    },
    healthCheck: {
      path: '/api/health'
    },
    readyCheck: {
      path: '/api/ready'
    }
  }
})

Selective Endpoint Enabling

Enable only the endpoints you need (all are disabled by default):

export default defineNuxtConfig({
  modules: ['nuxt-monitoring'],
  monitoring: {
    // Enable only specific endpoints
    healthCheck: { enabled: true },   // Enable health checks
    readyCheck: { enabled: true },    // Enable readiness checks
    metrics: { enabled: false }       // Keep metrics disabled (default)
  }
})

// Or enable all endpoints
export default defineNuxtConfig({
  modules: ['nuxt-monitoring'],
  monitoring: {
    metrics: { enabled: true },
    healthCheck: { enabled: true },
    readyCheck: { enabled: true }
  }
})

Health Check API

The module provides a robust programmatic API for health state management, enabling applications to report and track component health automatically.

Available Functions

import {
  setHealthError,
  clearHealthError,
  clearAllHealthErrors,
  getHealthState,
  type HealthState,
  type HealthError,
  type HealthResponse
} from 'nuxt-monitoring'

Core Functions

setHealthError(key: string, message: string, code?: string): void

Register a health error for a specific component or service:

// Basic error registration
setHealthError('database', 'Connection timeout')

// Error with custom error code
setHealthError('redis', 'Connection refused', 'ECONNREFUSED')

// Business logic error
setHealthError('payment-service', 'Payment gateway unreachable', 'GATEWAY_TIMEOUT')

Parameters:

  • key (string): Unique identifier for the error component
  • message (string): Human-readable error description
  • code (string, optional): Machine-readable error code
clearHealthError(key: string): void

Remove a health error for a specific component:

// Clear database error when connection is restored
clearHealthError('database')

// Clear service error after successful health check
clearHealthError('payment-service')
clearAllHealthErrors(): void

Remove all health errors and reset to healthy state:

// Reset all health errors (use with caution)
clearAllHealthErrors()
getHealthState(): HealthState

Retrieve the current health state:

const healthState = getHealthState()
console.log(healthState)

// Example output:
// {
//   isHealthy: false,
//   errors: {
//     'database': {
//       message: 'Connection timeout',
//       code: 'TIMEOUT',
//       timestamp: 1640995200000
//     },
//     'redis': {
//       message: 'Connection refused',
//       code: 'ECONNREFUSED',
//       timestamp: 1640995260000
//     }
//   }
// }

Health State Types

interface HealthError {
  message: string           // Error description
  code?: string            // Optional error code
  timestamp: number        // Unix timestamp when error occurred
}

interface HealthState {
  isHealthy: boolean                          // Overall health status
  errors: Record<string, HealthError>         // Map of component errors
}

interface HealthResponse {
  status: 'ok' | 'error'                     // HTTP response status
  errors?: Record<string, HealthError>        // Errors (only when status is 'error')
}

Practical Usage Patterns

Database Connection Health
// server/plugins/database.ts
import { setHealthError, clearHealthError } from 'nuxt-monitoring'

export default nitroPlugin(async () => {
  try {
    await connectToDatabase()
    clearHealthError('database')
    console.log('Database connected successfully')
  } catch (error) {
    setHealthError('database', `Failed to connect: ${error.message}`, 'DB_CONNECTION_ERROR')
    console.error('Database connection failed')
  }
})
External Service Monitoring
// server/middleware/external-services.ts
export default defineEventHandler(async (event) => {
  // Only check external services every 30 seconds
  if (shouldCheckServices()) {
    await Promise.allSettled([
      checkPaymentGateway(),
      checkNotificationService(),
      checkFileStorage()
    ])
  }
})

async function checkPaymentGateway() {
  try {
    const response = await fetch('https://api.payment-gateway.com/health', {
      timeout: 5000
    })

    if (response.ok) {
      clearHealthError('payment-gateway')
    } else {
      setHealthError('payment-gateway', `HTTP ${response.status}`, 'HTTP_ERROR')
    }
  } catch (error) {
    setHealthError('payment-gateway', 'Service unreachable', 'NETWORK_ERROR')
  }
}
Application Startup Health
// server/plugins/startup-checks.ts
export default nitroPlugin(async () => {
  console.log('Running startup health checks...')

  // Check required environment variables
  const requiredEnvVars = ['DATABASE_URL', 'REDIS_URL', 'API_SECRET']
  const missingEnvVars = requiredEnvVars.filter(key => !process.env[key])

  if (missingEnvVars.length > 0) {
    setHealthError('environment',
      `Missing required environment variables: ${missingEnvVars.join(', ')}`,
      'MISSING_ENV_VARS'
    )
  } else {
    clearHealthError('environment')
  }

  // Check disk space
  try {
    const stats = await checkDiskSpace()
    if (stats.freeSpacePercent < 10) {
      setHealthError('disk-space', 'Low disk space warning', 'LOW_DISK_SPACE')
    } else {
      clearHealthError('disk-space')
    }
  } catch (error) {
    setHealthError('disk-space', 'Unable to check disk space', 'DISK_CHECK_FAILED')
  }
})
Business Logic Health
// server/api/orders/process.post.ts
export default defineEventHandler(async (event) => {
  try {
    const order = await readBody(event)

    // Process order
    const result = await processOrder(order)

    // Clear any previous processing errors
    clearHealthError('order-processing')

    return { success: true, orderId: result.id }

  } catch (error) {
    // Set health error for failed order processing
    setHealthError('order-processing',
      `Order processing failed: ${error.message}`,
      'ORDER_PROCESSING_ERROR'
    )

    throw createError({
      statusCode: 500,
      statusMessage: 'Order processing failed'
    })
  }
})

HTTP Endpoint Behavior

The health endpoint automatically reflects the current state:

Healthy Response (HTTP 200)
{
  "status": "ok"
}
Unhealthy Response (HTTP 503)
{
  "status": "error",
  "errors": {
    "database": {
      "message": "Connection timeout",
      "code": "TIMEOUT",
      "timestamp": 1640995200000
    },
    "payment-gateway": {
      "message": "Service unreachable",
      "code": "NETWORK_ERROR",
      "timestamp": 1640995260000
    }
  }
}

Debug Server

The debug server feature allows you to run monitoring endpoints on a separate port, providing better isolation and security for your monitoring infrastructure.

Configuration

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['nuxt-monitoring'],
  monitoring: {
    // Enable endpoints you want to expose via debug server
    metrics: { enabled: true },
    healthCheck: { enabled: true },
    readyCheck: { enabled: true },

    // Enable debug server
    debugServer: {
      enabled: true,
      port: 3001
    }
  }
})

Available Endpoints

When the debug server is enabled, monitoring endpoints are available at:

  • http://localhost:3001/health - Health check endpoint (requires healthCheck.enabled: true)
  • http://localhost:3001/ready - Readiness probe endpoint (requires readyCheck.enabled: true)
  • http://localhost:3001/metrics - Prometheus metrics endpoint (requires metrics.enabled: true)

Note: Endpoints are only accessible if explicitly enabled in configuration.

Benefits

  1. Traffic Isolation: Monitoring traffic doesn't interfere with application traffic
  2. Security: Apply different security policies to monitoring endpoints
  3. Reliability: Monitor application health even when main server is overloaded
  4. CORS Support: Built-in cross-origin headers for dashboard integration
  5. Resource Control: Dedicated resources for monitoring infrastructure

Docker Integration

Perfect for containerized deployments:

# Dockerfile
EXPOSE 3000 3001

# Start application with debug server
CMD ["npm", "start"]
# docker-compose.yml
services:
  app:
    build: .
    ports:
      - "3000:3000"    # Application traffic
      - "3001:3001"    # Monitoring traffic

  prometheus:
    image: prom/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
    configs:
      - source: prometheus_config
        target: /etc/prometheus/prometheus.yml

configs:
  prometheus_config:
    content: |
      scrape_configs:
        - job_name: 'nuxt-app'
          static_configs:
            - targets: ['app:3001']  # Scrape from debug server

Kubernetes Integration

# deployment.yaml
apiVersion: v1
kind: Service
metadata:
  name: app-monitoring
spec:
  selector:
    app: nuxt-app
  ports:
    - name: monitoring
      port: 3001
      targetPort: 3001
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nuxt-app
spec:
  template:
    spec:
      containers:
        - name: app
          image: nuxt-app:latest
          ports:
            - containerPort: 3000  # App traffic
            - containerPort: 3001  # Monitoring traffic
          readinessProbe:
            httpGet:
              path: /ready
              port: 3001
          livenessProbe:
            httpGet:
              path: /health
              port: 3001

Metrics Collection

The module automatically collects comprehensive application and runtime metrics in Prometheus format.

Automatic HTTP Metrics

Metric Name Type Labels Description
http_request_total Counter method, route, status_code Total number of HTTP requests
http_request_duration_seconds Summary method, route, status_code Request duration in seconds
http_active_requests Gauge — Number of currently active requests

Node.js Runtime Metrics

Through integration with prom-client, the module automatically collects:

  • Process Metrics: CPU usage, memory consumption, uptime
  • Event Loop: Event loop lag and utilization
  • Garbage Collection: GC duration and frequency by type
  • Node.js Version: Runtime version information
  • System Metrics: Platform, architecture, load average

Request Filtering

The module intelligently filters requests to avoid noise:

  • Skipped: Nuxt internal requests (/__nuxt/*)
  • Skipped: Static assets (.js, .css, .png, etc.)
  • Skipped: Monitoring endpoints themselves (/metrics, /health, /ready)
  • Tracked: All API routes and page requests

Metrics Endpoint

Access Prometheus metrics at /metrics (or your configured path):

# HELP http_request_total Total number of HTTP requests
# TYPE http_request_total counter
http_request_total{method="GET",route="/api/users",status_code="200"} 145

# HELP http_request_duration_seconds Duration of HTTP requests in seconds
# TYPE http_request_duration_seconds summary
http_request_duration_seconds{method="GET",route="/api/users",status_code="200",quantile="0.5"} 0.023
http_request_duration_seconds{method="GET",route="/api/users",status_code="200",quantile="0.95"} 0.156

Custom Metrics

Extend with your own application-specific metrics:

// server/plugins/custom-metrics.ts
import { register } from 'prom-client'

// Custom business metrics
const userRegistrations = new Counter({
  name: 'user_registrations_total',
  help: 'Total number of user registrations',
  labelNames: ['method', 'status']
})

const orderValue = new Histogram({
  name: 'order_value_dollars',
  help: 'Distribution of order values',
  buckets: [10, 50, 100, 500, 1000, 5000]
})

// Register with the existing registry
register.registerMetric(userRegistrations)
register.registerMetric(orderValue)

export { userRegistrations, orderValue }
// server/api/auth/register.post.ts
import { userRegistrations } from '~/server/plugins/custom-metrics'

export default defineEventHandler(async (event) => {
  try {
    const user = await createUser(userData)

    // Track successful registration
    userRegistrations.inc({ method: 'email', status: 'success' })

    return { user }
  } catch (error) {
    // Track failed registration
    userRegistrations.inc({ method: 'email', status: 'error' })
    throw error
  }
})

Development

Project Setup

  1. Clone and Install:

    git clone <repository-url>
    cd nuxt-monitoring
    npm install
    
  2. Prepare Development Environment:

    # Generate type stubs and prepare module
    npm run dev:prepare
    
  3. Start Development Server:

    # Start playground with hot reload
    npm run dev
    

The playground will be available at:

Available Scripts

# Development
npm run dev              # Start development server with playground
npm run dev:build        # Build playground for production
npm run dev:prepare      # Prepare development environment

# Testing
npm test                 # Run test suite
npm run test:watch       # Run tests in watch mode
npm run test:coverage    # Run tests with coverage report
npm run test:ui          # Run tests with UI

# Code Quality
npm run lint             # Run ESLint
npm run typecheck        # Run TypeScript type checking

# Build & Release
npm run build            # Build module for production
npm run release:patch    # Release patch version
npm run release:minor    # Release minor version
npm run release:major    # Release major version

Development Workflow

  1. Make Changes: Edit source files in src/
  2. Test Changes: Use playground at http://localhost:3000
  3. Run Tests: Ensure npm test passes
  4. Check Linting: Ensure npm run lint passes
  5. Type Check: Ensure npm run typecheck passes

Testing

The module includes comprehensive tests covering:

  • Unit Tests: Core functionality and API methods
  • Integration Tests: Nuxt module integration
  • HTTP Tests: Endpoint behavior and responses
  • Type Tests: TypeScript type definitions

Run specific test suites:

# Run specific test file
npm test src/runtime/health/spec/state.spec.ts

# Run tests with specific pattern
npm test -- --grep "health"

# Run tests in watch mode with coverage
npm run test:watch -- --coverage

Playground Features

The included playground demonstrates all module features:

  • Health Management: Interactive health error setting/clearing
  • Endpoint Testing: Test all monitoring endpoints
  • Debug Server: Toggle between regular and debug server modes
  • Metrics Visualization: View Prometheus metrics output
  • Status Indicators: Visual feedback for endpoint responses

CORS Support

All monitoring endpoints include CORS headers by default:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization

This enables monitoring dashboards and external tools to access endpoints directly from browsers.

License

MIT License - see LICENSE

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.


Related Packages

nuxt-observe

Self-hosted observability + service-registry dashboard module for Nuxt

2,027
nuxt-prometheus-module

A nuxt module to export data to prometheus

11,074 3
@errorgap/nuxt

Nuxt module for Errorgap error tracking (client and server).

988 0
@lutejka/nuxt-otel

OpenTelemetry tracing for Nuxt applications

0 0
nuxt-monitor

Local-first error monitoring for Nuxt. No DSN, no account, no sourcemap upload.

1,619 1

Version History

Version Released Vue License
1.3.0 ^3.0 MIT
1.2.0 ^3.0 MIT
1.0.0 ^3.0 MIT
0.9.2 ^3.0 MIT
0.9.1 ^3.0 MIT