{"id":50354689,"url":"https://github.com/slybase/wordpress-slymetrics","last_synced_at":"2026-05-29T22:01:47.276Z","repository":{"id":315064056,"uuid":"1054487312","full_name":"SlyBase/wordpress-slymetrics","owner":"SlyBase","description":"A WordPress plugin for rich export of metrics for prometheus. Grafana dashboard visualize these metrics","archived":false,"fork":false,"pushed_at":"2026-05-28T19:44:52.000Z","size":7225,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-28T21:20:27.494Z","etag":null,"topics":["grafana","metrics","prometheus","wordpress"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SlyBase.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"slydlake"}},"created_at":"2025-09-10T23:12:50.000Z","updated_at":"2026-05-28T19:44:48.000Z","dependencies_parsed_at":"2025-09-16T14:40:25.125Z","dependency_job_id":"b4ba8014-d4c2-47d2-94af-0713096efdba","html_url":"https://github.com/SlyBase/wordpress-slymetrics","commit_stats":null,"previous_names":["slydlake/slymetrics","slybase/wordpress-slymetrics"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/SlyBase/wordpress-slymetrics","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SlyBase%2Fwordpress-slymetrics","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SlyBase%2Fwordpress-slymetrics/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SlyBase%2Fwordpress-slymetrics/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SlyBase%2Fwordpress-slymetrics/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SlyBase","download_url":"https://codeload.github.com/SlyBase/wordpress-slymetrics/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SlyBase%2Fwordpress-slymetrics/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33672125,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-29T02:00:06.066Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["grafana","metrics","prometheus","wordpress"],"created_at":"2026-05-29T22:01:47.146Z","updated_at":"2026-05-29T22:01:47.268Z","avatar_url":"https://github.com/SlyBase.png","language":"PHP","funding_links":["https://github.com/sponsors/slydlake"],"categories":[],"sub_categories":[],"readme":"[![Sponsor on GitHub](https://img.shields.io/badge/Sponsor-%E2%9D%A4-pink?logo=github)](https://github.com/sponsors/slydlake)\n\n# SlyMetrics - WordPress Prometheus and MCP metrics provider\n\nA comprehensive WordPress plugin that exports WordPress metrics in Prometheus and MCP format for monitoring including Grafana Dashboard for multi sites.\n\nWordpress Plugin page: [https://wordpress.org/plugins/slymetrics](https://wordpress.org/plugins/slymetrics/)\n\n![Grafana Dashboard](./assets//screenshot-4.png)\n\n## 🚀 Features\n\n- **📊 Comprehensive Metrics**: WordPress content, users, plugins, themes, and system information\n- **🔒 Enterprise Security**: Advanced authentication with rate limiting, input validation, and XSS protection\n- **🌐 Multiple Endpoints**: Clean URLs (`/slymetrics/metrics`), REST API, and query parameter fallbacks\n- **🤖 MCP Integration**: Expose metrics via WordPress MCP Adapter as AI-accessible tools (`metrics/get-summary`, `metrics/get-users`, `metrics/get-posts`, `metrics/get-plugins`, `metrics/get-site-health`, `metrics/get-content`, `metrics/get-storage`, `metrics/get-health-checks`)\n- **🏥 Health Monitoring**: Integration with WordPress Site Health API for detailed system checks\n- **📈 Grafana Optimized**: Display-friendly metrics specifically designed for clean table visualizations\n- **🐳 Container Ready**: Environment variable support for Docker, Kubernetes, and CI/CD pipelines\n- **⚡ High Performance**: 3-tier intelligent caching system with 3x performance improvement\n- **🔄 Auto-Discovery**: Automatic endpoint detection and fallback mechanisms\n- **📱 Admin Interface**: User-friendly settings page with token management and health status\n- **🛡️ Production Ready**: Enterprise-grade architecture with comprehensive error handling\n- **💾 Memory Optimized**: Lazy loading and optimized data structures for heavy operations\n- **🌐 Professional Code**: Multi-language support with enterprise-grade documentation\n\n## 📊 Metrics Overview\n\n| Metric Name | Type | Description | Labels |\n|-------------|------|-------------|---------|\n| `wordpress_users_total` | counter | Number of users per role | `wordpress_site`, `role` |\n| `wordpress_posts_total` | counter | Number of posts by status | `wordpress_site`, `status`: `published`, `draft`, `all` |\n| `wordpress_pages_total` | counter | Number of pages by status | `wordpress_site`, `status`: `published`, `draft`, `all` |\n| `wordpress_plugins_total` | counter | Active and inactive plugins | `wordpress_site`, `status`: `active`, `inactive`, `all` |\n| `wordpress_plugins_update_total` | counter | Plugin update status | `wordpress_site`, `status`: `available`, `uptodate` |\n| `wordpress_themes_total` | counter | Number of installed themes | `wordpress_site`, `type`: `child`, `parent` |\n| `wordpress_comments_total` | counter | Number of comments by status | `wordpress_site`, `status`: `approved`, `spam`, `trash`, `post_trashed`, `moderated` |\n| `wordpress_categories_total` | counter | Total number of categories | `wordpress_site` |\n| `wordpress_media_total` | counter | Total number of media items | `wordpress_site` |\n| `wordpress_tags_total` | counter | Total number of tags | `wordpress_site` |\n| `wordpress_version_info` | gauge | WordPress version information | `wordpress_site`, `version`, `update_available` |\n| `wordpress_autoload_options_total` | gauge | Number of autoloaded options | `wordpress_site` |\n| `wordpress_autoload_size_bytes` | gauge | Size of autoloaded options in bytes | `wordpress_site` |\n| `wordpress_autoload_transients_total` | gauge | Number of autoloaded transients | `wordpress_site` |\n| `wordpress_php_info` | gauge | PHP configuration information | `wordpress_site`, `type`, `label` |\n| `wordpress_php_version_info` | gauge | PHP version as readable string | `wordpress_site`, `php_version` |\n| `wordpress_config_info` | gauge | WordPress and PHP configuration values | `wordpress_site`, `config`, `value` |\n| `wordpress_memory_limit_info` | gauge | Memory limit for table display | `wordpress_site`, `memory_limit` |\n| `wordpress_upload_max_info` | gauge | Upload max filesize for table display | `wordpress_site`, `upload_max` |\n| `wordpress_post_max_info` | gauge | Post max size for table display | `wordpress_site`, `post_max` |\n| `wordpress_exec_time_info` | gauge | Max execution time for table display | `wordpress_site`, `exec_time` |\n| `wordpress_database_size_bytes` | gauge | Database size in bytes | `wordpress_site` |\n| `wordpress_directory_size_bytes` | gauge | Directory sizes in bytes | `wordpress_site`, `directory`: `uploads`, `themes`, `plugins`, `total` |\n| `wordpress_health_check_total` | gauge | Site health check results | `wordpress_site`, `category`: `critical`, `recommended`, `good`, `security`, `performance`, `total_failed` |\n| `wordpress_health_check_detail_info` | gauge | Individual health check test results | `wordpress_site`, `test_name`, `status`, `category`, `description` |\n\n## 🔧 Installation\n\n1. Download the plugin files\n2. Upload to your WordPress `wp-content/plugins/` directory\n3. Activate the plugin through the WordPress admin interface\n4. Configure authentication tokens in **Settings** → **SlyMetrics**\n\n## 🌐 API Endpoints\n\nThe plugin provides multiple endpoint options to ensure compatibility across different server configurations:\n\n### Primary Endpoints (Require Permalink Support)\n```\n/slymetrics/metrics\n/slymetrics\n```\n**Note:** Requires WordPress permalink support (Settings → Permalinks → Select any option except \"Plain\").\n\n### Fallback Endpoints (No Permalink Support Required)\n```\n/index.php?rest_route=/slymetrics/v1/metrics    # REST API fallback\n/?slymetrics=1                                  # Query parameter fallback\n/wp-json/slymetrics/v1/metrics                  # Standard REST API\n```\n\n**Note:** If permalink support is not available, use the fallback URLs above.\n\n## 🔐 Authentication Methods\n\nThe plugin supports multiple authentication methods:\n\n### 1. Bearer Token (Recommended)\n```bash\ncurl -H \"Authorization: Bearer YOUR_TOKEN\" \\\n     http://yoursite.com/slymetrics/metrics\n```\n\n### 2. API Key (URL Parameter)\n```bash\ncurl \"http://yoursite.com/slymetrics/metrics?api_key=YOUR_API_KEY\"\n```\n\n### 3. WordPress Administrator\n- Automatic access for logged-in WordPress administrators\n\n## 🛡️ Security Features\n\n### Encrypted Token Storage\n- All authentication tokens are encrypted using **AES-256-CBC**\n- Unique initialization vectors (IV) for each encryption\n- Secure random token generation (64-character hex strings)\n\n### Environment Variable Support\nFor enhanced security and stable token configuration, set environment variables:\n\n```bash\n# Generate a secure encryption key\nexport SLYMETRICS_ENCRYPTION_KEY=$(openssl rand -base64 32)\n\n# Set a stable bearer token for Prometheus\nexport SLYMETRICS_BEARER_TOKEN=$(openssl rand -hex 32)\n```\n\n**Environment Variables:**\n- **`SLYMETRICS_ENCRYPTION_KEY`**: Base64-encoded 32-byte encryption key for API key storage\n- **`SLYMETRICS_BEARER_TOKEN`**: Stable bearer token for Prometheus authentication (plain text, 64-character hex)\n\n**When using environment variables:**\n- Encryption key is not stored in the database\n- Bearer token remains stable across container restarts\n- Token regeneration via web interface is disabled for environment-managed tokens\n- Enhanced security indicator in admin interface\n- Perfect for containerized deployments and CI/CD pipelines\n\n## ⚙️ Configuration\n\n### Basic Setup\n1. Navigate to **Settings** → **Prometheus Metrics**\n2. Copy the Bearer Token or API Key\n3. Configure your Prometheus scraper\n\n![Wordpress Admin Page](./assets//screenshot-1.png)\n\n### Prometheus Configuration\n\n#### Primary Configuration (requires permalinks)\n```yaml\n# prometheus.yml\nscrape_configs:\n  - job_name: 'wordpress'\n    scheme: https # use here http or https\n    static_configs:\n      - targets: ['yoursite.com']\n    metrics_path: '/slymetrics/metrics'\n    authorization:\n      type: Bearer\n      credentials: 'your_bearer_token_here'\n    scrape_interval: 60s\n```\n\n#### REST API Fallback Configuration\n```yaml\n# prometheus.yml (REST API fallback)\nscrape_configs:\n  - job_name: 'wordpress'\n    scheme: https # use here http or https\n    static_configs:\n      - targets: ['yoursite.com']\n    metrics_path: '/index.php'\n    params:\n      rest_route: ['/slymetrics/v1/metrics']\n    authorization:\n      type: Bearer\n      credentials: 'your_bearer_token_here'\n    scrape_interval: 60s\n```\n\n#### Query Parameter Fallback Configuration\n```yaml\n# prometheus.yml (query parameter fallback)\nscrape_configs:\n  - job_name: 'wordpress'\n    scheme: https # use here http or https\n    static_configs:\n      - targets: ['yoursite.com']\n    metrics_path: '/'\n    params:\n      slymetrics: ['1']\n    authorization:\n      type: Bearer\n      credentials: 'your_bearer_token_here'\n    scrape_interval: 60s\n```\n\n### Docker Environment\n```bash\n# With stable bearer token for Prometheus\ndocker run -e SLYMETRICS_ENCRYPTION_KEY=\"$(openssl rand -base64 32)\" \\\n           -e SLYMETRICS_BEARER_TOKEN=\"your_stable_prometheus_token\" \\\n           your-wordpress-image\n\n# Generate new tokens\ndocker run -e SLYMETRICS_ENCRYPTION_KEY=\"$(openssl rand -base64 32)\" \\\n           -e SLYMETRICS_BEARER_TOKEN=\"$(openssl rand -hex 32)\" \\\n           your-wordpress-image\n```\n\n### Environment Variables\n```bash\n# .env file\nSLYMETRICS_ENCRYPTION_KEY=base64_encoded_32_byte_key\nSLYMETRICS_BEARER_TOKEN=your_stable_64_character_hex_token\n```\n\n**Benefits of using `SLYMETRICS_BEARER_TOKEN`:**\n- **Stable Configuration**: Token remains consistent across container restarts\n- **Prometheus Integration**: No need to update Prometheus configuration when containers restart\n- **CI/CD Friendly**: Tokens can be managed via secrets management systems\n- **Production Ready**: Eliminates token rotation issues in production environments\n\n### Container Environments\n\n#### Docker Compose\n```yaml\nversion: '3.8'\nservices:\n  wordpress:\n    image: wordpress:latest\n    environment:\n      - SLYMETRICS_ENCRYPTION_KEY=${SLYMETRICS_ENCRYPTION_KEY}\n      - SLYMETRICS_BEARER_TOKEN=${SLYMETRICS_BEARER_TOKEN}\n    volumes:\n      - ./wordpress-exporter-prometheus.php:/var/www/html/wp-content/plugins/wordpress-prometheus-metrics/wordpress-exporter-prometheus.php\n\n  # Example Prometheus configuration with stable token\n  prometheus:\n    image: prom/prometheus:latest\n    volumes:\n      - ./prometheus.yml:/etc/prometheus/prometheus.yml\n    # Use the same token in prometheus.yml:\n    # credentials: '${SLYMETRICS_BEARER_TOKEN}'\n```\n\n#### Kubernetes Deployment\n```yaml\napiVersion: apps/v1\nkind: Deployment\nmetadata:\n  name: wordpress\nspec:\n  template:\n    spec:\n      containers:\n      - name: wordpress\n        image: wordpress:latest\n        env:\n        - name: SLYMETRICS_ENCRYPTION_KEY\n          valueFrom:\n            secretKeyRef:\n              name: slymetrics-secrets\n              key: slymetrics-encryption-key\n        - name: SLYMETRICS_BEARER_TOKEN\n          valueFrom:\n            secretKeyRef:\n              name: slymetrics-secrets\n              key: slymetrics-bearer-token\n---\n# Example: Create secret with stable tokens\napiVersion: v1\nkind: Secret\nmetadata:\n  name: wordpress-secrets\ntype: Opaque\ndata:\n  # Base64 encoded values\n  slymetrics-encryption-key: \u003cbase64-encoded-32-byte-key\u003e\n  slymetrics-bearer-token: \u003cbase64-encoded-64-char-hex-token\u003e\n```\n\n**Kubernetes Token Management:**\n```bash\n# Generate and create secret\nkubectl create secret generic slymetrics-secrets \\\n  --from-literal=slymetrics-encryption-key=\"$(openssl rand -base64 32)\" \\\n  --from-literal=slymetrics-bearer-token=\"$(openssl rand -hex 32)\"\n\n# Use the same token in your Prometheus configuration\nkubectl get secret slymetrics-secrets -o jsonpath='{.data.slymetrics-bearer-token}' | base64 -d\n```\n\n## � Available Metrics\n\n### Core WordPress Metrics\n\n| Metric Name | Type | Description | Labels | Example |\n|-------------|------|-------------|--------|---------|\n| `wordpress_users_total` | counter | Number of users per role | `wordpress_site`, `role` | `wordpress_users_total{role=\"administrator\"} 1` |\n| `wordpress_posts_total` | counter | Number of posts by status | `wordpress_site`, `status` | `wordpress_posts_total{status=\"published\"} 5` |\n| `wordpress_pages_total` | counter | Number of pages by status | `wordpress_site`, `status` | `wordpress_pages_total{status=\"published\"} 3` |\n| `wordpress_plugins_total` | counter | Number of plugins by status | `wordpress_site`, `status` | `wordpress_plugins_total{status=\"active\"} 12` |\n| `wordpress_plugins_update_total` | counter | Plugin update status | `wordpress_site`, `status` | `wordpress_plugins_update_total{status=\"available\"} 2` |\n| `wordpress_themes_total` | counter | Number of installed themes | `wordpress_site`, `type` | `wordpress_themes_total{type=\"parent\"} 5` |\n| `wordpress_comments_total` | counter | Number of comments by status | `wordpress_site`, `status` | `wordpress_comments_total{status=\"approved\"} 45` |\n| `wordpress_categories_total` | counter | Total number of categories | `wordpress_site` | `wordpress_categories_total{} 8` |\n| `wordpress_media_total` | counter | Total number of media items | `wordpress_site` | `wordpress_media_total{} 150` |\n| `wordpress_tags_total` | counter | Total number of tags | `wordpress_site` | `wordpress_tags_total{} 25` |\n\n### System Information Metrics\n\n| Metric Name | Type | Description | Labels | Example |\n|-------------|------|-------------|--------|---------|\n| `wordpress_version_info` | gauge | WordPress version information | `wordpress_site`, `version`, `update_available` | `wordpress_version_info{version=\"6.8.2\"} 1` |\n| `wordpress_php_info` | gauge | PHP configuration details | `wordpress_site`, `type`, `label` | `wordpress_php_info{type=\"version\",label=\"8.2.29\"} 80229` |\n| `wordpress_database_size_bytes` | gauge | Database size in bytes | `wordpress_site` | `wordpress_database_size_bytes{} 125450000` |\n| `wordpress_directory_size_bytes` | gauge | Directory sizes in bytes | `wordpress_site`, `directory` | `wordpress_directory_size_bytes{directory=\"uploads\"} 512800000` |\n\n### Display-Friendly Metrics (Grafana Optimized)\n\n| Metric Name | Type | Description | Labels | Example |\n|-------------|------|-------------|--------|---------|\n| `wordpress_php_version_info` | gauge | PHP version (display format) | `wordpress_site`, `php_version` | `wordpress_php_version_info{php_version=\"8.2.29\"} 1` |\n| `wordpress_config_info` | gauge | WordPress and PHP config values | `wordpress_site`, `config`, `value` | `wordpress_config_info{config=\"memory_limit\",value=\"256M\"} 268435456` |\n| `wordpress_memory_limit_info` | gauge | Memory limit (display format) | `wordpress_site`, `memory_limit` | `wordpress_memory_limit_info{memory_limit=\"256M\"} 1` |\n| `wordpress_upload_max_info` | gauge | Upload max size (display format) | `wordpress_site`, `upload_max` | `wordpress_upload_max_info{upload_max=\"64M\"} 1` |\n| `wordpress_post_max_info` | gauge | Post max size (display format) | `wordpress_site`, `post_max` | `wordpress_post_max_info{post_max=\"64M\"} 1` |\n| `wordpress_exec_time_info` | gauge | Max execution time (display format) | `wordpress_site`, `exec_time` | `wordpress_exec_time_info{exec_time=\"30\"} 1` |\n\n### Performance \u0026 Health Metrics\n\n| Metric Name | Type | Description | Labels | Example |\n|-------------|------|-------------|--------|---------|\n| `wordpress_autoload_options_total` | gauge | Number of autoloaded options | `wordpress_site` | `wordpress_autoload_options_total{} 245` |\n| `wordpress_autoload_size_bytes` | gauge | Size of autoloaded options in bytes | `wordpress_site` | `wordpress_autoload_size_bytes{} 156200` |\n| `wordpress_autoload_transients_total` | gauge | Number of autoloaded transients | `wordpress_site` | `wordpress_autoload_transients_total{} 12` |\n\n### Site Health Metrics\n\n| Metric Name | Type | Description | Labels | Example |\n|-------------|------|-------------|--------|---------|\n| `wordpress_health_check_total` | gauge | Site health check summary | `wordpress_site`, `category` | `wordpress_health_check_total{category=\"critical\"} 0` |\n| `wordpress_health_check_detail_info` | gauge | Individual health check results | `wordpress_site`, `test_name`, `status`, `category`, `description` | `wordpress_health_check_detail_info{test_name=\"php_version\",status=\"good\"} 1` |\n\n### Label Descriptions\n\n- **`wordpress_site`**: WordPress site name/title\n- **`role`**: User role (administrator, editor, author, etc.)\n- **`status`**: Status type (published, draft, active, inactive, etc.)\n- **`type`**: Category type (parent, child, version, etc.)\n- **`directory`**: Directory name (uploads, themes, plugins, total)\n- **`category`**: Health check category (critical, recommended, good, security, performance)\n- **`test_name`**: Individual health check test identifier\n- **`description`**: Human-readable description of the health check\n\n## 📈 Example Metrics Output\n\n```\ncurl -H \"Authorization: Bearer f5634d6a966856848e2f3f4a139e534b844805f7561d86642adb19060719e95d\" \"http://192.168.178.21:30107/slymetrics/metrics\"\n# HELP wordpress_users_total Number of users per role.\n# TYPE wordpress_users_total counter\nwordpress_users_total{wordpress_site=\"New wordpress blog\",role=\"administrator\"} 1\nwordpress_users_total{wordpress_site=\"New wordpress blog\",role=\"contributor\"} 1\nwordpress_users_total{wordpress_site=\"New wordpress blog\",role=\"none\"} 0\nwordpress_users_total{wordpress_site=\"New wordpress blog\",role=\"total\"} 2\n# HELP wordpress_posts_total Number of posts.\n# TYPE wordpress_posts_total counter\nwordpress_posts_total{wordpress_site=\"New wordpress blog\",status=\"published\"} 1\nwordpress_posts_total{wordpress_site=\"New wordpress blog\",status=\"draft\"} 0\nwordpress_posts_total{wordpress_site=\"New wordpress blog\",status=\"all\"} 1\n# HELP wordpress_pages_total Number of pages.\n# TYPE wordpress_pages_total counter\nwordpress_pages_total{wordpress_site=\"New wordpress blog\",status=\"published\"} 1\nwordpress_pages_total{wordpress_site=\"New wordpress blog\",status=\"draft\"} 1\nwordpress_pages_total{wordpress_site=\"New wordpress blog\",status=\"all\"} 2\n# HELP wordpress_plugins_total Number of active and inactive plugins.\n# TYPE wordpress_plugins_total counter\nwordpress_plugins_total{wordpress_site=\"New wordpress blog\",status=\"active\"} 2\nwordpress_plugins_total{wordpress_site=\"New wordpress blog\",status=\"inactive\"} 1\nwordpress_plugins_total{wordpress_site=\"New wordpress blog\",status=\"all\"} 3\n# HELP wordpress_plugins_update_total Plugin update status.\n# TYPE wordpress_plugins_update_total counter\nwordpress_plugins_update_total{wordpress_site=\"New wordpress blog\",status=\"available\"} 0\nwordpress_plugins_update_total{wordpress_site=\"New wordpress blog\",status=\"uptodate\"} 3\n# HELP wordpress_themes_total Number of installed themes.\n# TYPE wordpress_themes_total counter\nwordpress_themes_total{wordpress_site=\"New wordpress blog\",type=\"child\"} 0\nwordpress_themes_total{wordpress_site=\"New wordpress blog\",type=\"parent\"} 0\n# HELP wordpress_comments_total Total number of comments by status.\n# TYPE wordpress_comments_total counter\nwordpress_comments_total{wordpress_site=\"New wordpress blog\",status=\"approved\"} 1\nwordpress_comments_total{wordpress_site=\"New wordpress blog\",status=\"spam\"} 0\nwordpress_comments_total{wordpress_site=\"New wordpress blog\",status=\"trash\"} 0\nwordpress_comments_total{wordpress_site=\"New wordpress blog\",status=\"post_trashed\"} 0\nwordpress_comments_total{wordpress_site=\"New wordpress blog\",status=\"all\"} 1\nwordpress_comments_total{wordpress_site=\"New wordpress blog\",status=\"moderated\"} 0\n# HELP wordpress_categories_total Total number of categories.\n# TYPE wordpress_categories_total counter\nwordpress_categories_total{wordpress_site=\"New wordpress blog\"} 1\n# HELP wordpress_media_total Total number of media items.\n# TYPE wordpress_media_total counter\nwordpress_media_total{wordpress_site=\"New wordpress blog\"} 0\n# HELP wordpress_tags_total Total number of tags.\n# TYPE wordpress_tags_total counter\nwordpress_tags_total{wordpress_site=\"New wordpress blog\"} 0\n# HELP wordpress_autoload_options_total Number of autoloaded options.\n# TYPE wordpress_autoload_options_total gauge\nwordpress_autoload_options_total{wordpress_site=\"New wordpress blog\"} 0\n# HELP wordpress_autoload_size_bytes Size of autoloaded options in bytes.\n# TYPE wordpress_autoload_size_bytes gauge\nwordpress_autoload_size_bytes{wordpress_site=\"New wordpress blog\"} 0\n# HELP wordpress_autoload_transients_total Number of autoloaded transients.\n# TYPE wordpress_autoload_transients_total gauge\nwordpress_autoload_transients_total{wordpress_site=\"New wordpress blog\"} 0\n# HELP wordpress_database_size_bytes Database size in bytes.\n# TYPE wordpress_database_size_bytes gauge\nwordpress_database_size_bytes{wordpress_site=\"New wordpress blog\"} 828375.04\n# HELP wordpress_directory_size_bytes Directory sizes in bytes.\n# TYPE wordpress_directory_size_bytes gauge\nwordpress_directory_size_bytes{wordpress_site=\"New wordpress blog\",directory=\"uploads\"} 0\nwordpress_directory_size_bytes{wordpress_site=\"New wordpress blog\",directory=\"themes\"} 0\nwordpress_directory_size_bytes{wordpress_site=\"New wordpress blog\",directory=\"plugins\"} 13621002.24\nwordpress_directory_size_bytes{wordpress_site=\"New wordpress blog\",directory=\"total\"} 13621002.24\n# HELP wordpress_health_check_total Site health check results.\n# TYPE wordpress_health_check_total gauge\nwordpress_health_check_total{wordpress_site=\"New wordpress blog\",category=\"good\"} 5\nwordpress_health_check_total{wordpress_site=\"New wordpress blog\",category=\"recommended\"} 2\nwordpress_health_check_total{wordpress_site=\"New wordpress blog\",category=\"critical\"} 0\nwordpress_health_check_total{wordpress_site=\"New wordpress blog\",category=\"security\"} 2\nwordpress_health_check_total{wordpress_site=\"New wordpress blog\",category=\"performance\"} 0\nwordpress_health_check_total{wordpress_site=\"New wordpress blog\",category=\"total_failed\"} 2\n# HELP wordpress_health_check_detail_info Individual health check test results.\n# TYPE wordpress_health_check_detail_info gauge\nwordpress_health_check_detail_info{wordpress_site=\"New wordpress blog\",test_name=\"file_editing\",status=\"recommended\",category=\"security\",description=\"File editing should be disabled in production environments\"} 0\nwordpress_health_check_detail_info{wordpress_site=\"New wordpress blog\",test_name=\"debug_mode\",status=\"good\",category=\"security\",description=\"Debug mode is properly disabled\"} 1\nwordpress_health_check_detail_info{wordpress_site=\"New wordpress blog\",test_name=\"plugin_updates\",status=\"good\",category=\"security\",description=\"All plugins are up to date\"} 1\nwordpress_health_check_detail_info{wordpress_site=\"New wordpress blog\",test_name=\"php_version\",status=\"good\",category=\"performance\",description=\"PHP version 8.2.29 is current\"} 1\nwordpress_health_check_detail_info{wordpress_site=\"New wordpress blog\",test_name=\"php_memory_limit\",status=\"good\",category=\"performance\",description=\"Memory limit 256M is adequate\"} 1\nwordpress_health_check_detail_info{wordpress_site=\"New wordpress blog\",test_name=\"database_connection\",status=\"good\",category=\"general\",description=\"Database connection is working properly\"} 1\nwordpress_health_check_detail_info{wordpress_site=\"New wordpress blog\",test_name=\"https_status\",status=\"recommended\",category=\"security\",description=\"Site should use HTTPS for better security\"} 0\n# HELP wordpress_version WordPress version information.\n# TYPE wordpress_version gauge\nwordpress_version{wordpress_site=\"New wordpress blog\",version=\"6.8.2\",update_available=\"0\"} 1\n# HELP wordpress_php_info PHP configuration information.\n# TYPE wordpress_php_info gauge\nwordpress_php_info{wordpress_site=\"New wordpress blog\",type=\"version\",label=\"8.2.29\"} 80229\nwordpress_php_info{wordpress_site=\"New wordpress blog\",type=\"major_version\",label=\"8\"} 8\nwordpress_php_info{wordpress_site=\"New wordpress blog\",type=\"minor_version\",label=\"2\"} 2\nwordpress_php_info{wordpress_site=\"New wordpress blog\",type=\"release_version\",label=\"29\"} 29\nwordpress_php_info{wordpress_site=\"New wordpress blog\",type=\"max_input_vars\",label=\"1000\"} 1000\nwordpress_php_info{wordpress_site=\"New wordpress blog\",type=\"max_execution_time\",label=\"30\"} 30\nwordpress_php_info{wordpress_site=\"New wordpress blog\",type=\"memory_limit\",label=\"256M\"} 268435456\nwordpress_php_info{wordpress_site=\"New wordpress blog\",type=\"max_input_time\",label=\"-1\"} -1\nwordpress_php_info{wordpress_site=\"New wordpress blog\",type=\"upload_max_filesize\",label=\"2M\"} 2097152\nwordpress_php_info{wordpress_site=\"New wordpress blog\",type=\"post_max_size\",label=\"8M\"} 8388608\n# HELP wordpress_php_version_info PHP version as readable string.\n# TYPE wordpress_php_version_info gauge\nwordpress_php_version_info{wordpress_site=\"New wordpress blog\",php_version=\"8.2.29\"} 1\n# HELP wordpress_config_info WordPress and PHP configuration values.\n# TYPE wordpress_config_info gauge\nwordpress_config_info{wordpress_site=\"New wordpress blog\",config=\"max_input_vars\",value=\"1000\"} 1000\nwordpress_config_info{wordpress_site=\"New wordpress blog\",config=\"max_execution_time\",value=\"30\"} 30\nwordpress_config_info{wordpress_site=\"New wordpress blog\",config=\"memory_limit\",value=\"256M\"} 268435456\nwordpress_config_info{wordpress_site=\"New wordpress blog\",config=\"max_input_time\",value=\"-1\"} -1\nwordpress_config_info{wordpress_site=\"New wordpress blog\",config=\"upload_max_filesize\",value=\"2M\"} 2097152\nwordpress_config_info{wordpress_site=\"New wordpress blog\",config=\"post_max_size\",value=\"8M\"} 8388608\n# HELP wordpress_memory_limit_info Memory limit for table display.\n# TYPE wordpress_memory_limit_info gauge\nwordpress_memory_limit_info{wordpress_site=\"New wordpress blog\",memory_limit=\"256M\"} 1\n# HELP wordpress_upload_max_info Upload max filesize for table display.\n# TYPE wordpress_upload_max_info gauge\nwordpress_upload_max_info{wordpress_site=\"New wordpress blog\",upload_max=\"2M\"} 1\n# HELP wordpress_post_max_info Post max size for table display.\n# TYPE wordpress_post_max_info gauge\nwordpress_post_max_info{wordpress_site=\"New wordpress blog\",post_max=\"8M\"} 1\n# HELP wordpress_exec_time_info Max execution time for table display.\n# TYPE wordpress_exec_time_info gauge\nwordpress_exec_time_info{wordpress_site=\"New wordpress blog\",exec_time=\"30\"} 1\n```\n# HELP wordpress_directory_size_bytes Directory sizes in bytes.\n# TYPE wordpress_directory_size_bytes gauge\nwordpress_directory_size_bytes{wordpress_site=\"New wordpress blog\",directory=\"uploads\"} 0\nwordpress_directory_size_bytes{wordpress_site=\"New wordpress blog\",directory=\"themes\"} 13.56\nwordpress_directory_size_bytes{wordpress_site=\"New wordpress blog\",directory=\"plugins\"} 10.48\nwordpress_directory_size_bytes{wordpress_site=\"New wordpress blog\",directory=\"total\"} 24.05\n# HELP wordpress_health_check_total Site health check results.\n# TYPE wordpress_health_check_total gauge\nwordpress_health_check_total{wordpress_site=\"New wordpress blog\",category=\"critical\"} 0\nwordpress_health_check_total{wordpress_site=\"New wordpress blog\",category=\"recommended\"} 3\nwordpress_health_check_total{wordpress_site=\"New wordpress blog\",category=\"good\"} 4\nwordpress_health_check_total{wordpress_site=\"New wordpress blog\",category=\"security\"} 3\nwordpress_health_check_total{wordpress_site=\"New wordpress blog\",category=\"performance\"} 0\nwordpress_health_check_total{wordpress_site=\"New wordpress blog\",category=\"total_failed\"} 3\n# HELP wordpress_health_check_detail_info Individual health check test results.\n# TYPE wordpress_health_check_detail_info gauge\nwordpress_health_check_detail_info{wordpress_site=\"New wordpress blog\",test_name=\"file_editing\",status=\"recommended\",category=\"security\",description=\"File editing should be disabled in production environments\"} 0\nwordpress_health_check_detail_info{wordpress_site=\"New wordpress blog\",test_name=\"debug_mode\",status=\"good\",category=\"security\",description=\"Debug mode is properly disabled\"} 1\nwordpress_health_check_detail_info{wordpress_site=\"New wordpress blog\",test_name=\"plugin_updates\",status=\"recommended\",category=\"security\",description=\"1 plugin(s) need updates\"} 0\nwordpress_health_check_detail_info{wordpress_site=\"New wordpress blog\",test_name=\"php_version\",status=\"good\",category=\"performance\",description=\"PHP version 8.2.29 is current\"} 1\nwordpress_health_check_detail_info{wordpress_site=\"New wordpress blog\",test_name=\"php_memory_limit\",status=\"good\",category=\"performance\",description=\"Memory limit 256M is adequate\"} 1\nwordpress_health_check_detail_info{wordpress_site=\"New wordpress blog\",test_name=\"database_connection\",status=\"good\",category=\"general\",description=\"Database connection is working properly\"} 1\nwordpress_health_check_detail_info{wordpress_site=\"New wordpress blog\",test_name=\"https_status\",status=\"recommended\",category=\"security\",description=\"Site should use HTTPS for better security\"} 0\n```\n\n## 🏗️ Technical Requirements\n\n- **WordPress:** 5.0 or higher\n- **PHP:** 7.4 or higher\n- **PHP Extensions:** OpenSSL (recommended for encryption)\n- **Permissions:** WordPress administrator access for configuration\n\n### Fallback Mode\nIf OpenSSL is not available, the plugin falls back to Base64 encoding for token storage.\n\n## 🚨 Security Considerations\n\n### Production Recommendations\n1. **Use Environment Variables**: Set `SLYMETRICS_ENCRYPTION_KEY` for production\n2. **Secure Network**: Use HTTPS for all metric requests\n3. **Access Control**: Restrict Prometheus server access to metrics endpoint\n4. **Regular Token Rotation**: Regenerate tokens periodically\n5. **Monitor Access**: Review WordPress access logs for suspicious activity\n\n### Network Security (optional)\n\n**Apache Configuration:** Edit your virtual host file (typically `/etc/apache2/sites-available/000-default.conf` or `/etc/apache2/sites-available/your-site.conf`)\n\n```apache\n# Example: Restrict access by IP (Apache)\n\u003cLocation \"/slymetrics/metrics\"\u003e\n    Require ip 10.0.0.0/8\n    Require ip 192.168.0.0/16\n\u003c/Location\u003e\n\n\u003cLocation \"/wp-json/slymetrics/v1/metrics\"\u003e\n    Require ip 10.0.0.0/8\n    Require ip 192.168.0.0/16\n\u003c/Location\u003e\n```\n\n**Nginx Configuration:** Add to your server block in `/etc/nginx/sites-available/your-site`\n```nginx\nlocation /slymetrics/metrics {\n    allow 10.0.0.0/8;\n    allow 192.168.0.0/16;\n    deny all;\n    try_files $uri $uri/ /index.php?$args;\n}\n\nlocation /wp-json/slymetrics/v1/metrics {\n    allow 10.0.0.0/8;\n    allow 192.168.0.0/16;\n    deny all;\n    try_files $uri $uri/ /index.php?$args;\n}\n```\n\n## 🛠️ Troubleshooting\n\n### Common Issues\n\n**Metrics endpoint returns JSON instead of plain text:**\n- Check if WordPress REST API is properly configured\n- Verify the route registration\n\n**Authentication fails:**\n- Verify token is correctly copied (no extra spaces)\n- Check if environment variable is properly set\n- Ensure WordPress user has admin privileges\n- CHeck if apache rewrite is working properly\n\n**Empty metrics:**\n- Check WordPress database connectivity\n- Verify plugin is activated\n- Review WordPress error logs\n\n\n## 📊 Grafana Dashboards\n\n### WordPress Comprehensive Monitoring Dashboard\n\nA complete Grafana dashboard that combines health monitoring, performance metrics, and content statistics.\n\n**Dashboard File:** `grafana/wordpress-metrics-dashboard.json`\n\n![Grafana Dashboard](./assets/screenshot-4.png)\n![Grafana Dashboard](./assets/screenshot-5.png)\n![Grafana Dashboard](./assets/screenshot-6.png)\n\n## 🤝 Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Commit your changes\n4. Push to the branch\n5. Create a Pull Request","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslybase%2Fwordpress-slymetrics","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fslybase%2Fwordpress-slymetrics","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslybase%2Fwordpress-slymetrics/lists"}