PrometheusPlugin verified by Strapi
strapi-prometheus is a simple plugin that exposes a metrics url for prometheus to scrape.
📊 Strapi Prometheus Plugin
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 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 lifecycle events | Histogram | event |
🎯 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 modeprocess_cpu_system_seconds_total
- CPU time spent in system modeprocess_start_time_seconds
- Process start timeprocess_resident_memory_bytes
- Resident memory sizenodejs_heap_size_total_bytes
- Total heap sizenodejs_heap_size_used_bytes
- Used heap sizenodejs_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
- Install and configure the plugin (see Installation)
- Start your Strapi application
- Metrics will be available at
http://localhost:9000/metrics
- 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 Version | Plugin Version | Status |
---|---|---|
v5.x | v2.x.x | ✅ Fully Supported |
v4.x | v1.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
- Dashboard 14565 - Comprehensive Strapi monitoring dashboard
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 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
- Update plugin name in your configuration
- Review new configuration options (especially
server
settings) - Update Prometheus scrape config if using custom settings
- Update Grafana dashboards with new metric names
- 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
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature
- Make your changes
- Add tests if applicable
- Commit with clear messages:
git commit -m 'Add amazing feature'
- Push to your branch:
git push origin feature/amazing-feature
- 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)
- 🐙 GitHub: XanderD99
- ☕ Buy me a coffee: buymeacoffee.com/xanderd
🙏 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
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.