diff --git a/composer.json b/composer.json index 1058f36..2241a6f 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,7 @@ { "require": { - "symfony/polyfill-php80": "^v1.23.1" + "symfony/polyfill-php80": "^v1.24.0", + "promphp/prometheus_client_php": "^2.6" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index 023cd74..cfd9b76 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,87 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1fa5276c2607f5e87566e1a033ef7d60", + "content-hash": "580809e61522eaa2e2ccba810d85789d", "packages": [ + { + "name": "promphp/prometheus_client_php", + "version": "v2.6.2", + "source": { + "type": "git", + "url": "https://github.com/PromPHP/prometheus_client_php.git", + "reference": "df77bbcc65bd173f2ffaf40ab4e1ca8716da8ce6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PromPHP/prometheus_client_php/zipball/df77bbcc65bd173f2ffaf40ab4e1ca8716da8ce6", + "reference": "df77bbcc65bd173f2ffaf40ab4e1ca8716da8ce6", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.2|^8.0" + }, + "replace": { + "endclothing/prometheus_client_php": "*", + "jimdo/prometheus_client_php": "*", + "lkaemmerling/prometheus_client_php": "*" + }, + "require-dev": { + "guzzlehttp/guzzle": "^6.3|^7.0", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5.4", + "phpstan/phpstan-phpunit": "^1.1.0", + "phpstan/phpstan-strict-rules": "^1.1.0", + "phpunit/phpunit": "^9.4", + "squizlabs/php_codesniffer": "^3.6", + "symfony/polyfill-apcu": "^1.6" + }, + "suggest": { + "ext-apc": "Required if using APCu.", + "ext-redis": "Required if using Redis.", + "promphp/prometheus_push_gateway_php": "An easy client for using Prometheus PushGateway.", + "symfony/polyfill-apcu": "Required if you use APCu on PHP8.0+" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Prometheus\\": "src/Prometheus/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Lukas Kämmerling", + "email": "kontakt@lukas-kaemmerling.de" + } + ], + "description": "Prometheus instrumentation library for PHP applications.", + "support": { + "issues": "https://github.com/PromPHP/prometheus_client_php/issues", + "source": "https://github.com/PromPHP/prometheus_client_php/tree/v2.6.2" + }, + "time": "2022-06-30T03:46:23+00:00" + }, { "name": "symfony/polyfill-php80", - "version": "v1.23.1", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", - "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", "shasum": "" }, "require": { @@ -26,7 +93,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -34,12 +101,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, "files": [ "bootstrap.php" ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, "classmap": [ "Resources/stubs" ] @@ -71,7 +138,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" }, "funding": [ { @@ -87,7 +154,7 @@ "type": "tidelift" } ], - "time": "2021-07-28T13:41:28+00:00" + "time": "2022-05-10T07:21:04+00:00" } ], "packages-dev": [], diff --git a/includes/_legacy.prometheus_custom_metrics.php b/includes/_legacy.prometheus_custom_metrics.php deleted file mode 100644 index 930bcdb..0000000 --- a/includes/_legacy.prometheus_custom_metrics.php +++ /dev/null @@ -1,28 +0,0 @@ -publish; - $n_posts_dra = $posts->draft; - $result .= "# HELP wp_posts_total Deprecated. Total number of posts published.\n"; - $result .= "# TYPE wp_posts_total counter\n"; - $result .= 'wp_posts_total{host="' . get_site_url() . '", status="published"} ' . $n_posts_pub . "\n"; - $result .= 'wp_posts_total{host="' . get_site_url() . '", status="draft"} ' . $n_posts_dra . "\n"; - } - - if ( ( $measure_all && filter_input( INPUT_GET, 'pages', FILTER_SANITIZE_STRING ) !== 'no' ) - || filter_input( INPUT_GET, 'pages', FILTER_SANITIZE_STRING ) === 'yes' ) { - $n_pages = wp_count_posts( 'page' ); - $result .= "# HELP wp_pages_total Deprecated. Total number of pages published.\n"; - $result .= "# TYPE wp_pages_total counter\n"; - $result .= 'wp_pages_total{host="' . get_site_url() . '", status="published"} ' . $n_pages->publish . "\n"; - $result .= 'wp_pages_total{host="' . get_site_url() . '", status="draft"} ' . $n_pages->draft . "\n"; - } - - return $result; -} \ No newline at end of file diff --git a/includes/classes/Default_Metrics_Loader.php b/includes/classes/Default_Metrics_Loader.php index 158d509..d4190c8 100644 --- a/includes/classes/Default_Metrics_Loader.php +++ b/includes/classes/Default_Metrics_Loader.php @@ -3,10 +3,12 @@ namespace WP_Prometheus_Metrics; use WP_Prometheus_Metrics\metrics\Database_Size_Metric; +use WP_Prometheus_Metrics\metrics\Info_Metric; use WP_Prometheus_Metrics\metrics\Options_Autoloaded_Count_Metric; use WP_Prometheus_Metrics\metrics\Options_Autoloaded_Size_Metric; use WP_Prometheus_Metrics\metrics\Pending_Updates_Metric; use WP_Prometheus_Metrics\metrics\Performance_Count_Posts_Metric; +use WP_Prometheus_Metrics\metrics\Performance_Write_File_To_WP_Upload_Dir_Metric; use WP_Prometheus_Metrics\metrics\Performance_Write_Temp_File_Metric; use WP_Prometheus_Metrics\metrics\Post_Types_Count_Metric; use WP_Prometheus_Metrics\metrics\Posts_Without_Content_Metric; @@ -15,33 +17,36 @@ use WP_Prometheus_Metrics\metrics\Users_Count_Metric; use WP_Prometheus_Metrics\metrics\Users_Sessions_Metric; -class Default_Metrics_Loader { - private $metrics_loaded = false; - - public function __construct() { - add_filter( 'prometheus_get_metrics', [ $this, 'load_default_metrics' ], 0 ); - } - - - function load_default_metrics( $metrics = [] ) { - if ( ! $this->metrics_loaded ) { - - new Database_Size_Metric(); - new Users_Count_Metric(); - new Users_Sessions_Metric(); - new Options_Autoloaded_Count_Metric(); - new Options_Autoloaded_Size_Metric(); - new Posts_Without_Content_Metric(); - new Posts_Without_Title_Metric(); - new Post_Types_Count_Metric(); - new Pending_Updates_Metric(); - new Transients_Autoloaded_Count_Metric(); - new Performance_Count_Posts_Metric(); - new Performance_Write_Temp_File_Metric(); - - $this->metrics_loaded = true; - } - - return $metrics; - } +class Default_Metrics_Loader +{ + private $metrics_loaded = false; + + public function __construct() + { + add_filter('prometheus-metrics-for-wp/get_metrics', [$this, 'load_default_metrics'], 0, 2); + } + + function load_default_metrics($metrics = []) + { + if (!$this->metrics_loaded) { + new Database_Size_Metric(); + new Info_Metric(); + new Options_Autoloaded_Count_Metric(); + new Options_Autoloaded_Size_Metric(); + new Pending_Updates_Metric(); + new Performance_Count_Posts_Metric(); + new Performance_Write_File_To_WP_Upload_Dir_Metric(); + new Performance_Write_Temp_File_Metric(); + new Post_Types_Count_Metric(); + new Posts_Without_Content_Metric(); + new Posts_Without_Title_Metric(); + new Transients_Autoloaded_Count_Metric(); + new Users_Count_Metric(); + new Users_Sessions_Metric(); + + $this->metrics_loaded = true; + } + + return $metrics; + } } diff --git a/includes/classes/Site_Health_Extension.php b/includes/classes/Site_Health_Extension.php index 881f423..db69732 100644 --- a/includes/classes/Site_Health_Extension.php +++ b/includes/classes/Site_Health_Extension.php @@ -2,162 +2,167 @@ namespace WP_Prometheus_Metrics; -class Site_Health_Extension { - public function __construct() { - add_filter( 'plugin_action_links_' . PROMETHEUS_PLUGIN_FILE, [ $this, 'add_plugin_action_links' ], 0, 1 ); - add_filter( 'site_health_navigation_tabs', [ $this, 'add_site_health_tab' ] ); - add_action( 'site_health_tab_content', [ $this, 'render_site_health_tab_content' ] ); - } - - function add_plugin_action_links( $actions = [] ) { - $actions[] = '' . _x( 'Settings', 'Site Health', 'prometheus-metrics-for-wp' ) . ''; - - return $actions; - } - - function add_site_health_tab( $tabs ) { - $tabs['prometheus'] = esc_html_x( 'Prometheus', 'Site Health', 'prometheus-metrics-for-wp' ); - - return $tabs; - } - - function render_site_health_tab_content( $tab ) { - // Do nothing if this is not our tab. - if ( 'prometheus' !== $tab ) { - return; - } - if ( ! current_user_can( 'administrator' ) ) { - echo _x( 'Access denied', 'Site Health', 'prometheus-metrics-for-wp' ); - - return; - } - - ?> +use WP_Prometheus_Metrics\metrics\Abstract_Metric; + +class Site_Health_Extension +{ + public function __construct() + { + add_filter('plugin_action_links_' . PROMETHEUS_PLUGIN_FILE, [$this, 'add_plugin_action_links'], 0, 1); + add_filter('site_health_navigation_tabs', [$this, 'add_site_health_tab']); + add_action('site_health_tab_content', [$this, 'render_site_health_tab_content']); + } + + function add_plugin_action_links($actions = []) + { + $actions[] = '' . _x('Settings', 'Site Health', 'prometheus-metrics-for-wp') . ''; + + return $actions; + } + + function add_site_health_tab($tabs) + { + $tabs['prometheus'] = esc_html_x('Prometheus', 'Site Health', 'prometheus-metrics-for-wp'); + + return $tabs; + } + + function render_site_health_tab_content($tab) + { + // Do nothing if this is not our tab. + if ('prometheus' !== $tab) { + return; + } + if (!current_user_can('administrator')) { + echo _x('Access denied', 'Site Health', 'prometheus-metrics-for-wp'); + + return; + } + + ?>
-

+

-

- +

+

- PROMETHEUS_KEY is: %s', 'Site Health', 'prometheus-metrics-for-wp' ), PROMETHEUS_KEY ); ?> + PROMETHEUS_KEY is: %s', 'Site Health', 'prometheus-metrics-for-wp'), PROMETHEUS_KEY); ?>

+ style="width:100%;">
- +

- PROMETHEUS_KEY set.', 'Site Health', 'prometheus-metrics-for-wp' ) ?> + PROMETHEUS_KEY set.', 'Site Health', 'prometheus-metrics-for-wp') ?>

- wp-config.php, i.e. like: ', 'Site Health', 'prometheus-metrics-for-wp' ) ?> + wp-config.php, i.e. like: ', 'Site Health', 'prometheus-metrics-for-wp') ?> define('PROMETHEUS_KEY','')

- +
-

- + -

Please write down they key, you won\'t see it here again.', 'Site Health', 'prometheus-metrics-for-wp' ) ?>

+ if (filter_input(INPUT_POST, 'generate_key', FILTER_VALIDATE_BOOL)) { + $prometheusUrl = prometheus_get_url(false); + ?> +

Please write down they key, you won\'t see it here again.', 'Site Health', 'prometheus-metrics-for-wp') ?>

- +
    - $key ) { - ?> + $key) { + ?>
  1. + } + ?>
- + ?>

+ type="submit">

- +
-

+

- I.e. to a hosting vendor and hosting rate:', 'Site Health', 'prometheus-metrics-for-wp' ); - ?> + I.e. to a hosting vendor and hosting rate:', 'Site Health', 'prometheus-metrics-for-wp'); + ?>

+ style="width:100%;">&label_hosting_vendor=MyExampleHoster&label_hosting_rate=FastWPHosting
-

+

- - - - + + + - + - - + - +
- get_metric_labels(); + $gauge = $registry->getOrRegisterGauge($this->namespace, $this->metric_name, $this->get_help_text(), array_keys($labels)); + $gauge->set($this->get_metric_value(), array_values($labels)); + } +} diff --git a/includes/classes/metrics/Abstract_Metric.php b/includes/classes/metrics/Abstract_Metric.php index fa63093..c7deccb 100644 --- a/includes/classes/metrics/Abstract_Metric.php +++ b/includes/classes/metrics/Abstract_Metric.php @@ -2,96 +2,96 @@ namespace WP_Prometheus_Metrics\metrics; -abstract class Abstract_Metric { - - public $metric_name; - public $type; - - public $legacy_get_param; - - /** - * Metric constructor. - * - * @param $metric_name String Name of the metric - * @param $type String The metrics type, defaults to "gauge" - * @param $legacy_get_param String (Deprecated) The legacy GET parameter, which is checked. Use metric_name instead. - */ - public function __construct( string $metric_name, string $type = 'gauge', $legacy_get_param = false ) { - $this->metric_name = str_replace( '-', '_', $metric_name ); - - // For legacy reasons, this is still supported. Just use the metric name instead - $this->legacy_get_param = $legacy_get_param; - - // @deprecated PROMETHEUS_LEGACY_TYPE -> will be removed in a future release - $this->type = defined( 'PROMETHEUS_LEGACY_TYPE' ) && PROMETHEUS_LEGACY_TYPE ? 'counter' : $type; - - add_filter( 'prometheus_get_metrics', [ $this, 'get_metric' ], 10, 1 ); - } - - public function get_metric( $metrics = [] ) { - $metrics[] = $this; - - return $metrics; - } - - public function print_metric( $measure_all = false ) { - if ( ! $this->is_enabled( $measure_all ) ) { - return; - } - echo "# HELP $this->metric_name {$this->get_help_text()}\n"; - echo "# TYPE $this->metric_name $this->type\n"; - echo $this->metric_name . '{' . $this->get_metric_labels() . '} ' . $this->get_cached_metric_value() . "\n"; - } - - public function get_metric_labels(): string { - $labels = [ 'host="' . get_site_url() . '"' ]; - foreach ( $_GET as $label => $value ) { - if ( str_starts_with( $label, 'label_' ) ) { - $label = sanitize_title( str_replace( [ 'label_', '-' ], [ '', '_' ], $label ) ); - $labels[] = $label . '="' . esc_attr( $value ) . '"'; - } - } - $labels = apply_filters( 'prometheus-metrics-for-wp/labels', $labels, $this->metric_name ); - - return join( ',', $labels ); - } - - public function is_enabled( $measure_all ) { - if ( $measure_all && filter_input( INPUT_GET, $this->metric_name, FILTER_SANITIZE_STRING ) !== 'no' ) { - return $measure_all; - } - - if ( filter_input( INPUT_GET, $this->metric_name, FILTER_SANITIZE_STRING ) === 'yes' ) { - return true; - } - - if ( $this->legacy_get_param && filter_input( INPUT_GET, $this->legacy_get_param, FILTER_SANITIZE_STRING ) === 'yes' ) { - _deprecated_argument( __FUNCTION__, '2.0', "Usage of legacy parameter $this->legacy_get_param is deprecated. Please use metric name instead: $this->metric_name" ); - - return true; - } - - return false; - } - - abstract function get_metric_value(); - - /** - * @return String Must be a function so i18n is supported - */ - abstract function get_help_text(): string; - - private function get_cached_metric_value() { - $transientKey = 'prometheus-metrics-for-wp/' . $this->metric_name; - $value = get_transient( $transientKey ); - if ( ! $value ) { - $value = $this->get_metric_value(); - $value = ( $value != 0 && empty( $value ) ? '-1' : $value ) . " " . ( time() * 1000 ); - $timeout = apply_filters( 'prometheus-metrics-for-wp/timeout', 3600, $this->metric_name ); // 1h by default - set_transient( $transientKey, $value, $timeout ); - } - - return $value; - } - +use Exception; +use Prometheus\CollectorRegistry; + +abstract class Abstract_Metric +{ + + public $metric_name; + public $namespace; + + + public $scheme; + public $host; + public $port; + + /** + * Metric constructor. + * + * @param $metric_name String Name of the metric + */ + public function __construct(string $metric_name, string $namespace = 'wp') + { + $this->metric_name = str_replace('-', '_', $metric_name); + $this->namespace = $namespace; + + add_filter('prometheus-metrics-for-wp/get_metrics', [$this, 'get_metric'], 10, 1); + + $this->scheme = parse_url(get_site_url(), PHP_URL_SCHEME); + $this->host = parse_url(get_site_url(), PHP_URL_HOST); + $this->port = parse_url(get_site_url(), PHP_URL_PORT); + } + + /** + * @param $registry CollectorRegistry + * @param $measure_all bool + */ + public function add_metric($registry, $measure_all) + { + if (!$this->is_enabled($measure_all)) { + return; + } + + try { + $this->internal_add_metric($registry); + } catch (Exception $e) { + error_log($e->getMessage()); + } + } + + abstract function internal_add_metric($registry); + + public function get_metric($metrics = []) + { + $metrics[] = $this; + + return $metrics; + } + + public function get_metric_labels(): array + { + $labels = [ + 'host' => $this->host, + 'scheme' => $this->scheme + ]; + if (!empty($this->port)) { + $labels['port'] = $this->port; + } + foreach ($_GET as $label => $value) { + if (str_starts_with($label, 'label_')) { + $label = sanitize_title(str_replace(['label_', '-'], ['', '_'], $label)); + $labels[$label] = $value; + } + } + return apply_filters('prometheus-metrics-for-wp/labels', $labels, $this->metric_name); + } + + public function is_enabled($measure_all) + { + if ($measure_all && filter_input(INPUT_GET, $this->namespace . '_' . $this->metric_name, FILTER_SANITIZE_STRING) !== 'no') { + return $measure_all; + } + + if (filter_input(INPUT_GET, $this->namespace . '_' . $this->metric_name, FILTER_SANITIZE_STRING) === 'yes') { + return true; + } + + return false; + } + + /** + * @return String Must be a function so i18n is supported + */ + abstract function get_help_text(): string; } \ No newline at end of file diff --git a/includes/classes/metrics/Database_Size_Metric.php b/includes/classes/metrics/Database_Size_Metric.php index ee43ffb..3b4f687 100644 --- a/includes/classes/metrics/Database_Size_Metric.php +++ b/includes/classes/metrics/Database_Size_Metric.php @@ -3,20 +3,22 @@ namespace WP_Prometheus_Metrics\metrics; -class Database_Size_Metric extends Abstract_Metric { +class Database_Size_Metric extends Abstract_Gauge_Metric +{ - public function __construct() { - parent::__construct( 'wp_db_size', 'gauge', 'db_size' ); - } + public function __construct() + { + parent::__construct('db_size'); + } - function get_metric_value() { - global $wpdb; - $size = $wpdb->get_var( "SELECT SUM(ROUND(((data_length + index_length) / 1024 / 1024), 2)) as value FROM information_schema.TABLES WHERE table_schema = '" . DB_NAME . "'" ); // phpcs:ignore WordPress.DB + function get_help_text(): string + { + return _x('Total DB size in MB', 'Metric Help Text', 'prometheus-metrics-for-wp'); + } - return $size; - } - - function get_help_text(): string { - return _x( 'Total DB size in MB', 'Metric Help Text', 'prometheus-metrics-for-wp' ); - } + function get_metric_value() + { + global $wpdb; + return $wpdb->get_var("SELECT SUM(ROUND(((data_length + index_length) / 1024 / 1024), 2)) as value FROM information_schema.TABLES WHERE table_schema = '" . DB_NAME . "'"); // phpcs:ignore WordPress.DB + } } diff --git a/includes/classes/metrics/Info_Metric.php b/includes/classes/metrics/Info_Metric.php new file mode 100644 index 0000000..410d2a2 --- /dev/null +++ b/includes/classes/metrics/Info_Metric.php @@ -0,0 +1,40 @@ + get_bloginfo('version'), + 'db_version' => $wp_db_version, + ] + ); + } + + function get_metric_value() + { + // This metric as no value, the interesting part is in it's labels. + // Returning a standard 1 value here. + return 1; + } + + function get_help_text(): string + { + return _x('Information about the WordPress environment', 'Metric Help Text', 'prometheus-metrics-for-wp'); + } +} diff --git a/includes/classes/metrics/Options_Autoloaded_Count_Metric.php b/includes/classes/metrics/Options_Autoloaded_Count_Metric.php index b654e71..f10525a 100644 --- a/includes/classes/metrics/Options_Autoloaded_Count_Metric.php +++ b/includes/classes/metrics/Options_Autoloaded_Count_Metric.php @@ -3,19 +3,23 @@ namespace WP_Prometheus_Metrics\metrics; -class Options_Autoloaded_Count_Metric extends Abstract_Metric { +class Options_Autoloaded_Count_Metric extends Abstract_Gauge_Metric +{ - public function __construct() { - parent::__construct( 'wp_options_autoload', 'gauge', 'autoload' ); - } + public function __construct() + { + parent::__construct('options_autoload'); + } - function get_metric_value() { - global $wpdb; + function get_metric_value() + { + global $wpdb; - return $wpdb->get_var( "SELECT count(*) FROM $wpdb->options WHERE `autoload` = 'yes'" ); // phpcs:ignore WordPress.DB - } + return $wpdb->get_var("SELECT count(*) FROM $wpdb->options WHERE `autoload` = 'yes'"); // phpcs:ignore WordPress.DB + } - function get_help_text(): string { - return _x( 'Options size in KB in autoload', 'Metric Help Text', 'prometheus-metrics-for-wp' ); - } + function get_help_text(): string + { + return _x('Options size in KB in autoload', 'Metric Help Text', 'prometheus-metrics-for-wp'); + } } diff --git a/includes/classes/metrics/Options_Autoloaded_Size_Metric.php b/includes/classes/metrics/Options_Autoloaded_Size_Metric.php index f4841b1..3ca9f6b 100644 --- a/includes/classes/metrics/Options_Autoloaded_Size_Metric.php +++ b/includes/classes/metrics/Options_Autoloaded_Size_Metric.php @@ -3,19 +3,22 @@ namespace WP_Prometheus_Metrics\metrics; -class Options_Autoloaded_Size_Metric extends Abstract_Metric { +class Options_Autoloaded_Size_Metric extends Abstract_Gauge_Metric +{ - public function __construct() { - parent::__construct( 'wp_options_autoload_size', 'gauge', 'autoload' ); - } + public function __construct() + { + parent::__construct('options_autoload_size'); + } - function get_metric_value() { - global $wpdb; + function get_metric_value() + { + global $wpdb; + return $wpdb->get_var("SELECT ROUND(SUM(LENGTH(option_value))/ 1024) FROM $wpdb->options WHERE `autoload` = 'yes'"); // phpcs:ignore WordPress.DB + } - return $wpdb->get_var( "SELECT ROUND(SUM(LENGTH(option_value))/ 1024) FROM $wpdb->options WHERE `autoload` = 'yes'" ); // phpcs:ignore WordPress.DB - } - - function get_help_text(): string { - return _x( 'Options in autoload', 'Metric Help Text', 'prometheus-metrics-for-wp' ); - } + function get_help_text(): string + { + return _x('Options in autoload', 'Metric Help Text', 'prometheus-metrics-for-wp'); + } } diff --git a/includes/classes/metrics/Pending_Updates_Metric.php b/includes/classes/metrics/Pending_Updates_Metric.php index 88c6d7b..f347798 100644 --- a/includes/classes/metrics/Pending_Updates_Metric.php +++ b/includes/classes/metrics/Pending_Updates_Metric.php @@ -3,22 +3,26 @@ namespace WP_Prometheus_Metrics\metrics; -class Pending_Updates_Metric extends Abstract_Metric { +class Pending_Updates_Metric extends Abstract_Gauge_Metric +{ - public function __construct() { - parent::__construct( 'wp_pending_updates', 'gauge', 'pending_updates' ); - } + public function __construct() + { + parent::__construct('pending_updates'); + } - function get_metric_value() { - $status = get_site_transient( 'update_plugins' ); + function get_metric_value() + { + $status = get_site_transient('update_plugins'); - $pluginUpdates = is_countable( $status->response ) ? count( $status->response ) : 0; - $translationUpdates = is_countable( $status->translations ) ? count( $status->translations ) : 0; + $pluginUpdates = is_countable($status->response) ? count($status->response) : 0; + $translationUpdates = is_countable($status->translations) ? count($status->translations) : 0; - return $pluginUpdates + $translationUpdates; - } + return $pluginUpdates + $translationUpdates; + } - function get_help_text(): string { - return _x( 'Pending updates in the WordPress website', 'Metric Help Text', 'prometheus-metrics-for-wp' ); - } + function get_help_text(): string + { + return _x('Pending updates in the WordPress website', 'Metric Help Text', 'prometheus-metrics-for-wp'); + } } diff --git a/includes/classes/metrics/Performance_Count_Posts_Metric.php b/includes/classes/metrics/Performance_Count_Posts_Metric.php index 3265a7f..b3678d8 100644 --- a/includes/classes/metrics/Performance_Count_Posts_Metric.php +++ b/includes/classes/metrics/Performance_Count_Posts_Metric.php @@ -3,22 +3,26 @@ namespace WP_Prometheus_Metrics\metrics; -class Performance_Count_Posts_Metric extends Abstract_Metric { +class Performance_Count_Posts_Metric extends Abstract_Gauge_Metric +{ - public function __construct() { - parent::__construct( 'perf_count_posts', ); - } + public function __construct() + { + parent::__construct('count_posts', 'performance'); + } - function get_metric_value() { - global $wpdb; - $start = hrtime( true ); - $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->posts}" ); - $end = hrtime( true ); + function get_metric_value() + { + global $wpdb; + $start = hrtime(true); + $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->posts}"); + $end = hrtime(true); - return $end - $start; - } + return $end - $start; + } - function get_help_text(): string { - return _x( 'Measure the time in ns for a count query on the posts table', 'Metric Help Text', 'prometheus-metrics-for-wp' ); - } + function get_help_text(): string + { + return _x('Measure the time in ns for a count query on the posts table', 'Metric Help Text', 'prometheus-metrics-for-wp'); + } } diff --git a/includes/classes/metrics/Performance_Write_File_To_WP_Upload_Dir_Metric.php b/includes/classes/metrics/Performance_Write_File_To_WP_Upload_Dir_Metric.php new file mode 100644 index 0000000..c08c6d7 --- /dev/null +++ b/includes/classes/metrics/Performance_Write_File_To_WP_Upload_Dir_Metric.php @@ -0,0 +1,35 @@ +is_enabled( $measure_all ) ) { - return; - } - - $transientKey = 'prometheus-metrics-for-wp/' . $this->metric_name; - $value = get_transient( $transientKey ); - - if ( $value ) { - echo $value; - - return; - } - - ob_start(); - - echo "# HELP $this->metric_name {$this->get_help_text()}\n"; - echo "# TYPE $this->metric_name $this->type\n"; - - $post_types = array_merge( [ - 'page', - 'post', - 'attachment' - ], get_post_types( [ 'publicly_queryable' => true ] ) ); - - $post_types = apply_filters( 'prometheus-metrics-for-wp/wp_post_types_total/type', $post_types ); - - foreach ( $post_types as $post_type ) { - $counts = wp_count_posts( $post_type ); - $time = time() * 1000; - foreach ( get_object_vars( $counts ) as $post_status => $count ) { - if ( get_post_status_object( $post_status ) && $count > 0 ) { - echo $this->metric_name . '{' . $this->get_metric_labels() . ',post_type="' . $post_type . '",status="' . $post_status . '"} ' . $count . " " . $time . "\n"; - } - } - } - - $value = ob_get_clean(); - $timeout = apply_filters( 'prometheus-metrics-for-wp/timeout', 3600, $this->metric_name ); // 1h by default - set_transient( $transientKey, $value, $timeout ); - - echo $value; - - - } - - function get_metric_value() { - return ''; // Do nothing. - } - - function get_help_text(): string { - return _x( 'Total number of content by type and status', 'Metric Help Text', 'prometheus-metrics-for-wp' ); - } +class Post_Types_Count_Metric extends Abstract_Metric +{ + + public function __construct() + { + parent::__construct('post_types_total'); + } + + public function print_metric($measure_all = false) + { + if (!$this->is_enabled($measure_all)) { + return; + } + + $transientKey = 'prometheus-metrics-for-wp/' . $this->metric_name; + $value = get_transient($transientKey); + + if ($value) { + echo $value; + + return; + } + + ob_start(); + + echo "# HELP $this->metric_name {$this->get_help_text()}\n"; + echo "# TYPE $this->metric_name $this->type\n"; + + $post_types = array_merge([ + 'page', + 'post', + 'attachment' + ], get_post_types(['publicly_queryable' => true])); + + $post_types = apply_filters('prometheus-metrics-for-wp/wp_post_types_total/type', $post_types); + + foreach ($post_types as $post_type) { + $counts = wp_count_posts($post_type); + $time = time() * 1000; + foreach (get_object_vars($counts) as $post_status => $count) { + if (get_post_status_object($post_status) && $count > 0) { + echo $this->metric_name . '{' . $this->get_metric_labels() . ',post_type="' . $post_type . '",status="' . $post_status . '"} ' . $count . " " . $time . "\n"; + } + } + } + + $value = ob_get_clean(); + $timeout = apply_filters('prometheus-metrics-for-wp/timeout', 3600, $this->metric_name); // 1h by default + set_transient($transientKey, $value, $timeout); + + echo $value; + + + } + + + function get_help_text(): string + { + return _x('Total number of content by type and status', 'Metric Help Text', 'prometheus-metrics-for-wp'); + } + + function internal_add_metric($registry) + { + $labels = $this->get_metric_labels(); + $labels['post_type'] = false; + $labels['post_status'] = false; + + $gauge = $registry->getOrRegisterGauge($this->namespace, $this->metric_name, $this->get_help_text(), array_keys($labels)); + + $post_types = array_merge([ + 'page', + 'post', + 'attachment' + ], get_post_types(['publicly_queryable' => true])); + + $post_types = apply_filters('prometheus-metrics-for-wp/wp_post_types_total/type', $post_types); + + foreach ($post_types as $post_type) { + $counts = wp_count_posts($post_type); + $time = time() * 1000; + foreach (get_object_vars($counts) as $post_status => $count) { + if (get_post_status_object($post_status) && $count > 0) { + $labels['post_type'] = $post_type; + $labels['post_status'] = $post_status; + $gauge->set($count, array_values($labels)); + } + } + } + } } diff --git a/includes/classes/metrics/Posts_Without_Content_Metric.php b/includes/classes/metrics/Posts_Without_Content_Metric.php index 262d7ad..5efc279 100644 --- a/includes/classes/metrics/Posts_Without_Content_Metric.php +++ b/includes/classes/metrics/Posts_Without_Content_Metric.php @@ -3,20 +3,24 @@ namespace WP_Prometheus_Metrics\metrics; -class Posts_Without_Content_Metric extends Abstract_Metric { +class Posts_Without_Content_Metric extends Abstract_Gauge_Metric +{ - public function __construct() { - parent::__construct( 'wp_posts_without_content', 'gauge', 'posts_without_content' ); - } + public function __construct() + { + parent::__construct('posts_without_content'); + } - function get_metric_value() { - global $wpdb; + function get_metric_value() + { + global $wpdb; - return $wpdb->get_var( "SELECT count(*) FROM " . $wpdb->posts . " WHERE post_content='' AND post_status!='draft' AND post_status!='trash' AND post_status!='auto-draft' AND (post_type='post' OR post_type='page')" ); // phpcs:ignore WordPress.DB - } + return $wpdb->get_var("SELECT count(*) FROM " . $wpdb->posts . " WHERE post_content='' AND post_status!='draft' AND post_status!='trash' AND post_status!='auto-draft' AND (post_type='post' OR post_type='page')"); // phpcs:ignore WordPress.DB + } - function get_help_text(): string { - return _x( 'Posts and Pages without content', 'Metric Help Text', 'prometheus-metrics-for-wp' ); - } + function get_help_text(): string + { + return _x('Posts and Pages without content', 'Metric Help Text', 'prometheus-metrics-for-wp'); + } } diff --git a/includes/classes/metrics/Posts_Without_Title_Metric.php b/includes/classes/metrics/Posts_Without_Title_Metric.php index 82bf66e..b1749ad 100644 --- a/includes/classes/metrics/Posts_Without_Title_Metric.php +++ b/includes/classes/metrics/Posts_Without_Title_Metric.php @@ -2,21 +2,23 @@ namespace WP_Prometheus_Metrics\metrics; -class Posts_Without_Title_Metric extends Abstract_Metric { - - - public function __construct() { - parent::__construct( 'wp_posts_without_title', 'gauge', 'posts_without_title' ); - } - - function get_metric_value() { - global $wpdb; - - return $wpdb->get_var( "SELECT count(*) FROM {$wpdb->posts} WHERE post_title='' AND post_status!='auto-draft' AND post_status!='draft' AND post_status!='trash' AND (post_type='post' OR post_type='page')" ); // phpcs:ignore WordPress.DB - } - - function get_help_text(): string { - return _x( 'Posts and Pages without title', 'Metric Help Text', 'prometheus-metrics-for-wp' ); - } +class Posts_Without_Title_Metric extends Abstract_Gauge_Metric +{ + public function __construct() + { + parent::__construct('posts_without_title'); + } + + function get_metric_value() + { + global $wpdb; + + return $wpdb->get_var("SELECT count(*) FROM {$wpdb->posts} WHERE post_title='' AND post_status!='auto-draft' AND post_status!='draft' AND post_status!='trash' AND (post_type='post' OR post_type='page')"); // phpcs:ignore WordPress.DB + } + + function get_help_text(): string + { + return _x('Posts and Pages without title', 'Metric Help Text', 'prometheus-metrics-for-wp'); + } } diff --git a/includes/classes/metrics/Transients_Autoloaded_Count_Metric.php b/includes/classes/metrics/Transients_Autoloaded_Count_Metric.php index f6b8fe4..2f934a4 100644 --- a/includes/classes/metrics/Transients_Autoloaded_Count_Metric.php +++ b/includes/classes/metrics/Transients_Autoloaded_Count_Metric.php @@ -3,19 +3,22 @@ namespace WP_Prometheus_Metrics\metrics; -class Transients_Autoloaded_Count_Metric extends Abstract_Metric { +class Transients_Autoloaded_Count_Metric extends Abstract_Gauge_Metric +{ - public function __construct() { - parent::__construct( 'wp_transient_autoload', 'gauge', 'transient' ); - } + public function __construct() + { + parent::__construct('transient_autoload'); + } - function get_metric_value() { - global $wpdb; + function get_metric_value() + { + global $wpdb; + return $wpdb->get_var("SELECT count(*) FROM $wpdb->options WHERE `autoload` = 'yes' AND `option_name` LIKE '%transient%'"); // phpcs:ignore WordPress.DB + } - return $wpdb->get_var( "SELECT count(*) FROM $wpdb->options WHERE `autoload` = 'yes' AND `option_name` LIKE '%transient%'" ); // phpcs:ignore WordPress.DB - } - - function get_help_text(): string { - return _x( 'DB Transient in autoload.', 'Metric Help Text', 'prometheus-metrics-for-wp' ); - } + function get_help_text(): string + { + return _x('DB Transient in autoload.', 'Metric Help Text', 'prometheus-metrics-for-wp'); + } } diff --git a/includes/classes/metrics/Users_Count_Metric.php b/includes/classes/metrics/Users_Count_Metric.php index 7897a02..37f03d3 100644 --- a/includes/classes/metrics/Users_Count_Metric.php +++ b/includes/classes/metrics/Users_Count_Metric.php @@ -3,17 +3,21 @@ namespace WP_Prometheus_Metrics\metrics; -class Users_Count_Metric extends Abstract_Metric { +class Users_Count_Metric extends Abstract_Gauge_Metric +{ - public function __construct() { - parent::__construct( 'wp_users_total', 'gauge', 'users' ); - } + public function __construct() + { + parent::__construct('users_total'); + } - function get_metric_value() { - return count_users()['total_users']; - } + function get_metric_value() + { + return count_users()['total_users']; + } - function get_help_text(): string { - return _x( 'Total number of users', 'Metric Help Text', 'prometheus-metrics-for-wp' ); - } + function get_help_text(): string + { + return _x('Total number of users', 'Metric Help Text', 'prometheus-metrics-for-wp'); + } } diff --git a/includes/classes/metrics/Users_Sessions_Metric.php b/includes/classes/metrics/Users_Sessions_Metric.php index 1a85950..6d75951 100644 --- a/includes/classes/metrics/Users_Sessions_Metric.php +++ b/includes/classes/metrics/Users_Sessions_Metric.php @@ -3,20 +3,23 @@ namespace WP_Prometheus_Metrics\metrics; -class Users_Sessions_Metric extends Abstract_Metric { +class Users_Sessions_Metric extends Abstract_Gauge_Metric +{ + public function __construct() + { + parent::__construct('user_sessions'); + } - public function __construct() { - parent::__construct( 'wp_user_sessions', 'gauge', 'user_sessions' ); - } - - function get_metric_value() { - global $wpdb; + function get_metric_value() + { + global $wpdb; // TODO is this still working? - return $wpdb->get_var( "SELECT count(*) FROM $wpdb->options WHERE `option_name` LIKE '_wp_session_%'" ); - } + return $wpdb->get_var("SELECT count(*) FROM $wpdb->options WHERE `option_name` LIKE '_wp_session_%'"); + } - function get_help_text(): string { - return _x( 'User sessions', 'Metric Help Text', 'prometheus-metrics-for-wp' ); - } + function get_help_text(): string + { + return _x('User sessions', 'Metric Help Text', 'prometheus-metrics-for-wp'); + } } diff --git a/prometheus-metrics-for-wp.php b/prometheus-metrics-for-wp.php index a669a46..2a12a64 100644 --- a/prometheus-metrics-for-wp.php +++ b/prometheus-metrics-for-wp.php @@ -3,7 +3,7 @@ * Plugin Name: Prometheus Metrics in WordPress * Plugin URI: https://github.com/codeatcode/prometheus-metrics-for-wp/ * Description: Add a custom endpoint for Prometheus - * Version: 2.0 + * Version: 3.0.1 * Requires at least: 5.6 * Requires PHP: 7.3 * Text Domain: prometheus-metrics-for-wp @@ -15,43 +15,24 @@ */ // https://developer.wordpress.org/reference/hooks/plugin_action_links_plugin_file/ +use Prometheus\CollectorRegistry; +use Prometheus\RenderTextFormat; +use Prometheus\Storage\InMemory; use WP_Prometheus_Metrics\Default_Metrics_Loader; -use WP_Prometheus_Metrics\metrics\Abstract_Metric; use WP_Prometheus_Metrics\Site_Health_Extension; -define( 'PROMETHEUS_PLUGIN_FILE', plugin_basename( __FILE__ ) ); +define('PROMETHEUS_PLUGIN_FILE', plugin_basename(__FILE__)); include "vendor/autoload.php"; new Site_Health_Extension(); new Default_Metrics_Loader(); -add_filter( 'rest_pre_serve_request', 'prometheus_serve_request', 10, 4 ); -add_action( 'rest_api_init', 'prometheus_register_route' ); -add_action( 'wp_ajax_prometheus_metrics_get_url', 'prometheus_get_url' ); +add_filter('rest_pre_serve_request', 'prometheus_serve_request', 10, 4); +add_action('rest_api_init', 'prometheus_register_route'); +add_action('wp_ajax_prometheus_metrics_get_url', 'prometheus_get_url'); -add_filter( 'prometheus-metrics-for-wp/is_access_allowed', 'prometheus_is_access_allowed', 10, 2 ); - -/** - * @deprecated - * @var boolean $measure_all True, if the "all" parameter is send - */ -function prometheus_get_metrics( bool $measure_all ): string { - - include 'includes/_legacy.prometheus_custom_metrics.php'; - /** - * Filter database metrics result - * - * @var string $result The database metrics result - * @var boolean $measure_all True, if the "all" parameter is send - */ - $result = apply_filters( 'prometheus_custom_metrics', '', $measure_all ); - if ( ! empty( $result ) ) { - _deprecated_hook( 'prometheus_custom_metrics', '2.0', 'prometheus_print_metrics', 'Use the new action instead' ); - } - - return $result; -} +add_filter('prometheus-metrics-for-wp/is_access_allowed', 'prometheus_is_access_allowed', 10, 2); /** * @param bool $for_rest Prints the URL and "dies" if true, else returns the url @@ -59,58 +40,61 @@ function prometheus_get_metrics( bool $measure_all ): string { * * @return string Url for the endpoint */ -function prometheus_get_url( bool $for_rest = true, bool $generate_if_requested = true ): string { - if ( ! current_user_can( 'administrator' ) ) { - echo prometheus_empty_func(); - } +function prometheus_get_url(bool $for_rest = true, bool $generate_if_requested = true): string +{ + if (!current_user_can('administrator')) { + echo prometheus_empty_func(); + } - $prometheusKey = defined( 'PROMETHEUS_KEY' ) ? PROMETHEUS_KEY : ''; + $prometheusKey = defined('PROMETHEUS_KEY') ? PROMETHEUS_KEY : ''; - if ( $generate_if_requested && filter_input( INPUT_POST, 'generate_key', FILTER_VALIDATE_BOOL ) ) { - $prometheusKey = wp_generate_uuid4(); + if ($generate_if_requested && filter_input(INPUT_POST, 'generate_key', FILTER_VALIDATE_BOOL)) { + $prometheusKey = wp_generate_uuid4(); - $prometheusKeys = get_option( 'prometheus-metrics-for-wp-keys', [] ); - $prometheusKeys[ date( 'Y-m-d H:i:s' ) . ' User: ' . wp_get_current_user()->user_login ] = md5( $prometheusKey ); - update_option( 'prometheus-metrics-for-wp-keys', $prometheusKeys, false ); - } + $prometheusKeys = get_option('prometheus-metrics-for-wp-keys', []); + $prometheusKeys[date('Y-m-d H:i:s') . ' User: ' . wp_get_current_user()->user_login] = md5($prometheusKey); + update_option('prometheus-metrics-for-wp-keys', $prometheusKeys, false); + } - $url = add_query_arg( [ - 'all' => 'yes', - 'prometheus' => $prometheusKey, - ], get_rest_url( null, '/metrics' ) ); + $url = add_query_arg([ + 'all' => 'yes', + 'prometheus' => $prometheusKey, + ], get_rest_url(null, '/metrics')); - if ( $for_rest ) { - echo $url; - wp_die(); - } + if ($for_rest) { + echo $url; + wp_die(); + } - return $url; + return $url; } /** * @param $default bool * @param $request WP_REST_Request */ -function prometheus_is_access_allowed( bool $default, WP_REST_Request $request ): bool { - if ( $default ) { - return true; - } +function prometheus_is_access_allowed(bool $default, WP_REST_Request $request): bool +{ + if ($default) { + return true; + } - $prometheusKey = filter_input( INPUT_GET, 'prometheus', FILTER_SANITIZE_STRING ); + $prometheusKey = filter_input(INPUT_GET, 'prometheus', FILTER_SANITIZE_STRING); - if ( defined( 'PROMETHEUS_KEY' ) && $prometheusKey === PROMETHEUS_KEY ) { - return true; - } + if (defined('PROMETHEUS_KEY') && $prometheusKey === PROMETHEUS_KEY) { + return true; + } - if ( in_array( md5( $prometheusKey ), get_option( 'prometheus-metrics-for-wp-keys', [] ) ) ) { - return true; - } + if (in_array(md5($prometheusKey), get_option('prometheus-metrics-for-wp-keys', []))) { + return true; + } - return false; + return false; } -function prometheus_empty_func(): string { - return '{ "error": "You cannot access to that page" }'; +function prometheus_empty_func(): string +{ + return '{ "error": "You cannot access to that page" }'; } /** @@ -121,38 +105,51 @@ function prometheus_empty_func(): string { * * @return bool True, if the request was processed */ -function prometheus_serve_request( bool $served, WP_HTTP_Response $result, WP_REST_Request $request, WP_REST_Server $server ): bool { - if ( $request->get_route() !== '/metrics' ) { - return $served; - } - - if ( ! apply_filters( 'prometheus-metrics-for-wp/is_access_allowed', false, $request ) ) { - echo prometheus_empty_func(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - - return true; - } - $measure_all = filter_input( INPUT_GET, 'all', FILTER_SANITIZE_STRING ) === 'yes'; - - header( 'Content-Type: text/plain; charset=' . get_option( 'blog_charset' ) ); - $legacy_metrics = prometheus_get_metrics( $measure_all ); - echo $legacy_metrics; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped - $metrics = apply_filters( 'prometheus_get_metrics', [] ); - /** @var $metric Abstract_Metric */ - foreach ( $metrics as $metric ) { - $metric->print_metric( $measure_all ); - } - - return true; +function prometheus_serve_request(bool $served, WP_HTTP_Response $result, WP_REST_Request $request, WP_REST_Server $server): bool +{ + if ($request->get_route() !== '/metrics') { + return $served; + } + + if (!apply_filters('prometheus-metrics-for-wp/is_access_allowed', false, $request)) { + echo prometheus_empty_func(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + return true; + } + $measure_all = filter_input(INPUT_GET, 'all', FILTER_SANITIZE_STRING) === 'yes'; + + header('Content-type: ' . RenderTextFormat::MIME_TYPE); + + $metrics = get_transient('prometheus-metrics-for-wp-cached-metrics'); + if ($metrics && (!defined('PROMETHEUS_METRICS_FOR_WP_DISABLE_CACHE') || !PROMETHEUS_METRICS_FOR_WP_DISABLE_CACHE)) { + echo $metrics; + return true; + } + + /** @var CollectorRegistry $registry */ + $registry = apply_filters('prometheus-metrics-for-wp/get_registry', new CollectorRegistry(new InMemory())); + + $metrics = apply_filters('prometheus-metrics-for-wp/get_metrics', []); + foreach ($metrics as $metric) { + $metric->add_metric($registry, $measure_all); + } + $renderer = new RenderTextFormat(); + $metrics = $renderer->render($registry->getMetricFamilySamples()); + + set_transient('prometheus-metrics-for-wp-cached-metrics', $metrics, apply_filters('prometheus-metrics-for-wp/cache_timeout', 3600)); + + echo $metrics; + return true; } -function prometheus_register_route() { - register_rest_route( - 'metrics', - '/', - array( - 'methods' => 'GET', - 'callback' => 'prometheus_empty_func', - 'permission_callback' => '__return_true', - ) - ); +function prometheus_register_route() +{ + register_rest_route( + 'metrics', + '/', + array( + 'methods' => 'GET', + 'callback' => 'prometheus_empty_func', + 'permission_callback' => '__return_true', + ) + ); } diff --git a/readme.md b/readme.md index 3ebf7c7..d4cbf9d 100644 --- a/readme.md +++ b/readme.md @@ -4,7 +4,7 @@ A WordPress plugin, based on [https://github.com/CodeAtCode/WPDB-Status](https://github.com/CodeAtCode/WPDB-Status). -Grafana dashboard avalaible on [official website](https://grafana.com/grafana/dashboards/11178). +Grafana dashboard avalaible on [official website](https://grafana.com/grafana/dashboards/11178), the `wp_info` data JSON for Grafana it's available [here](https://github.com/CodeAtCode/Prometheus-Metrics-in-WordPress/pull/16#issuecomment-1464940620). ![](https://grafana.com/api/dashboards/11178/images/7117/image) @@ -58,6 +58,19 @@ See the included page at `Tools` -> `Site Health` -> `Prometheus` with specific ## Changelog +### 3.0.x ### + +* Use Prometheus Client PHP lib to make sure, the format is correct (https://github.com/promphp/prometheus_client_php) +* Removed "legacy" metrics +* Fixed warnings + +### 2.1 ### + +* Seperated host and schema (and port) +* Added metric for writing temporary file into uploads folder +* Disabled legacy metrics by default (to avoid warnings in the logs) + * Enable it, by adding `define('PROMETHEUS_INCLUDE_LEGACY_METRICS', true);` to `wp-config.php` + ### 2.0 ### * **Major rewrite, which may break your current metrics!**