Strapi plugin logo for Prometheus

Prometheus

strapi-prometheus is a simple plugin that exposes a metrics url for prometheus to scrape.

📊 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.

✨ Features

  • 🚀 Real-time API Metrics - Track HTTP request duration, payload sizes, and response codes
  • 📈 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
  • 📊 Lifecycle Tracking - Monitor Strapi lifecycle events duration
  • 🔌 Easy Integration - Simple configuration with sensible defaults
  • 🆔 Version Tracking - Monitor Strapi version information

⏳ 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):

1// config/plugins.js
2module.exports = {
3  // ...other plugins
4  prometheus: {
5    enabled: true,
6    config: {
7      // Optional: Collect Node.js default metrics
8      // See collectDefaultMetricsOption of prom-client for all options
9      collectDefaultMetrics: false, // or { prefix: 'my_app_' }
10      
11      // Optional: Add custom labels to all metrics
12      labels: { 
13        app: "my-strapi-app",
14        environment: "production"
15      },
16      
17      // Server configuration
18      // Set to false to expose metrics on your main Strapi server (not recommended)
19      server: {
20        port: 9000,           // Metrics server port
21        host: '0.0.0.0',      // Metrics server host
22        path: '/metrics'      // Metrics endpoint path
23      }
24      // OR disable separate server (use with caution):
25      // server: false
26    }
27  }
28};

For TypeScript projects:

1// config/plugins.ts
2export default {
3  prometheus: {
4    enabled: true,
5    config: {
6      collectDefaultMetrics: false,
7      labels: { 
8        app: "my-strapi-app",
9        environment: process.env.NODE_ENV || "development"
10      },
11      server: {
12        port: parseInt(process.env.METRICS_PORT || '9000'),
13        host: process.env.METRICS_HOST || '0.0.0.0',
14        path: '/metrics'
15      }
16    }
17  }
18};

📊 Available Metrics

The plugin automatically collects the following HTTP metrics with intelligent route pattern detection:

Metric NameDescriptionTypeLabels
http_request_duration_secondsDuration of HTTP requests in secondsHistogramorigin, method, route, status
http_request_content_length_bytesSize of request payloads in bytesHistogramorigin, method, route, status
http_response_content_length_bytesSize of response payloads in bytesHistogramorigin, method, route, status
strapi_version_infoStrapi version informationGaugeversion
lifecycle_duration_secondsDuration of Strapi lifecycle eventsHistogramevent

🎯 Smart Route Labeling

The plugin uses intelligent route pattern detection to ensure low cardinality metrics:

Route Pattern Examples:

1/api/articles/123/api/articles/:id
2/uploads/image.jpg/uploads/:file
3/admin/users/uuid-here   → /admin/users/:uuid

Benefits:

  • Low cardinality - Groups similar requests together
  • Consistent aggregation - Easy to analyze API performance patterns
  • Prometheus-friendly - Prevents metric explosion
  • Automatic normalization - Handles IDs, UUIDs, file names automatically

📊 Metric Buckets

Request Duration Buckets: 1ms, 5ms, 10ms, 50ms, 100ms, 200ms, 500ms, 1s, 2s, 5s, 10s

Content Length Buckets: 256KB, 512KB, 1MB, 2MB, 4MB, 8MB, 16MB, 32MB, 64MB, 128MB, 256MB, 512MB, 1GB

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...

� Configuration Options

collectDefaultMetrics

Controls collection of Node.js process metrics:

1// Disable default metrics (default)
2collectDefaultMetrics: false
3
4// Enable with default settings
5collectDefaultMetrics: true
6
7// Enable with custom prefix
8collectDefaultMetrics: { 
9  prefix: 'my_app_',
10  register: undefined, // Uses default registry
11  gcDurationBuckets: [0.001, 0.01, 0.1, 1, 2, 5], // Custom GC buckets
12  eventLoopMonitoringPrecision: 10 // Event loop precision
13}

labels

Global labels added to all metrics:

1labels: {
2  app: 'my-app',
3  environment: 'production',
4  version: '1.0.0',
5  datacenter: 'us-east-1'
6}

server

Metrics server configuration:

1// Dedicated server (recommended)
2server: {
3  port: 9000,
4  host: '0.0.0.0',
5  path: '/metrics'
6}
7
8// Disable dedicated server (adds /metrics to main Strapi server)
9server: false

🚀 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/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 VersionPlugin VersionStatus
v5.xv2.x.x✅ Fully Supported
v4.xv1.x.x✅ Legacy Support

Note: For new projects, we recommend using Strapi v5.x with the latest plugin version.

📊 Prometheus Configuration Example

!NOTE This plugin only exposes metrics - you need to set up your own Prometheus instance to collect them.

Here's a basic Prometheus configuration to scrape metrics from the dedicated server:

1# prometheus.yml
2global:
3  scrape_interval: 15s     # How frequently to scrape targets
4  evaluation_interval: 15s # How frequently to evaluate rules
5
6rule_files:
7  # - "first_rules.yml"
8  # - "second_rules.yml"
9
10scrape_configs:
11  - job_name: "strapi-app"
12    static_configs:
13      - targets: ["localhost:9000"]  # Metrics server endpoint
14    scrape_interval: 10s             # Override global interval
15    metrics_path: /metrics           # Metrics endpoint path
16    
17    # Optional: Add additional labels to all metrics from this job
18    relabel_configs:
19      - target_label: 'app'
20        replacement: 'my-strapi-app'

Docker Compose Example

If you're running Strapi in Docker, here's a complete example:

1version: '3.8'
2services:
3  strapi:
4    image: my-strapi-app
5    ports:
6      - "1337:1337"  # Strapi app
7      - "9000:9000"  # Metrics (expose only to monitoring network)
8    
9  prometheus:
10    image: prom/prometheus:latest
11    ports:
12      - "9090:9090"
13    volumes:
14      - ./prometheus.yml:/etc/prometheus/prometheus.yml
15    command:
16      - '--config.file=/etc/prometheus/prometheus.yml'
17      - '--storage.tsdb.path=/prometheus'
18      - '--web.console.libraries=/etc/prometheus/console_libraries'
19      - '--web.console.templates=/etc/prometheus/consoles'

📊 Grafana Dashboards

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

Official Dashboards

Custom Dashboard Examples

You can create custom dashboards using queries like:

1# Average request duration by route
2rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m])
3
4# Request rate by route pattern
5sum(rate(http_request_duration_seconds_count[5m])) by (route)
6
7# Request rate by method and status
8sum(rate(http_request_duration_seconds_count[5m])) by (method, status)
9
10# Error rate by route
11sum(rate(http_request_duration_seconds_count{status=~"5.."}[5m])) by (route) / sum(rate(http_request_duration_seconds_count[5m])) by (route)
12
13# Active requests by route
14sum(http_active_requests) by (route)
15
16# Top slowest API endpoints
17topk(10, histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) by (route))
18
19# Request throughput by origin
20sum(rate(http_request_duration_seconds_count[5m])) by (origin)
21
22# Response size distribution
23histogram_quantile(0.95, rate(http_response_content_length_bytes_bucket[5m])) by (route)
24
25# Memory usage (when collectDefaultMetrics is enabled)
26nodejs_heap_size_used_bytes / nodejs_heap_size_total_bytes

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

Debug Mode

Enable debug logging to troubleshoot issues:

1// config/plugins.js
2module.exports = {
3  prometheus: {
4    enabled: true,
5    config: {
6      // ... your config
7    }
8  }
9};

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):

1module.exports = {
2  'strapi-prometheus': {
3    enabled: true,
4    config: {
5      // v1 config
6    }
7  }
8};

New (v2):

1module.exports = {
2  prometheus: {  // ← Plugin name simplified
3    enabled: true,
4    config: {
5      // v2 config (see configuration section above)
6    }
7  }
8};

🚀 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 Metricv2 MetricChange
http_request_duration_shttp_request_duration_seconds✅ Renamed for clarity
http_request_size_byteshttp_request_content_length_bytes✅ Renamed for accuracy
http_response_size_byteshttp_response_content_length_bytes✅ Renamed for accuracy
Labels: pathLabels: 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!

Install now

npm install strapi-prometheus

STATS

17 GitHub stars1370 weekly downloads

Last updated

2 days ago

Strapi Version

5.0.0 and above

Author

github profile image for XanderD99
XanderD99

Useful links

Create your own plugin

Check out the available plugin resources that will help you to develop your plugin or provider and get it listed on the marketplace.