Skip to content

XanderD99/strapi-prometheus

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ“Š Strapi Prometheus Plugin

npm downloads npm version license GitHub stars

A powerful middleware plugin that adds comprehensive Prometheus metrics to your Strapi application using prom-client ๐Ÿ“ˆ. Monitor your API performance, track system resources, and gain valuable insights into your application's behavior with just a few lines of configuration! ๐Ÿš€

โœจ Features

  • ๐Ÿš€ Real-time API Metrics - Track HTTP request duration, payload sizes, and response codes with intelligent route normalization
  • ๐Ÿ“ˆ System Monitoring - Collect Node.js process metrics as recommended by Prometheus
  • ๐Ÿ”’ Secure by Default - Dedicated metrics server (port 9000) isolated from your main application
  • ๐Ÿท๏ธ Custom Labels - Add custom labels to categorize and filter your metrics across environments ๐ŸŒ
  • ๐Ÿ“Š Database Lifecycle Tracking - Monitor Strapi lifecycle events (create, update, delete) duration โšก
  • ๐Ÿ”Œ Easy Integration - Simple configuration with sensible defaults - get started in minutes!
  • ๐Ÿ†” Version Tracking - Monitor Strapi version information for deployment tracking
  • ๐ŸŽฏ Smart Path Normalization - Flexible normalization with regex patterns or custom functions to group similar routes for better metric cardinality ๐Ÿ“Š
  • ๐Ÿ“ฆ TypeScript Support - Built with TypeScript for better developer experience

โšก Installation

1. Install the package ๐Ÿ“ฆ

npm install strapi-prometheus
# or
yarn add strapi-prometheus
# or
pnpm add strapi-prometheus

2. Install peer dependencies ๐Ÿ”ง

npm install prom-client
# or
yarn add prom-client
# or
pnpm add prom-client

3. Configure the plugin โš™๏ธ

Create or update your config/plugins.js (or config/plugins.ts for TypeScript):

// config/plugins.js
module.exports = {
  // ...other plugins
  prometheus: {
    enabled: true,
    config: {
      // Optional: Collect Node.js default metrics
      // See collectDefaultMetricsOption of prom-client for all options
      collectDefaultMetrics: false, // or { prefix: 'my_app_' }
      
      // Optional: Add custom labels to all metrics
      labels: { 
        app: "my-strapi-app",
        environment: "production"
      },
      
      // Server configuration
      // Set to false to expose metrics on your main Strapi server (not recommended)
      server: {
        port: 9000,           // Metrics server port
        host: '0.0.0.0',      // Metrics server host
        path: '/metrics'      // Metrics endpoint path
      },
      // OR disable separate server (use with caution):
      // server: false
      
      // ๐ŸŽฏ Path Normalization Rules
      normalize: [
        [/\/(?:[a-z0-9]{24,25}|\d+)(?=\/|$)/, '/:id'], // Document IDs or numeric IDs
        [/\/uploads\/[^\/]+\.[a-zA-Z0-9]+/, '/uploads/:file'], // Uploaded files with extensions
      ]
    }
  }
};

For TypeScript projects:

// config/plugins.ts
export default {
  prometheus: {
    enabled: true,
    config: {
      collectDefaultMetrics: false,
      labels: { 
        app: "my-strapi-app",
        environment: process.env.NODE_ENV || "development"
      },
      server: {
        port: parseInt(process.env.METRICS_PORT || '9000'),
        host: process.env.METRICS_HOST || '0.0.0.0',
        path: '/metrics'
      },
      
      // Custom normalization function (alternative to array rules)
      normalize: (ctx) => {
        let path = ctx.path;
        
        // Custom logic for your specific needs
        if (path.startsWith('/api/')) {
          path = path.replace(/\/\d+/g, '/:id'); // Replace numeric IDs
        }
        
        return path;
      }
    }
  }
};

๐Ÿ“Š Available Metrics

The plugin automatically collects the following metrics with intelligent route pattern detection โœจ:

Metric Name Description Type Labels
http_request_duration_seconds Duration of HTTP requests in seconds โฑ๏ธ Histogram origin, method, route, status
http_request_content_length_bytes Size of request payloads in bytes ๐Ÿ“ค Histogram origin, method, route, status
http_response_content_length_bytes Size of response payloads in bytes ๐Ÿ“ฅ Histogram origin, method, route, status
strapi_version_info Strapi version information ๐Ÿท๏ธ Gauge version
lifecycle_duration_seconds Duration of Strapi database lifecycle events ๐Ÿ’พ Histogram event

Optional System Metrics

When collectDefaultMetrics is enabled, you'll also get Node.js process metrics:

  • process_cpu_user_seconds_total - CPU time spent in user mode
  • process_cpu_system_seconds_total - CPU time spent in system mode
  • process_start_time_seconds - Process start time
  • process_resident_memory_bytes - Resident memory size
  • nodejs_heap_size_total_bytes - Total heap size
  • nodejs_heap_size_used_bytes - Used heap size
  • nodejs_external_memory_bytes - External memory usage
  • And more...

๐ŸŽฏ Smart Path Normalization

The plugin features intelligent path normalization to ensure optimal metric cardinality by grouping similar routes together โœจ

๐Ÿ“ Configuration Options

You can configure path normalization in two ways:

1. Array of Regex Rules (Recommended)

Use an array of [RegExp, replacement] tuples to define normalization patterns:

normalize: [
  [/\/(?:[a-z0-9]{24,25}|\d+)(?=\/|$)/, '/:id'], // Document IDs or numeric IDs
  [/\/uploads\/[^\/]+\.[a-zA-Z0-9]+/, '/uploads/:file'], // Uploaded files with extensions
  
  // Custom patterns
  [/\/users\/\d+/, '/users/:id'],                                   // /users/123
  [/\/orders\/ORD\d+/, '/orders/:orderCode']                        // /orders/ORD12345
]

2. Custom Function

Use a function for dynamic normalization logic:

normalize: (ctx) => {
  let path = ctx.path;
  
  // Custom normalization logic
  if (path.startsWith('/api/')) {
    path = path.replace(/\/\d+/g, '/:id');           // Replace numeric IDs
    path = path.replace(/\/[a-f0-9-]{36}/gi, '/:uuid'); // Replace UUIDs
  }
  
  // Multi-tenant example
  if (path.startsWith('/tenant/')) {
    path = path.replace(/^\/tenant\/[^\/]+/, '/tenant/:id');
  }
  
  return path;
}

๐Ÿท๏ธ Built-in Patterns

The plugin includes pre-configured patterns for common Strapi routes:

Original Path Normalized Path Description
/api/posts/123 /api/posts/:id API resource with ID
/api/posts/123/comments/456 /api/posts/:id/comments/:id Nested resources
/admin/content-manager/collection-types/api::post.post/123 /admin/content-manager/:type/:contentType/:id Admin content manager
/uploads/image.jpg /uploads/:file File uploads
/en/api/posts/123 /:locale/api/posts/:id i18n localized routes
/fr-FR/dashboard /:locale/dashboard Locale-specific pages

๐Ÿš€ Benefits

  • โœ… Low Cardinality - Groups similar routes to prevent metric explosion
  • โœ… Prometheus-Friendly - Follows Prometheus best practices
  • โœ… Flexible - Support both regex patterns and custom functions
  • โœ… Performance - Efficient pattern matching with minimal overhead
  • โœ… Strapi-Aware - Built-in knowledge of Strapi routing conventions

๐Ÿš€ Quick Start

  1. ๐Ÿ“ฆ Install and configure the plugin (see Installation)
  2. ๐ŸŽฌ Start your Strapi application
  3. ๐Ÿ“Š Metrics will be available at http://localhost:9000/metrics
  4. ๐Ÿ”— Configure Prometheus to scrape this endpoint

๐Ÿ“Š Accessing Metrics

Dedicated Server (Default & Recommended)

By default, metrics are served on a separate server:

curl http://localhost:9000/metrics

Main Strapi Server (Not Recommended)

If you set server: false, metrics will be available on your main Strapi server:

# Requires authentication token
curl -H "Authorization: Bearer YOUR_API_TOKEN" http://localhost:1337/api/metrics

๐Ÿ‘ฎโ€โ™€๏ธ Security Considerations

Caution

Metrics can contain sensitive information about your application's usage patterns, performance characteristics, and potentially user behavior. Always secure your metrics endpoint appropriately.

Recommended: Dedicated Server (Default)

The plugin starts a separate server on port 9000 by default, isolated from your main application:

  • โœ… Secure by design - No external access to your main application
  • โœ… Simple firewall rules - Block port 9000 from external access
  • โœ… Performance - No impact on your main application
  • โœ… Monitoring-specific - Dedicated to metrics collection

Alternative: Main Server Integration

You can expose metrics on your main Strapi server by setting server: false:

  • โš ๏ธ Authentication required - Protected by Strapi's auth middleware
  • โš ๏ธ API token needed - Must create and manage API tokens
  • โš ๏ธ Potential exposure - Metrics endpoint on your main application
  • โš ๏ธ Performance impact - Additional load on main server

We strongly recommend using the dedicated server approach.

๐Ÿค Compatibility

Strapi Version Plugin Version Status
v5.x v2.x.x โœ… Fully Supported โญ
v4.x v1.x.x โŒ EOL ๐Ÿ”ง

Note: For new projects, we recommend using Strapi v5.x with the latest plugin version! ๐ŸŽฏ

๐Ÿ“Š Grafana Dashboards

Ready-to-use Grafana dashboards for visualizing your Strapi metrics:

Official Dashboards

Contributing Dashboards

Have a great dashboard? We'd love to feature it! Please open a pull request with your dashboard JSON. ๐ŸŽจ

๐Ÿ” Troubleshooting

Common Issues

Metrics server not starting

  • Check if port 9000 is already in use
  • Verify firewall settings
  • Check Strapi logs for error messages

No metrics appearing

  • Ensure the plugin is properly enabled in config/plugins.js
  • Verify that prom-client is installed
  • Check that requests are being made to your Strapi application

Memory usage increasing

  • Consider disabling collectDefaultMetrics if not needed
  • Review custom labels - avoid high-cardinality labels
  • Monitor Prometheus scrape interval

๐Ÿ†˜ Getting Help

๐Ÿ—๏ธ v1 โ†’ v2 Migration Guide

๐Ÿ—๏ธ Migration Guide (v1 โ†’ v2)

Version 2.0 brings significant improvements and Strapi v5 support. Here's what you need to know:

๐Ÿ”ง Configuration Changes

Old (v1):

module.exports = {
  'strapi-prometheus': {
    enabled: true,
    config: {
      // v1 config
    }
  }
};

New (v2):

module.exports = {
  prometheus: {  // โ† Plugin name simplified
    enabled: true,
    config: {
      // v2 config (see configuration section above)
    }
  }
};

๐Ÿš€ New Features in v2

  • Dedicated metrics server - Default behavior for better security
  • Simplified configuration - Easier setup and maintenance
  • Strapi v5 support - Future-ready compatibility
  • Enhanced metrics - More comprehensive monitoring
  • Improved performance - Optimized for production use

๐Ÿ“Š Metric and Label Changes

v1 Metric v2 Metric Change
http_request_duration_s http_request_duration_seconds โœ… Renamed for clarity
http_request_size_bytes http_request_content_length_bytes โœ… Renamed for accuracy
http_response_size_bytes http_response_content_length_bytes โœ… Renamed for accuracy
Labels: path Labels: route โœ… More consistent route patterns
Apollo metrics โŒ ๐Ÿ—‘๏ธ Removed - use apollo-prometheus-exporter
- http_requests_total โœ… New counter metric
- http_active_requests โœ… New gauge metric

๐Ÿท๏ธ Enhanced Label Strategy

v2 Improvements:

  • Smart route detection - Uses _matchedRoute when available for accurate patterns
  • Consistent normalization - /api/articles/123 โ†’ /api/articles/:id
  • Low cardinality - Prevents metric explosion from dynamic paths
  • Added origin label - Track requests by source

๐Ÿ”„ Migration Steps

  1. Update plugin name in your configuration
  2. Review new configuration options (especially server settings)
  3. Update Prometheus scrape config if using custom settings
  4. Update Grafana dashboards with new metric names
  5. Test thoroughly in development before production deployment

โš ๏ธ Breaking Changes

  • Apollo metrics removed - If you were using Apollo GraphQL metrics, you'll need to implement them separately
  • Custom registry removed - Now uses the default prom-client registry (this actually gives you more flexibility!)
  • Configuration structure changed - Follow the new configuration format

๐Ÿ’ก Recommendations

  • Start with default settings and customize as needed
  • Use the dedicated metrics server (default behavior)
  • Monitor your Prometheus targets after migration
  • Consider this a good time to review your monitoring setup

๐Ÿค Contributing

We welcome contributions! Here's how you can help:

๐Ÿ› Reporting Issues

  • Use the issue tracker ๐Ÿ“
  • Search existing issues before creating new ones ๐Ÿ”
  • Provide clear reproduction steps ๐Ÿ“‹
  • Include environment details (Strapi version, Node.js version, OS) ๐Ÿ’ป

๐Ÿ’ป Development

  1. Fork the repository ๐Ÿด
  2. Create a feature branch: git checkout -b feature/amazing-feature ๐ŸŒฟ
  3. Make your changes โœจ
  4. Add tests if applicable ๐Ÿงช
  5. Commit with clear messages: git commit -m 'Add amazing feature' ๐Ÿ’ฌ
  6. Push to your branch: git push origin feature/amazing-feature ๐Ÿš€
  7. Open a Pull Request ๐Ÿ”„

๐Ÿ“ Documentation

  • Improve README documentation ๐Ÿ“–
  • Add code examples ๐Ÿ’ก
  • Create tutorials or blog posts โœ๏ธ
  • Share Grafana dashboards ๐Ÿ“Š

๐Ÿ“œ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ‘จโ€๐Ÿ’ป Author & Maintainer

Xander Denecker (@XanderD99)

๐Ÿ™ Acknowledgments

  • Prometheus - The monitoring system that makes this all possible
  • prom-client - The Node.js Prometheus client library
  • Strapi - The leading open-source headless CMS
  • All contributors who have helped improve this plugin

โญ If this plugin helps you, please consider giving it a star on GitHub!

About

Strapi prometheus plugin

Resources

License

Stars

Watchers

Forks

Contributors 4

  •  
  •  
  •  
  •