A powerful Strapi plugin that adds comprehensive Prometheus metrics to monitor your API performance, system resources, and application behavior using prom-client.
npm install strapi-prometheus



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! ๐
- ๐ 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
``bash`
npm install strapi-prometheusor
yarn add strapi-prometheusor
pnpm add strapi-prometheus
`bash`
npm install prom-clientor
yarn add prom-clientor
pnpm add prom-client
Create or update your config/plugins.js (or config/plugins.ts for TypeScript):
`js`
// 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:
`ts`
// 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;
}
}
}
};
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 | method, route, status |http_request_content_length_bytes
| | Size of request payloads in bytes ๐ค | Histogram | method, route, status |http_response_content_length_bytes
| | Size of response payloads in bytes ๐ฅ | Histogram | method, route, status |strapi_version_info
| | Strapi version information ๐ท๏ธ | Gauge | version |lifecycle_duration_seconds
| | Duration of Strapi database lifecycle events ๐พ | Histogram | event |
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 mode process_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...
The plugin features intelligent path normalization to ensure optimal metric cardinality by grouping similar routes together โจ
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:
`js`
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:
`js`
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;
}
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 |
- โ
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
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
By default, metrics are served on a separate server:
`bash`
curl http://localhost:9000/metrics
If you set server: false, metrics will be available on your main Strapi server:
`bash`Requires authentication token
curl -H "Authorization: Bearer YOUR_API_TOKEN" http://localhost:1337/api/metrics
> [!CAUTION]
> Metrics can contain sensitive information about your application's usage patterns, performance characteristics, and potentially user behavior. Always secure your metrics endpoint appropriately.
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
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.
| 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! ๐ฏ
Ready-to-use Grafana dashboards for visualizing your Strapi metrics:
- Dashboard 14565 - Comprehensive Strapi monitoring dashboard
Have a great dashboard? We'd love to feature it! Please open a pull request with your dashboard JSON. ๐จ
#### 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.jsprom-client
- Verify that 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
- ๐ Report bugs
- ๐ก Request features
- ๐ Read the documentation
- โ Buy me a coffee
Version 2.0 brings significant improvements and Strapi v5 support. Here's what you need to know:
Old (v1):
`js`
module.exports = {
'strapi-prometheus': {
enabled: true,
config: {
// v1 config
}
}
};
New (v2):
`js`
module.exports = {
prometheus: { // โ Plugin name simplified
enabled: true,
config: {
// v2 config (see configuration section above)
}
}
};
- 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
| 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 |path
| Labels: | Labels: route | โ
More consistent route patterns |http_requests_total
| Apollo metrics | โ | ๐๏ธ Removed - use apollo-prometheus-exporter |
| - | | โ
New counter metric |http_active_requests
| - | | โ
New gauge metric |
v2 Improvements:
- Smart route detection - Uses _matchedRoute when available for accurate patterns/api/articles/123
- Consistent normalization - โ /api/articles/:id
- Low cardinality - Prevents metric explosion from dynamic paths
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
- 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
- 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
We welcome contributions! Here's how you can help:
- Use the issue tracker ๐
- Search existing issues before creating new ones ๐
- Provide clear reproduction steps ๐
- Include environment details (Strapi version, Node.js version, OS) ๐ป
1. Fork the repository ๐ด
2. Create a feature branch: git checkout -b feature/amazing-feature ๐ฟgit commit -m 'Add amazing feature'
3. Make your changes โจ
4. Add tests if applicable ๐งช
5. Commit with clear messages: ๐ฌgit push origin feature/amazing-feature` ๐
6. Push to your branch:
7. Open a Pull Request ๐
- Improve README documentation ๐
- Add code examples ๐ก
- Create tutorials or blog posts โ๏ธ
- Share Grafana dashboards ๐
This project is licensed under the MIT License - see the LICENSE file for details.
Xander Denecker (@XanderD99)
- ๐ GitHub: XanderD99
- โ Buy me a coffee: buymeacoffee.com/xanderd
- 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!