You've already forked wc-licensed-product
Add Grafana dashboard and wp-prometheus integration (v0.7.5)
- Add example Grafana dashboard with 24 panels for license metrics - Register dashboard with wp-prometheus via hook - Add dashboard documentation with PromQL examples and alerting rules - Update README with monitoring section Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
22
CHANGELOG.md
22
CHANGELOG.md
@@ -7,6 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.7.5] - 2026-02-03
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **Grafana Dashboard**: Example dashboard for license metrics monitoring
|
||||||
|
- 24 panels organized into 4 sections: License Overview, Downloads & Versions, API Metrics, Errors & Rate Limiting
|
||||||
|
- Template variables for data source and instance filtering
|
||||||
|
- Includes example Prometheus alerting rules
|
||||||
|
- **WP Prometheus Dashboard Integration**: Dashboard automatically registered with wp-prometheus
|
||||||
|
- Appears in Settings > WP Prometheus > Dashboards when metrics are enabled
|
||||||
|
- Uses `wp_prometheus_register_dashboards` hook for seamless integration
|
||||||
|
- Documentation for Grafana dashboard installation and PromQL query examples
|
||||||
|
|
||||||
|
### New Files
|
||||||
|
|
||||||
|
- `docs/grafana-dashboard.json` - Complete Grafana dashboard with 24 panels
|
||||||
|
- `docs/grafana-dashboard.md` - Installation and usage documentation
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Updated README with "Monitoring with Prometheus & Grafana" section
|
||||||
|
|
||||||
## [0.7.4] - 2026-02-03
|
## [0.7.4] - 2026-02-03
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
36
CLAUDE.md
36
CLAUDE.md
@@ -2031,3 +2031,39 @@ Added Prometheus metrics integration to expose license and API metrics for monit
|
|||||||
- Static methods allow increment from API controllers without dependency injection
|
- Static methods allow increment from API controllers without dependency injection
|
||||||
- Counter values persist across requests via `wclp_prometheus_counters` option
|
- Counter values persist across requests via `wclp_prometheus_counters` option
|
||||||
- Gauges query database on each metric collection (uses existing statistics methods)
|
- Gauges query database on each metric collection (uses existing statistics methods)
|
||||||
|
|
||||||
|
### 2026-02-03 - Grafana Dashboard & WP Prometheus Integration
|
||||||
|
|
||||||
|
**Overview:**
|
||||||
|
|
||||||
|
Added example Grafana dashboard JSON and integrated with wp-prometheus dashboard registration system.
|
||||||
|
|
||||||
|
**New files:**
|
||||||
|
|
||||||
|
- `docs/grafana-dashboard.json` - Complete Grafana dashboard with 24 panels
|
||||||
|
- `docs/grafana-dashboard.md` - Installation and usage documentation
|
||||||
|
|
||||||
|
**Dashboard panels:**
|
||||||
|
|
||||||
|
- License Overview: Total, Active, Lifetime, Expiring Soon, Expired, Revoked stats + pie chart + time series
|
||||||
|
- Downloads & Versions: Total downloads, active versions, download trends
|
||||||
|
- API Metrics: Request rates by endpoint/result, pie chart breakdown, top requests table
|
||||||
|
- Errors & Rate Limiting: Rate limit events, validation errors by type over time
|
||||||
|
|
||||||
|
**WP Prometheus integration:**
|
||||||
|
|
||||||
|
- Dashboard automatically registered via `wp_prometheus_register_dashboards` hook
|
||||||
|
- Appears in Settings > WP Prometheus > Dashboards tab when metrics are enabled
|
||||||
|
- Uses file-based registration with metadata (title, description, icon, plugin attribution)
|
||||||
|
|
||||||
|
**Modified files:**
|
||||||
|
|
||||||
|
- `src/Metrics/PrometheusController.php` - Added `registerDashboard()` method and hook registration
|
||||||
|
- `docs/grafana-dashboard.md` - Added wp-prometheus installation option as recommended method
|
||||||
|
- `README.md` - Added "Monitoring with Prometheus & Grafana" section linking to dashboard docs
|
||||||
|
|
||||||
|
**Technical notes:**
|
||||||
|
|
||||||
|
- Dashboard registration only occurs when metrics are enabled (same condition as metric collection)
|
||||||
|
- Uses `dashicons-admin-network` icon for dashboard list
|
||||||
|
- File path uses `WC_LICENSED_PRODUCT_PLUGIN_DIR` constant for reliable path resolution
|
||||||
|
|||||||
32
README.md
32
README.md
@@ -393,6 +393,38 @@ The plugin sends automatic email notifications (configurable via WooCommerce > S
|
|||||||
- **Expiration Warning (1 day)**: Urgent reminder sent 1 day before expiration
|
- **Expiration Warning (1 day)**: Urgent reminder sent 1 day before expiration
|
||||||
- **License Expired**: Notification when a license auto-expires
|
- **License Expired**: Notification when a license auto-expires
|
||||||
|
|
||||||
|
## Monitoring with Prometheus & Grafana
|
||||||
|
|
||||||
|
The plugin integrates with [wp-prometheus](https://src.bundespruefstelle.ch/magdev/wp-prometheus) to expose metrics for monitoring and alerting.
|
||||||
|
|
||||||
|
### Enable Metrics
|
||||||
|
|
||||||
|
1. Install and configure the wp-prometheus plugin
|
||||||
|
2. Go to WooCommerce > Settings > Licensed Products > Metrics
|
||||||
|
3. Enable "Prometheus Metrics"
|
||||||
|
|
||||||
|
### Available Metrics
|
||||||
|
|
||||||
|
**Gauges:**
|
||||||
|
|
||||||
|
- `wclp_licenses_total{status}` - License counts by status
|
||||||
|
- `wclp_licenses_lifetime_total` - Lifetime licenses
|
||||||
|
- `wclp_licenses_expiring_soon` - Licenses expiring within 30 days
|
||||||
|
- `wclp_downloads_total` - Total file downloads
|
||||||
|
- `wclp_versions_active_total` - Active product versions
|
||||||
|
|
||||||
|
**Counters:**
|
||||||
|
|
||||||
|
- `wclp_api_requests_total{endpoint,result}` - API requests by endpoint and result
|
||||||
|
- `wclp_rate_limit_exceeded_total{endpoint}` - Rate limit events
|
||||||
|
- `wclp_validation_errors_total{error_type}` - Validation errors by type
|
||||||
|
|
||||||
|
### Grafana Dashboard
|
||||||
|
|
||||||
|
An example Grafana dashboard is included at [docs/grafana-dashboard.json](docs/grafana-dashboard.json).
|
||||||
|
|
||||||
|
See [docs/grafana-dashboard.md](docs/grafana-dashboard.md) for installation instructions, panel descriptions, and alerting examples.
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
See [CHANGELOG.md](CHANGELOG.md) for version history and changes.
|
See [CHANGELOG.md](CHANGELOG.md) for version history and changes.
|
||||||
|
|||||||
1748
docs/grafana-dashboard.json
Normal file
1748
docs/grafana-dashboard.json
Normal file
File diff suppressed because it is too large
Load Diff
219
docs/grafana-dashboard.md
Normal file
219
docs/grafana-dashboard.md
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
# Grafana Dashboard for WC Licensed Product
|
||||||
|
|
||||||
|
This dashboard provides comprehensive monitoring for the WC Licensed Product plugin using Prometheus metrics exposed via the [wp-prometheus](https://src.bundespruefstelle.ch/magdev/wp-prometheus) plugin.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
1. **WP Prometheus Plugin** - Install and configure [wp-prometheus](https://src.bundespruefstelle.ch/magdev/wp-prometheus) on your WordPress site
|
||||||
|
2. **Prometheus** - Configure Prometheus to scrape your WordPress metrics endpoint
|
||||||
|
3. **Grafana** - Grafana 9.0+ with Prometheus data source configured
|
||||||
|
4. **Enable Metrics** - In WordPress admin: WooCommerce > Settings > Licensed Products > Metrics > Enable Prometheus Metrics
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Option 1: Via WP Prometheus Settings (Recommended)
|
||||||
|
|
||||||
|
When metrics are enabled, the dashboard is automatically registered with wp-prometheus:
|
||||||
|
|
||||||
|
1. Go to **Settings > WP Prometheus** in WordPress admin
|
||||||
|
2. Navigate to the **Dashboards** tab
|
||||||
|
3. Find "WC Licensed Product - License Metrics" in the list
|
||||||
|
4. Click **Download JSON** to get the dashboard file
|
||||||
|
5. Import the downloaded file into Grafana
|
||||||
|
|
||||||
|
### Option 2: Manual Import
|
||||||
|
|
||||||
|
1. Open Grafana and navigate to **Dashboards > Import**
|
||||||
|
2. Upload the `grafana-dashboard.json` file or paste its contents
|
||||||
|
3. Select your Prometheus data source
|
||||||
|
4. Click **Import**
|
||||||
|
|
||||||
|
### Configure Variables
|
||||||
|
|
||||||
|
The dashboard includes two template variables:
|
||||||
|
|
||||||
|
- **datasource** - Select your Prometheus data source
|
||||||
|
- **instance** - Filter by WordPress instance (useful for multi-site monitoring)
|
||||||
|
|
||||||
|
## Dashboard Panels
|
||||||
|
|
||||||
|
### License Overview
|
||||||
|
|
||||||
|
| Panel | Description |
|
||||||
|
| --- | --- |
|
||||||
|
| Total Licenses | Total count of all licenses |
|
||||||
|
| Active Licenses | Licenses with `status=active` |
|
||||||
|
| Lifetime Licenses | Licenses without expiration date |
|
||||||
|
| Expiring Soon (30d) | Licenses expiring within 30 days |
|
||||||
|
| Expired Licenses | Licenses with `status=expired` |
|
||||||
|
| Revoked Licenses | Licenses with `status=revoked` |
|
||||||
|
| Licenses by Status | Pie chart showing distribution |
|
||||||
|
| License Status Over Time | Time series of license counts |
|
||||||
|
|
||||||
|
### Downloads & Versions
|
||||||
|
|
||||||
|
| Panel | Description |
|
||||||
|
| --- | --- |
|
||||||
|
| Total Downloads | Cumulative download count |
|
||||||
|
| Active Product Versions | Number of active versions |
|
||||||
|
| Downloads Over Time | Download trend graph |
|
||||||
|
| Downloads (Selected Range) | Downloads in selected time range |
|
||||||
|
|
||||||
|
### API Metrics
|
||||||
|
|
||||||
|
| Panel | Description |
|
||||||
|
| --- | --- |
|
||||||
|
| API Requests (5m intervals) | Stacked bar chart by endpoint/result |
|
||||||
|
| Requests by Endpoint | Donut chart of endpoint distribution |
|
||||||
|
| Top API Requests | Table of most frequent requests |
|
||||||
|
|
||||||
|
### Errors & Rate Limiting
|
||||||
|
|
||||||
|
| Panel | Description |
|
||||||
|
| --- | --- |
|
||||||
|
| Rate Limit Events (Total) | Total HTTP 429 responses |
|
||||||
|
| Validation Errors (Total) | Total validation failures |
|
||||||
|
| Validation Errors Over Time | Error trend by type |
|
||||||
|
| Validation Errors by Type | Pie chart breakdown |
|
||||||
|
| Rate Limit Events by Endpoint | Rate limits per endpoint |
|
||||||
|
|
||||||
|
## Metrics Reference
|
||||||
|
|
||||||
|
### Gauges (current values)
|
||||||
|
|
||||||
|
```promql
|
||||||
|
# Licenses by status
|
||||||
|
wclp_licenses_total{status="active|expired|revoked|inactive"}
|
||||||
|
|
||||||
|
# Lifetime licenses (no expiration)
|
||||||
|
wclp_licenses_lifetime_total
|
||||||
|
|
||||||
|
# Licenses with expiration date
|
||||||
|
wclp_licenses_expiring_total
|
||||||
|
|
||||||
|
# Licenses expiring within 30 days
|
||||||
|
wclp_licenses_expiring_soon
|
||||||
|
|
||||||
|
# Total downloads
|
||||||
|
wclp_downloads_total
|
||||||
|
|
||||||
|
# Active product versions
|
||||||
|
wclp_versions_active_total
|
||||||
|
```
|
||||||
|
|
||||||
|
### Counters (cumulative)
|
||||||
|
|
||||||
|
```promql
|
||||||
|
# API requests by endpoint and result
|
||||||
|
wclp_api_requests_total{endpoint="validate|status|activate|update-check", result="success|error"}
|
||||||
|
|
||||||
|
# Rate limit exceeded events
|
||||||
|
wclp_rate_limit_exceeded_total{endpoint="validate|status|activate|update-check"}
|
||||||
|
|
||||||
|
# Validation errors by type
|
||||||
|
wclp_validation_errors_total{error_type="license_not_found|domain_mismatch|license_expired|license_revoked|..."}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Example Prometheus Queries
|
||||||
|
|
||||||
|
### Success Rate
|
||||||
|
|
||||||
|
```promql
|
||||||
|
sum(rate(wclp_api_requests_total{result="success"}[5m])) /
|
||||||
|
sum(rate(wclp_api_requests_total[5m])) * 100
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Rate by Endpoint
|
||||||
|
|
||||||
|
```promql
|
||||||
|
sum by (endpoint) (rate(wclp_api_requests_total{result="error"}[5m]))
|
||||||
|
```
|
||||||
|
|
||||||
|
### License Churn (new activations)
|
||||||
|
|
||||||
|
```promql
|
||||||
|
increase(wclp_licenses_total{status="active"}[1d])
|
||||||
|
```
|
||||||
|
|
||||||
|
### Top Validation Errors
|
||||||
|
|
||||||
|
```promql
|
||||||
|
topk(5, sum by (error_type) (wclp_validation_errors_total))
|
||||||
|
```
|
||||||
|
|
||||||
|
## Alerting Examples
|
||||||
|
|
||||||
|
Add these alerts to your Prometheus alerting rules:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
groups:
|
||||||
|
- name: wc-licensed-product
|
||||||
|
rules:
|
||||||
|
# High rate limit events
|
||||||
|
- alert: HighRateLimitEvents
|
||||||
|
expr: increase(wclp_rate_limit_exceeded_total[5m]) > 10
|
||||||
|
for: 5m
|
||||||
|
labels:
|
||||||
|
severity: warning
|
||||||
|
annotations:
|
||||||
|
summary: "High rate limiting on {{ $labels.endpoint }}"
|
||||||
|
|
||||||
|
# Many expiring licenses
|
||||||
|
- alert: LicensesExpiringSoon
|
||||||
|
expr: wclp_licenses_expiring_soon > 20
|
||||||
|
for: 1h
|
||||||
|
labels:
|
||||||
|
severity: info
|
||||||
|
annotations:
|
||||||
|
summary: "{{ $value }} licenses expiring within 30 days"
|
||||||
|
|
||||||
|
# API error rate
|
||||||
|
- alert: HighAPIErrorRate
|
||||||
|
expr: |
|
||||||
|
sum(rate(wclp_api_requests_total{result="error"}[5m])) /
|
||||||
|
sum(rate(wclp_api_requests_total[5m])) > 0.1
|
||||||
|
for: 10m
|
||||||
|
labels:
|
||||||
|
severity: warning
|
||||||
|
annotations:
|
||||||
|
summary: "API error rate above 10%"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Prometheus Configuration
|
||||||
|
|
||||||
|
Add to your `prometheus.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
scrape_configs:
|
||||||
|
- job_name: 'wordpress'
|
||||||
|
metrics_path: '/metrics'
|
||||||
|
scheme: https
|
||||||
|
bearer_token: 'YOUR_WP_PROMETHEUS_TOKEN'
|
||||||
|
static_configs:
|
||||||
|
- targets: ['your-wordpress-site.com']
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### No data showing
|
||||||
|
|
||||||
|
1. Verify wp-prometheus is installed and configured
|
||||||
|
2. Check that metrics are enabled in WC Licensed Product settings
|
||||||
|
3. Confirm Prometheus can reach your WordPress metrics endpoint
|
||||||
|
4. Check the data source selection in Grafana
|
||||||
|
|
||||||
|
### Missing metrics
|
||||||
|
|
||||||
|
Some metrics only appear after relevant actions occur:
|
||||||
|
|
||||||
|
- `wclp_api_requests_total` - After API requests
|
||||||
|
- `wclp_rate_limit_exceeded_total` - After rate limit events
|
||||||
|
- `wclp_validation_errors_total` - After validation errors
|
||||||
|
|
||||||
|
### Counter resets
|
||||||
|
|
||||||
|
Counters persist in WordPress options and survive restarts. To reset:
|
||||||
|
|
||||||
|
```php
|
||||||
|
\Jeremias\WcLicensedProduct\Metrics\PrometheusController::resetCounters();
|
||||||
|
```
|
||||||
@@ -43,6 +43,29 @@ final class PrometheusController
|
|||||||
}
|
}
|
||||||
|
|
||||||
add_action('wp_prometheus_collect_metrics', [$this, 'collectMetrics']);
|
add_action('wp_prometheus_collect_metrics', [$this, 'collectMetrics']);
|
||||||
|
add_action('wp_prometheus_register_dashboards', [$this, 'registerDashboard']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register Grafana dashboard with wp-prometheus
|
||||||
|
*
|
||||||
|
* @param object $provider The dashboard provider object
|
||||||
|
*/
|
||||||
|
public function registerDashboard(object $provider): void
|
||||||
|
{
|
||||||
|
$dashboardFile = WC_LICENSED_PRODUCT_PLUGIN_DIR . 'docs/grafana-dashboard.json';
|
||||||
|
|
||||||
|
if (!file_exists($dashboardFile)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$provider->register_dashboard('wc-licensed-product', [
|
||||||
|
'title' => __('WC Licensed Product - License Metrics', 'wc-licensed-product'),
|
||||||
|
'description' => __('Monitor license status, downloads, API usage, and validation errors.', 'wc-licensed-product'),
|
||||||
|
'icon' => 'dashicons-admin-network',
|
||||||
|
'file' => $dashboardFile,
|
||||||
|
'plugin' => 'WC Licensed Product',
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Plugin Name: WooCommerce Licensed Product
|
* Plugin Name: WooCommerce Licensed Product
|
||||||
* Plugin URI: https://src.bundespruefstelle.ch/magdev/wc-licensed-product
|
* Plugin URI: https://src.bundespruefstelle.ch/magdev/wc-licensed-product
|
||||||
* Description: WooCommerce plugin to sell software products using license keys with domain-based validation.
|
* Description: WooCommerce plugin to sell software products using license keys with domain-based validation.
|
||||||
* Version: 0.7.4
|
* Version: 0.7.5
|
||||||
* Author: Marco Graetsch
|
* Author: Marco Graetsch
|
||||||
* Author URI: https://src.bundespruefstelle.ch/magdev
|
* Author URI: https://src.bundespruefstelle.ch/magdev
|
||||||
* License: GPL-2.0-or-later
|
* License: GPL-2.0-or-later
|
||||||
@@ -28,7 +28,7 @@ if (!defined('ABSPATH')) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Plugin constants
|
// Plugin constants
|
||||||
define('WC_LICENSED_PRODUCT_VERSION', '0.7.4');
|
define('WC_LICENSED_PRODUCT_VERSION', '0.7.5');
|
||||||
define('WC_LICENSED_PRODUCT_PLUGIN_FILE', __FILE__);
|
define('WC_LICENSED_PRODUCT_PLUGIN_FILE', __FILE__);
|
||||||
define('WC_LICENSED_PRODUCT_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
define('WC_LICENSED_PRODUCT_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
||||||
define('WC_LICENSED_PRODUCT_PLUGIN_URL', plugin_dir_url(__FILE__));
|
define('WC_LICENSED_PRODUCT_PLUGIN_URL', plugin_dir_url(__FILE__));
|
||||||
|
|||||||
Reference in New Issue
Block a user