run_as_root / magento2-prometheus-exporter
run_as_root/magento2-prometheus-exporter
Magento2 Prometheus Exporter
Magento 2 Prometheus Exporter
A comprehensive Magento 2 module that exposes essential Magento metrics in Prometheus format, enabling powerful monitoring and observability for your e-commerce platform.
🚀 Features
- 📊 Rich Metrics Collection: Monitors orders, products, customers, CMS content, cron jobs, indexers, and more
- 🔧 Configurable Metrics: Enable/disable specific metrics through Magento admin interface
- 🔐 Secure Access: Bearer token authentication support to protect your metrics endpoint
- ⚡ Performance Optimized: Efficient cron-based data aggregation to minimize performance impact
- 🎯 Prometheus Ready: Native Prometheus format output for seamless integration
- 🔌 Extensible Architecture: Easy to add custom metrics with clean interfaces
📋 Table of Contents
- Installation
- Configuration
- Prometheus Setup
- Available Metrics
- Security
- Custom Metrics
- CLI Commands
- Architecture
- Troubleshooting
- Contributing
- License
📦 Installation
Requirements
- Magento 2.3.x or higher
- PHP 8.2 or higher
- Composer
Install via Composer
composer require run-as-root/magento2-prometheus-exporter
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento cache:flush
Verify Installation
After installation, your metrics endpoint will be available at:
https://your-magento-store.com/metrics
⚙️ Configuration
Admin Configuration
Navigate to Stores → Configuration → Prometheus → Metric Configuration to:
- Enable/disable specific metric collectors
- Configure authentication settings
- Set collection intervals
- Manage metric labels and groupings
Cron Configuration
The module automatically registers a cron job that runs every minute to aggregate metrics. The job uses a dedicated cron group: run_as_root_prometheus_metrics_aggregator.
🎯 Prometheus Setup
Basic Configuration
Add the following scrape configuration to your prometheus.yml:
scrape_configs:
- job_name: 'magento-2'
scrape_interval: 5m
scrape_timeout: 60s
metrics_path: /metrics
static_configs:
- targets:
- 'your-magento-store.com'
With Authentication
For production environments, secure your metrics endpoint:
scrape_configs:
- job_name: 'magento-2'
scrape_interval: 5m
scrape_timeout: 60s
metrics_path: /metrics
authorization:
type: 'Bearer'
credentials: 'your-bearer-token-here'
static_configs:
- targets:
- 'your-magento-store.com'
Advanced Configuration with Labels
scrape_configs:
- job_name: 'magento-2'
scrape_interval: 5m
scrape_timeout: 60s
metrics_path: /metrics
authorization:
type: 'Bearer'
credentials: 'your-bearer-token-here'
static_configs:
- targets:
- 'your-magento-store.com'
relabel_configs:
- source_labels: [__address__]
target_label: instance
replacement: 'magento-production'
📊 Available Metrics
Order Metrics
| Metric | Type | Labels | Description |
|---|---|---|---|
magento_orders_count_total |
gauge | status, store_code |
Total count of orders by status and store |
magento_orders_amount_total |
gauge | status, store_code |
Total revenue by order status and store |
magento_order_items_count_total |
gauge | status, store_code |
Total count of order items |
Product & Catalog Metrics
| Metric | Type | Labels | Description |
|---|---|---|---|
magento_products_by_type_count_total |
gauge | product_type |
Count of products by type (simple, configurable, etc.) |
magento_catalog_category_count_total |
gauge | status, menu_status, store_code |
Count of categories by status |
magento_complex_product_variations_above_recommended_level |
gauge | - | Count of configurable products with more than 50 variations (performance risk) |
magento_products_with_bad_reviews_count_total |
gauge | store_code |
Count of products whose rating_summary is below 60 (≈ 3 of 5 stars) |
EAV & Attribute Metrics
| Metric | Type | Labels | Description |
|---|---|---|---|
magento_eav_attribute_count_total |
gauge | - | Total count of EAV attributes |
magento_eav_attribute_options_above_recommended_level_total |
gauge | - | Count of attributes with more than 100 options (performance risk) |
Customer Metrics
| Metric | Type | Labels | Description |
|---|---|---|---|
magento_customer_count_total |
gauge | store_code |
Total count of registered customers |
Content Metrics
| Metric | Type | Labels | Description |
|---|---|---|---|
magento_cms_block_count_total |
gauge | store_code |
Count of CMS blocks |
magento_cms_page_count_total |
gauge | store_code |
Count of CMS pages |
System Health Metrics
| Metric | Type | Labels | Description |
|---|---|---|---|
magento_cronjob_count_total |
gauge | status, job_code |
Count of cron jobs by status |
magento_cronjob_broken_count_total |
gauge | - | Count of broken cron jobs |
magento_indexer_backlog_count_total |
gauge | title |
Count of items in indexer backlog |
magento_cache_flush_count_total |
counter | - | Cumulative count of bin/magento cache:flush / admin flush-storage invocations |
Infrastructure Metrics
| Metric | Type | Labels | Description |
|---|---|---|---|
magento_store_count_total |
gauge | status |
Count of stores by status |
magento_website_count_total |
gauge | - | Total count of websites |
magento_shipments_count_total |
counter | source, store_code |
Count of shipments created |
magento_quotes_over_item_limit_count_total |
gauge | store_code |
Count of active carts with more than 100 items (performance risk) |
🔐 Security
Authentication Setup
- Generate Bearer Token: Navigate to Magento Admin → System → Integrations
- Create New Integration: Set up API access with appropriate permissions
- Configure Token: Use the generated access token in your Prometheus configuration
Best Practices
- Always use HTTPS for metrics endpoints in production
- Regularly rotate authentication tokens
- Restrict access to metrics endpoint via firewall rules
- Monitor access logs for unusual activity
IP Whitelisting
Consider restricting access to your Prometheus server IPs:
location /metrics {
allow 10.0.0.0/8; # Your Prometheus server
allow 172.16.0.0/12; # Internal network
deny all;
try_files $uri $uri/ /index.php?$args;
}
🔧 Custom Metrics
Creating a Custom Metric Aggregator
- Implement the Interface:
<?php
namespace YourNamespace\YourModule\Aggregator;
use RunAsRoot\PrometheusExporter\Api\MetricAggregatorInterface;
use RunAsRoot\PrometheusExporter\Service\UpdateMetricService;
class CustomMetricAggregator implements MetricAggregatorInterface
{
private UpdateMetricService $updateMetricService;
public function __construct(UpdateMetricService $updateMetricService)
{
$this->updateMetricService = $updateMetricService;
}
public function aggregate(): void
{
// Your metric collection logic here
$value = $this->calculateCustomMetric();
$this->updateMetricService->update(
'your_custom_metric_total',
(string) $value,
'gauge',
'Description of your custom metric',
['label1' => 'value1', 'label2' => 'value2']
);
}
private function calculateCustomMetric(): int
{
// Implement your metric calculation
return 42;
}
}
- Register in DI Configuration (
etc/di.xml):
<type name="RunAsRoot\PrometheusExporter\Metric\MetricAggregatorPool">
<arguments>
<argument name="items" xsi:type="array">
<item name="YourCustomAggregator" xsi:type="object">YourNamespace\YourModule\Aggregator\CustomMetricAggregator</item>
</argument>
</arguments>
</type>
Example: Product Rating Aggregator
<?php
namespace YourNamespace\YourModule\Aggregator;
use Magento\Review\Model\ResourceModel\Review\CollectionFactory;
use RunAsRoot\PrometheusExporter\Api\MetricAggregatorInterface;
use RunAsRoot\PrometheusExporter\Service\UpdateMetricService;
class ProductRatingAggregator implements MetricAggregatorInterface
{
private CollectionFactory $reviewCollectionFactory;
private UpdateMetricService $updateMetricService;
public function __construct(
CollectionFactory $reviewCollectionFactory,
UpdateMetricService $updateMetricService
) {
$this->reviewCollectionFactory = $reviewCollectionFactory;
$this->updateMetricService = $updateMetricService;
}
public function aggregate(): void
{
$collection = $this->reviewCollectionFactory->create()
->addStatusFilter(\Magento\Review\Model\Review::STATUS_APPROVED);
$averageRating = $collection->getConnection()
->fetchOne('SELECT AVG(rating_value) FROM rating_option_vote');
$this->updateMetricService->update(
'magento_product_average_rating',
(string) round($averageRating, 2),
'gauge',
'Average product rating across all approved reviews'
);
}
}
💻 CLI Commands
Collect Metrics Manually
php bin/magento run_as_root:metrics:collect
View Current Metrics
php bin/magento run_as_root:metrics:show
Clear Metrics Data
php bin/magento run_as_root:metrics:clear
🏗️ Architecture
Data Flow
- Cron Execution: Every minute, the
run_as_root_prometheus_metrics_aggregatorcron group executes - Metric Aggregation: Each enabled aggregator collects and processes data
- Data Storage: Aggregated metrics are stored in
run_as_root_prometheus_metricstable - Endpoint Response:
/metricscontroller serves data in Prometheus format
Key Components
- MetricAggregatorInterface: Contract for all metric collectors
- MetricAggregatorPool: Registry of all available aggregators
- UpdateMetricService: Service for storing metric data
- PrometheusController: HTTP endpoint for serving metrics
Database Schema
The module creates a dedicated table run_as_root_prometheus_metrics with the following structure:
metric_id: Primary keymetric_code: Unique metric identifiermetric_value: Numeric valuemetric_type: Type (gauge, counter, histogram)metric_help: Description textmetric_labels: JSON-encoded labelsupdated_at: Last update timestamp
🔍 Troubleshooting
Common Issues
Metrics Not Updating
# Check cron status
php bin/magento cron:status
# Run metrics collection manually
php bin/magento run_as_root:metrics:collect
# Check system logs
tail -f var/log/system.log | grep prometheus
Permission Denied on /metrics
- Verify web server has read access to Magento files
- Check Magento file permissions:
find . -type f -exec chmod 644 {} \; - Ensure proper ownership:
chown -R www-data:www-data .
High Memory Usage
- Reduce collection frequency in cron configuration
- Disable unused metric aggregators in admin configuration
- Consider implementing metric data retention policies
Debug Mode
Enable debug logging by adding to app/etc/env.php:
'system' => [
'default' => [
'prometheus_exporter' => [
'debug' => '1'
]
]
]
Performance Monitoring
Monitor the impact of metric collection:
# Check metric collection execution time
grep "prometheus.*aggregator" var/log/system.log
# Monitor database table size
SELECT COUNT(*) as total_metrics,
MAX(updated_at) as last_update
FROM run_as_root_prometheus_metrics;
🤝 Contributing
We welcome contributions! Here's how you can help:
Development Setup
- Fork the repository
- Clone your fork:
git clone https://gitlab.com/your-username/magento2-prometheus-exporter.git - Install dependencies:
composer install - Create a feature branch:
git checkout -b feature/your-feature-name
Code Standards
- Follow Magento 2 coding standards
- Write unit tests for new features
- Update documentation for new metrics or features
- Use meaningful commit messages
Pull Request Process
- Ensure all tests pass:
vendor/bin/phpunit - Update the CHANGELOG.md
- Submit a pull request with a clear description
- Respond to code review feedback
Reporting Issues
Please include:
- Magento version
- PHP version
- Module version
- Detailed error messages
- Steps to reproduce
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- run_as_root GmbH - Original development and maintenance
- Prometheus Community - For the excellent monitoring toolkit
- Magento Community - For feedback and contributions
📞 Support
- Email: [email protected]
- GitLab Issues: Report a bug
- Documentation: Wiki
Made with ❤️ by run_as_root
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to
Semantic Versioning.
[4.1.0] - 2026-05-28
Changed
symfony/consoleconstraint widened to^5.4.46|^6.0|^7.0for Magento 2.4.9 compatibility. (#65)- Test suite modernised: removed
getMockForAbstractClass()usage (deprecated in PHPUnit 10+), replacedreturnCallback()pattern to resolve deprecation notices, and completed mock method definitions. (#65)
[4.0.0] - 2026-04-20
Added
- GitHub Actions CI via
graycoreio/github-actions-magento2against the Mage-OSsupported-versionmatrix (Magento 2.4.6-p14 / 2.4.7-p9 / 2.4.8-p4). Unit tests, DI compile, Magento coding standard, and integration tests all run on every push and PR. (#60) phpcs.xml.distwith the Magento2 coding standard and project-specific exclusions.magento_complex_product_variations_above_recommended_level(gauge) — count of configurable products with more than 50 variations. (#25)magento_quotes_over_item_limit_count_total(gauge,store_codelabel) — count of active carts with more than 100 items. (#32)magento_products_with_bad_reviews_count_total(gauge,store_codelabel) — count of products withrating_summary < 60. Guarded byMagento_Reviewmodule-enabled check. (#26)magento_cache_flush_count_total(counter) — incremented on everyMagento\Framework\App\Cache\Manager::flush()invocation via a plugin. (#29)UpdateMetricServiceInterface::increment(string $code, array $labels = []): boolfor counter semantics.
Changed
- BREAKING: minimum PHP requirement is now 8.2 (was 7.4).
- BREAKING:
UpdateMetricServiceInterfacegained theincrement()method — downstream implementers must add it. magento/module-quoteis now a runtime dependency (added tocomposer.jsonrequire andmodule.xmlsequence).magento/module-reviewis now suggested; the bad-reviews aggregator no-ops if the module isn't installed.- Test suite migrated from phpunit 9.x patterns (
withConsecutive,at(),onConsecutiveCalls) towillReturnCallbackso it runs green on phpunit 9/10/12. composer.jsondeclaresrepositories.mage-os(public Mage-OS mirror) andconfig.allow-pluginsfor the Magento composer plugins graycore's coding-standard job pulls in.
Fixed
Test/Integration/Controller/IndexControllerTestnow supplies themetric_configuration/security/enable_tokenfixture so the test actually exercises the token validation code path.- Several unit tests had stale constructor mocks and mock-expectation drift versus current production signatures; all updated.
src/view/adminhtml/templates/system/config/tokenGeneratorButton.phtml: switched from deprecated$block->escape*to$escaper->escape*and fixed an unescaped-output XSS sniff.
Removed
- BREAKING: deleted
build/tools/(legacy GitLab-CI tooling). Closes GHSA-r39x-jcww-82v6 (symfony/process MSYS2 arg escaping).
[2.0.2] - 2021-06-11
Fixed
- Reset order count/amount metric before setting them
[2.0.1] - 2021-05-31
Fixed
- Fix order count reset
[2.0.0] - 2020-05-15
Added
- Added new CLI Command:
run_as_root:metrics:collect. - Added
CronJobCountAggregatorto collect metricmagento_cronjob_count_total. - Added
BrokenCronJobCountAggregatorto collect metricmagento_cronjob_broken_count_total. - Added
IndexerBacklogCountAggregatorto collect metricmagento_indexer_backlog_count_total. - Introduced custom cron group
run_as_root_prometheus_metrics_aggregator.
Changed
- Added some Interfaces instead of hard file links.
- Changed CLI namespace to
run_as_root. - Made all Test Cases final.
- Restructured module directories.
- Updated Readme.
Removed
- Removed Licenses from PHP Files.
[1.0.0] - 2019-06-14
Added
- Basic Module structure
- Metric Collector via Cron
- Console Command to view current metrics
- Cms Aggregator
- Order Aggregator
- Some basic readme
- Prometheus example configuration
- Basic Test Coverage
- StyleCi Integration
[1.0.1] - 2019-06-14
Changed
- Fixed composer.json
[1.0.2] - 2019-06-14
Removed
- Removed version from composer.json
[1.1.0] - 2019-06-18
Added
- CodeCov
- Customer Aggregator
- Additional Unit Tests
- Config wil be evaluated
- Updated Readme
Changed
- Fixed Metric Format
- Configuration is now Multiselect
[1.2.0] - 2019-07-10
Changed
- Interpret all metric aggregators as enabled when config value is NULL
| Version | Stability | QA Status | Compatibility | Released |
|---|---|---|---|---|
| 4.1.0 | stable | Fail | Magento 2.4.7-2.4.8 Details | 2026-05-28 14:32:16 |
| 4.0.0 | stable | Not tested | Not yet tested Details | 2026-04-20 13:44:03 |
| 3.2.6 | stable | Not tested | Not yet tested Details | 2025-12-28 12:14:51 |
| 3.2.5 | stable | Not tested | Not yet tested Details | 2025-12-19 14:19:30 |
| 3.2.4 | stable | Not tested | Not yet tested Details | 2025-08-29 12:52:00 |
| 3.2.3 | stable | Not tested | Not yet tested Details | 2025-06-03 06:47:10 |
| 3.2.2 | stable | Not tested | Not yet tested Details | 2024-11-12 11:42:28 |
| 3.2.1 | stable | Not tested | Not yet tested Details | 2024-11-07 10:27:50 |
| 3.2.0 | stable | Not tested | Not yet tested Details | 2024-11-07 10:27:01 |
| 3.1.6 | stable | Not tested | Not yet tested Details | 2023-11-22 08:05:19 |
| 3.1.5 | stable | Not tested | Not yet tested Details | 2023-08-21 15:17:58 |
| 3.1.4 | stable | Not tested | Not yet tested Details | 2023-07-07 09:18:46 |
| 3.1.3 | stable | Not tested | Not yet tested Details | 2023-07-07 09:08:32 |
| 3.1.2 | stable | Not tested | Not yet tested Details | 2023-07-07 08:48:58 |
| 3.1.1 | stable | Not tested | Not yet tested Details | 2023-06-26 07:11:38 |
| 3.1.0 | stable | Not tested | Not yet tested Details | 2023-06-23 14:55:53 |
| 3.0.1 | stable | Not tested | Not yet tested Details | 2021-12-06 08:27:49 |
| 2.0.2 | stable | Not tested | Not yet tested Details | 2021-06-14 10:56:49 |
| 2.0.1 | stable | Not tested | Not yet tested Details | 2021-06-01 08:39:32 |
| 2.0.0 | stable | Not tested | Not yet tested Details | 2021-06-01 08:37:53 |
| 1.2.0 | stable | Not tested | Not yet tested Details | 2019-07-10 09:13:15 |
| 1.1.0 | stable | Not tested | Not yet tested Details | 2019-06-18 09:11:40 |
| 1.0.2 | stable | Not tested | Not yet tested Details | 2019-06-14 15:42:05 |
| 1.0.1 | stable | Not tested | Not yet tested Details | 2019-06-14 15:37:50 |
Requires 20
| Package | Constraint |
|---|---|
| php | ^8.2 |
| magento/framework | * |
| magento/module-payment | * |
| magento/module-eav | * |
| magento/module-cron | * |
| magento/module-cms | * |
| magento/module-shipping | * |
| magento/module-catalog | * |
| magento/module-sales | * |
| magento/module-quote | * |
| laminas/laminas-http | ^2.15.0 |
| magento/module-config | * |
| magento/module-backend | * |
| guzzlehttp/guzzle | ^7.4.5 |
| symfony/console | ^5.4.46|^6.0|^7.0 |
| psr/log | ^1.1|^2.0|^3.0 |
| monolog/monolog | ^2.9.0|^3.0 |
| magento/module-store | * |
| magento/module-indexer | * |
| magento/zend-db | * |
Requires-dev 1
| Package | Constraint |
|---|---|
| phpunit/phpunit | ^9.5|^10.0 |
Conflicts 4
| Package | Constraint |
|---|---|
| symfony/process | <5.4.46 |
| guzzlehttp/guzzle | <7.4.5 |
| monolog/monolog | <2.9.0 |
| symfony/console | <5.4.46 |
Suggests 1
| Package | Reason |
|---|---|
| magento/module-review | Enables the magento_products_with_bad_reviews_count_total metric |
Compatibility
Each Magento release line is installed on its supported PHP versions, then the module is built (DI compilation + static-content deploy) and its unit and integration suites are run. The matrix shows the lines and PHP versions the module is confirmed to install and run on. Code-quality results further down (phpstan, phpcs, …) are reported separately and never affect compatibility.
Code Quality
Advisory checks against the module's source. Static analysis runs once across the whole module; PHPStan re-runs per Magento + PHP version because resolvable symbols differ between releases. These NEVER affect the Compatibility badge — a phpcs finding can't make a module incompatible.
Static analysis
Coding standards (phpcs), mess detection (phpmd), copy-pasted code (cpd), PHP cross-version compatibility, composer.json validity. Each runs once for the whole module.
| Tool | Status | Findings | Summary |
|---|---|---|---|
| PHPCS | Fail | 277 | 29 errors, 248 warnings (ruleset: Magento2) — 32 auto-fixable with phpcbf |
| PHPMD | Warning | 16 | 16 rule violations (MissingImport:7, UnusedLocalVariable:5, UnusedFormalParameter:3, ExcessiveMethodLength:1) |
| Cpd | Warning | 3 | 3 duplicated chunks spanning 71 total lines (min-lines=5, min-tokens=70) |
| Composer validate | Info | 15 | valid; 15 advisory notes (composer validate --strict) |
PHPStan
Type-checks the module's PHP against a real Magento install at the configured gate level. Re-runs per Magento and PHP version because resolvable symbols differ between releases. Cell → details modal.
Tests
Unit and integration suites, run for each applicable Magento and PHP version. A test failure speaks to the module's behaviour, not its compatibility with a Magento line, so it is reported here separately and never reddens the compatibility matrix.
Unit tests
Security
Security checks run directly against the module: an audit of its declared dependencies for known vulnerabilities (composer audit) and a scan of its source for malware and web-shell signatures. Each runs once. A malware detection fails the version outright.
More from run_as_root
View vendorTurn an existing module into recurring revenue.
If you already maintain a Magento 2 module on GitHub or GitLab, listing it on Packagento takes about five minutes. We mirror your tags, handle distribution signing, and route paid licenses through Stripe Connect, so you can keep shipping the way you already do.