2026-02-01 15:31:21 +01:00
< ? php
/**
* Metrics collector class .
*
* @ package WP_Prometheus
*/
namespace Magdev\WpPrometheus\Metrics ;
use Prometheus\CollectorRegistry ;
use Prometheus\Storage\InMemory ;
use Prometheus\RenderTextFormat ;
2026-02-02 15:27:16 +01:00
use Magdev\WpPrometheus\Metrics\CustomMetricBuilder ;
2026-02-01 15:31:21 +01:00
// Prevent direct file access.
if ( ! defined ( 'ABSPATH' ) ) {
exit ;
}
/**
* Collector class .
*
* Collects and manages Prometheus metrics .
*/
class Collector {
/**
* Prometheus collector registry .
*
* @ var CollectorRegistry
*/
private CollectorRegistry $registry ;
/**
* Metric namespace .
*
* @ var string
*/
private string $namespace = 'wordpress' ;
/**
* Constructor .
*/
public function __construct () {
$this -> registry = new CollectorRegistry ( new InMemory () );
}
/**
* Get the collector registry .
*
* @ return CollectorRegistry
*/
public function get_registry () : CollectorRegistry {
return $this -> registry ;
}
/**
* Get the metric namespace .
*
* @ return string
*/
public function get_namespace () : string {
return $this -> namespace ;
}
/**
* Collect all enabled metrics .
*
* @ return void
*/
public function collect () : void {
$enabled_metrics = get_option ( 'wp_prometheus_enabled_metrics' , array () );
// Always collect WordPress info.
if ( in_array ( 'wordpress_info' , $enabled_metrics , true ) ) {
$this -> collect_wordpress_info ();
}
// Collect user metrics.
if ( in_array ( 'wordpress_users_total' , $enabled_metrics , true ) ) {
$this -> collect_users_total ();
}
// Collect posts metrics.
if ( in_array ( 'wordpress_posts_total' , $enabled_metrics , true ) ) {
$this -> collect_posts_total ();
}
// Collect comments metrics.
if ( in_array ( 'wordpress_comments_total' , $enabled_metrics , true ) ) {
$this -> collect_comments_total ();
}
// Collect plugins metrics.
if ( in_array ( 'wordpress_plugins_total' , $enabled_metrics , true ) ) {
$this -> collect_plugins_total ();
}
2026-02-02 14:41:09 +01:00
// Collect cron metrics.
if ( in_array ( 'wordpress_cron_events_total' , $enabled_metrics , true ) ) {
$this -> collect_cron_metrics ();
}
// Collect transient metrics.
if ( in_array ( 'wordpress_transients_total' , $enabled_metrics , true ) ) {
$this -> collect_transient_metrics ();
}
// Collect WooCommerce metrics (if WooCommerce is active).
if ( $this -> is_woocommerce_active () ) {
$this -> collect_woocommerce_metrics ( $enabled_metrics );
}
2026-02-02 14:24:05 +01:00
// Collect runtime metrics (HTTP requests, DB queries).
$this -> collect_runtime_metrics ( $enabled_metrics );
2026-02-02 15:27:16 +01:00
// Collect custom user-defined metrics.
$custom_builder = new CustomMetricBuilder ();
$custom_builder -> register_with_collector ( $this );
2026-02-01 15:31:21 +01:00
/**
* Fires after default metrics are collected .
*
* @ param Collector $collector The metrics collector instance .
*/
do_action ( 'wp_prometheus_collect_metrics' , $this );
}
/**
* Render metrics in Prometheus text format .
*
* @ return string
*/
public function render () : string {
$this -> collect ();
$renderer = new RenderTextFormat ();
return $renderer -> render ( $this -> registry -> getMetricFamilySamples () );
}
/**
* Collect WordPress info metric .
*
* @ return void
*/
private function collect_wordpress_info () : void {
$gauge = $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
'info' ,
'WordPress installation information' ,
array ( 'version' , 'php_version' , 'multisite' )
);
$gauge -> set (
1 ,
array (
get_bloginfo ( 'version' ),
PHP_VERSION ,
is_multisite () ? 'yes' : 'no' ,
)
);
}
/**
* Collect total users metric .
*
* @ return void
*/
private function collect_users_total () : void {
$gauge = $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
'users_total' ,
'Total number of WordPress users' ,
array ( 'role' )
);
$user_count = count_users ();
foreach ( $user_count [ 'avail_roles' ] as $role => $count ) {
$gauge -> set ( $count , array ( $role ) );
}
}
/**
* Collect total posts metric .
*
* @ return void
*/
private function collect_posts_total () : void {
$gauge = $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
'posts_total' ,
'Total number of posts by type and status' ,
array ( 'post_type' , 'status' )
);
$post_types = get_post_types ( array ( 'public' => true ) );
foreach ( $post_types as $post_type ) {
$counts = wp_count_posts ( $post_type );
foreach ( get_object_vars ( $counts ) as $status => $count ) {
if ( $count > 0 ) {
$gauge -> set ( ( int ) $count , array ( $post_type , $status ) );
}
}
}
}
/**
* Collect total comments metric .
*
* @ return void
*/
private function collect_comments_total () : void {
$gauge = $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
'comments_total' ,
'Total number of comments by status' ,
array ( 'status' )
);
$comments = wp_count_comments ();
$statuses = array (
'approved' => $comments -> approved ,
'moderated' => $comments -> moderated ,
'spam' => $comments -> spam ,
'trash' => $comments -> trash ,
'total_comments' => $comments -> total_comments ,
);
foreach ( $statuses as $status => $count ) {
$gauge -> set ( ( int ) $count , array ( $status ) );
}
}
/**
* Collect total plugins metric .
*
* @ return void
*/
private function collect_plugins_total () : void {
if ( ! function_exists ( 'get_plugins' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php' ;
}
$gauge = $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
'plugins_total' ,
'Total number of plugins by status' ,
array ( 'status' )
);
$all_plugins = get_plugins ();
$active_plugins = get_option ( 'active_plugins' , array () );
$gauge -> set ( count ( $all_plugins ), array ( 'installed' ) );
$gauge -> set ( count ( $active_plugins ), array ( 'active' ) );
$gauge -> set ( count ( $all_plugins ) - count ( $active_plugins ), array ( 'inactive' ) );
}
2026-02-02 14:41:09 +01:00
/**
* Collect cron metrics .
*
* @ return void
*/
private function collect_cron_metrics () : void {
$cron_array = _get_cron_array ();
if ( ! is_array ( $cron_array ) ) {
return ;
}
// Events total gauge.
$events_gauge = $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
'cron_events_total' ,
'Total number of scheduled cron events' ,
array ( 'hook' )
);
// Count events by hook.
$hook_counts = array ();
$total_events = 0 ;
$overdue_count = 0 ;
$current_time = time ();
$next_run = PHP_INT_MAX ;
foreach ( $cron_array as $timestamp => $cron ) {
if ( $timestamp < $next_run ) {
$next_run = $timestamp ;
}
foreach ( $cron as $hook => $events ) {
$event_count = count ( $events );
$total_events += $event_count ;
if ( ! isset ( $hook_counts [ $hook ] ) ) {
$hook_counts [ $hook ] = 0 ;
}
$hook_counts [ $hook ] += $event_count ;
// Check if overdue.
if ( $timestamp < $current_time ) {
$overdue_count += $event_count ;
}
}
}
// Set events by hook (limit to top 20 to avoid cardinality explosion).
arsort ( $hook_counts );
$hook_counts = array_slice ( $hook_counts , 0 , 20 , true );
foreach ( $hook_counts as $hook => $count ) {
$events_gauge -> set ( $count , array ( $hook ) );
}
// Overdue events gauge.
$overdue_gauge = $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
'cron_overdue_total' ,
'Number of overdue cron events' ,
array ()
);
$overdue_gauge -> set ( $overdue_count , array () );
// Next run timestamp.
$next_run_gauge = $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
'cron_next_run_timestamp' ,
'Unix timestamp of next scheduled cron event' ,
array ()
);
if ( $next_run !== PHP_INT_MAX ) {
$next_run_gauge -> set ( $next_run , array () );
}
}
/**
* Collect transient metrics .
*
* @ return void
*/
private function collect_transient_metrics () : void {
global $wpdb ;
// Count all transients.
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
$transient_count = $wpdb -> get_var (
" SELECT COUNT(*) FROM { $wpdb -> options } WHERE option_name LIKE '_transient_%' AND option_name NOT LIKE '_transient_timeout_%' "
);
// Count transients with expiration.
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
$expiring_count = $wpdb -> get_var (
" SELECT COUNT(*) FROM { $wpdb -> options } WHERE option_name LIKE '_transient_timeout_%' "
);
// Count expired transients.
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
$expired_count = $wpdb -> get_var (
$wpdb -> prepare (
" SELECT COUNT(*) FROM { $wpdb -> options } WHERE option_name LIKE '_transient_timeout_%%' AND option_value < %d " ,
time ()
)
);
// Transients total gauge.
$transients_gauge = $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
'transients_total' ,
'Total number of transients in database' ,
array ( 'type' )
);
$transients_gauge -> set ( ( int ) $transient_count , array ( 'total' ) );
$transients_gauge -> set ( ( int ) $expiring_count , array ( 'with_expiration' ) );
$transients_gauge -> set ( ( int ) $transient_count - ( int ) $expiring_count , array ( 'persistent' ) );
$transients_gauge -> set ( ( int ) $expired_count , array ( 'expired' ) );
// Site transients (for multisite).
if ( is_multisite () ) {
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
$site_transient_count = $wpdb -> get_var (
" SELECT COUNT(*) FROM { $wpdb -> sitemeta } WHERE meta_key LIKE '_site_transient_%' AND meta_key NOT LIKE '_site_transient_timeout_%' "
);
$transients_gauge -> set ( ( int ) $site_transient_count , array ( 'site_transients' ) );
}
}
/**
* Check if WooCommerce is active .
*
* @ return bool
*/
private function is_woocommerce_active () : bool {
return class_exists ( 'WooCommerce' );
}
/**
* Collect WooCommerce metrics .
*
* @ param array $enabled_metrics List of enabled metrics .
* @ return void
*/
private function collect_woocommerce_metrics ( array $enabled_metrics ) : void {
// Products total.
if ( in_array ( 'wordpress_woocommerce_products_total' , $enabled_metrics , true ) ) {
$this -> collect_woocommerce_products ();
}
// Orders total.
if ( in_array ( 'wordpress_woocommerce_orders_total' , $enabled_metrics , true ) ) {
$this -> collect_woocommerce_orders ();
}
// Revenue.
if ( in_array ( 'wordpress_woocommerce_revenue_total' , $enabled_metrics , true ) ) {
$this -> collect_woocommerce_revenue ();
}
// Customers.
if ( in_array ( 'wordpress_woocommerce_customers_total' , $enabled_metrics , true ) ) {
$this -> collect_woocommerce_customers ();
}
}
/**
* Collect WooCommerce products metrics .
*
* @ return void
*/
private function collect_woocommerce_products () : void {
$gauge = $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
'woocommerce_products_total' ,
'Total number of WooCommerce products by status and type' ,
array ( 'status' , 'type' )
);
// Get product counts by status.
$product_counts = wp_count_posts ( 'product' );
$product_types = wc_get_product_types ();
foreach ( get_object_vars ( $product_counts ) as $status => $count ) {
if ( ( int ) $count > 0 ) {
$gauge -> set ( ( int ) $count , array ( $status , 'all' ) );
}
}
// Count by product type (for published products only).
foreach ( array_keys ( $product_types ) as $type ) {
$args = array (
'status' => 'publish' ,
'type' => $type ,
'limit' => - 1 ,
'return' => 'ids' ,
);
$products = wc_get_products ( $args );
$gauge -> set ( count ( $products ), array ( 'publish' , $type ) );
}
}
/**
* Collect WooCommerce orders metrics .
*
* @ return void
*/
private function collect_woocommerce_orders () : void {
$gauge = $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
'woocommerce_orders_total' ,
'Total number of WooCommerce orders by status' ,
array ( 'status' )
);
2026-02-02 14:57:43 +01:00
// Get all registered order statuses and count each.
$statuses = wc_get_order_statuses ();
foreach ( array_keys ( $statuses ) as $status ) {
// Remove 'wc-' prefix for the label.
$status_label = str_replace ( 'wc-' , '' , $status );
$count = wc_orders_count ( $status );
$gauge -> set ( ( int ) $count , array ( $status_label ) );
2026-02-02 14:41:09 +01:00
}
}
/**
* Collect WooCommerce revenue metrics .
*
* @ return void
*/
private function collect_woocommerce_revenue () : void {
global $wpdb ;
$gauge = $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
'woocommerce_revenue_total' ,
'Total WooCommerce revenue' ,
array ( 'period' , 'currency' )
);
$currency = get_woocommerce_currency ();
// Check if HPOS (High-Performance Order Storage) is enabled.
$hpos_enabled = class_exists ( '\Automattic\WooCommerce\Utilities\OrderUtil' )
&& \Automattic\WooCommerce\Utilities\OrderUtil :: custom_orders_table_usage_is_enabled ();
if ( $hpos_enabled ) {
$orders_table = $wpdb -> prefix . 'wc_orders' ;
// Total revenue (all time) - completed and processing orders.
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
$total_revenue = $wpdb -> get_var (
" SELECT SUM(total_amount) FROM { $orders_table } WHERE status IN ('wc-completed', 'wc-processing') "
);
// Today's revenue.
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
$today_revenue = $wpdb -> get_var (
$wpdb -> prepare (
" SELECT SUM(total_amount) FROM { $orders_table } WHERE status IN ('wc-completed', 'wc-processing') AND DATE(date_created_gmt) = %s " ,
gmdate ( 'Y-m-d' )
)
);
// This month's revenue.
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
$month_revenue = $wpdb -> get_var (
$wpdb -> prepare (
" SELECT SUM(total_amount) FROM { $orders_table } WHERE status IN ('wc-completed', 'wc-processing') AND YEAR(date_created_gmt) = %d AND MONTH(date_created_gmt) = %d " ,
gmdate ( 'Y' ),
gmdate ( 'm' )
)
);
} else {
// Legacy post-based orders.
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
$total_revenue = $wpdb -> get_var (
" SELECT SUM(meta_value) FROM { $wpdb -> postmeta } pm
JOIN { $wpdb -> posts } p ON p . ID = pm . post_id
WHERE pm . meta_key = '_order_total'
AND p . post_type = 'shop_order'
AND p . post_status IN ( 'wc-completed' , 'wc-processing' ) "
);
// Today's revenue.
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
$today_revenue = $wpdb -> get_var (
$wpdb -> prepare (
" SELECT SUM(meta_value) FROM { $wpdb -> postmeta } pm
JOIN { $wpdb -> posts } p ON p . ID = pm . post_id
WHERE pm . meta_key = '_order_total'
AND p . post_type = 'shop_order'
AND p . post_status IN ( 'wc-completed' , 'wc-processing' )
AND DATE ( p . post_date_gmt ) = % s " ,
gmdate ( 'Y-m-d' )
)
);
// This month's revenue.
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
$month_revenue = $wpdb -> get_var (
$wpdb -> prepare (
" SELECT SUM(meta_value) FROM { $wpdb -> postmeta } pm
JOIN { $wpdb -> posts } p ON p . ID = pm . post_id
WHERE pm . meta_key = '_order_total'
AND p . post_type = 'shop_order'
AND p . post_status IN ( 'wc-completed' , 'wc-processing' )
AND YEAR ( p . post_date_gmt ) = % d
AND MONTH ( p . post_date_gmt ) = % d " ,
gmdate ( 'Y' ),
gmdate ( 'm' )
)
);
}
$gauge -> set ( ( float ) ( $total_revenue ? ? 0 ), array ( 'all_time' , $currency ) );
$gauge -> set ( ( float ) ( $today_revenue ? ? 0 ), array ( 'today' , $currency ) );
$gauge -> set ( ( float ) ( $month_revenue ? ? 0 ), array ( 'month' , $currency ) );
}
/**
* Collect WooCommerce customers metrics .
*
* @ return void
*/
private function collect_woocommerce_customers () : void {
$gauge = $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
'woocommerce_customers_total' ,
'Total number of WooCommerce customers' ,
array ( 'type' )
);
// Count users with customer role.
$customer_count = count_users ();
$customers = $customer_count [ 'avail_roles' ][ 'customer' ] ? ? 0 ;
$gauge -> set ( $customers , array ( 'registered' ) );
// Count guest orders (orders without user_id).
global $wpdb ;
// Check if HPOS is enabled.
$hpos_enabled = class_exists ( '\Automattic\WooCommerce\Utilities\OrderUtil' )
&& \Automattic\WooCommerce\Utilities\OrderUtil :: custom_orders_table_usage_is_enabled ();
if ( $hpos_enabled ) {
$orders_table = $wpdb -> prefix . 'wc_orders' ;
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
$guest_orders = $wpdb -> get_var (
" SELECT COUNT(DISTINCT billing_email) FROM { $orders_table } WHERE customer_id = 0 AND billing_email != '' "
);
} else {
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
$guest_orders = $wpdb -> get_var (
" SELECT COUNT(DISTINCT pm.meta_value) FROM { $wpdb -> postmeta } pm
JOIN { $wpdb -> posts } p ON p . ID = pm . post_id
LEFT JOIN { $wpdb -> postmeta } pm2 ON pm2 . post_id = p . ID AND pm2 . meta_key = '_customer_user'
WHERE pm . meta_key = '_billing_email'
AND p . post_type = 'shop_order'
AND ( pm2 . meta_value = '0' OR pm2 . meta_value IS NULL ) "
);
}
$gauge -> set ( ( int ) $guest_orders , array ( 'guest' ) );
}
2026-02-02 14:24:05 +01:00
/**
* Collect runtime metrics from stored data .
*
* @ param array $enabled_metrics List of enabled metrics .
* @ return void
*/
private function collect_runtime_metrics ( array $enabled_metrics ) : void {
$runtime_collector = RuntimeCollector :: get_instance ();
$stored_metrics = $runtime_collector -> get_stored_metrics ();
// HTTP requests total counter.
if ( in_array ( 'wordpress_http_requests_total' , $enabled_metrics , true ) && ! empty ( $stored_metrics [ 'counters' ] ) ) {
foreach ( $stored_metrics [ 'counters' ] as $counter_data ) {
if ( 'http_requests_total' !== $counter_data [ 'name' ] ) {
continue ;
}
$counter = $this -> registry -> getOrRegisterCounter (
$this -> namespace ,
'http_requests_total' ,
'Total number of HTTP requests' ,
array ( 'method' , 'status' , 'endpoint' )
);
$counter -> incBy (
( int ) $counter_data [ 'value' ],
array (
$counter_data [ 'labels' ][ 'method' ] ? ? 'GET' ,
$counter_data [ 'labels' ][ 'status' ] ? ? '200' ,
$counter_data [ 'labels' ][ 'endpoint' ] ? ? 'unknown' ,
)
);
}
}
// HTTP request duration histogram.
if ( in_array ( 'wordpress_http_request_duration_seconds' , $enabled_metrics , true ) && ! empty ( $stored_metrics [ 'histograms' ] ) ) {
foreach ( $stored_metrics [ 'histograms' ] as $histogram_data ) {
if ( 'http_request_duration_seconds' !== $histogram_data [ 'name' ] ) {
continue ;
}
// For histograms, we expose as a gauge with pre-aggregated bucket counts.
// This is a workaround since we can't directly populate histogram buckets.
$this -> expose_histogram_as_gauges (
'http_request_duration_seconds' ,
'HTTP request duration in seconds' ,
$histogram_data ,
array ( 'method' , 'endpoint' )
);
}
}
// Database queries total counter.
if ( in_array ( 'wordpress_db_queries_total' , $enabled_metrics , true ) && ! empty ( $stored_metrics [ 'counters' ] ) ) {
foreach ( $stored_metrics [ 'counters' ] as $counter_data ) {
if ( 'db_queries_total' !== $counter_data [ 'name' ] ) {
continue ;
}
$counter = $this -> registry -> getOrRegisterCounter (
$this -> namespace ,
'db_queries_total' ,
'Total number of database queries' ,
array ( 'endpoint' )
);
$counter -> incBy (
( int ) $counter_data [ 'value' ],
array (
$counter_data [ 'labels' ][ 'endpoint' ] ? ? 'unknown' ,
)
);
}
}
// Database query duration histogram (if SAVEQUERIES is enabled).
if ( in_array ( 'wordpress_db_queries_total' , $enabled_metrics , true ) && ! empty ( $stored_metrics [ 'histograms' ] ) ) {
foreach ( $stored_metrics [ 'histograms' ] as $histogram_data ) {
if ( 'db_query_duration_seconds' !== $histogram_data [ 'name' ] ) {
continue ;
}
$this -> expose_histogram_as_gauges (
'db_query_duration_seconds' ,
'Database query duration in seconds' ,
$histogram_data ,
array ( 'endpoint' )
);
}
}
}
/**
* Expose pre - aggregated histogram data as gauge metrics .
*
* Since we store histogram data externally , we expose it using gauges
* that follow Prometheus histogram naming conventions .
*
* @ param string $name Metric name .
* @ param string $help Metric description .
* @ param array $histogram_data Stored histogram data .
* @ param array $label_names Label names .
* @ return void
*/
private function expose_histogram_as_gauges ( string $name , string $help , array $histogram_data , array $label_names ) : void {
$label_values = array ();
foreach ( $label_names as $label_name ) {
$label_values [] = $histogram_data [ 'labels' ][ $label_name ] ? ? 'unknown' ;
}
// Expose bucket counts.
$bucket_gauge = $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
$name . '_bucket' ,
$help . ' (bucket)' ,
array_merge ( $label_names , array ( 'le' ) )
);
$cumulative_count = 0 ;
foreach ( $histogram_data [ 'buckets' ] as $le => $count ) {
$cumulative_count += $count ;
$bucket_gauge -> set (
$cumulative_count ,
array_merge ( $label_values , array ( $le ) )
);
}
// Expose sum.
$sum_gauge = $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
$name . '_sum' ,
$help . ' (sum)' ,
$label_names
);
$sum_gauge -> set ( $histogram_data [ 'sum' ], $label_values );
// Expose count.
$count_gauge = $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
$name . '_count' ,
$help . ' (count)' ,
$label_names
);
$count_gauge -> set ( $histogram_data [ 'count' ], $label_values );
}
2026-02-01 15:31:21 +01:00
/**
* Register a custom gauge metric .
*
* @ param string $name Metric name .
* @ param string $help Metric description .
* @ param array $labels Label names .
* @ return \Prometheus\Gauge
*/
public function register_gauge ( string $name , string $help , array $labels = array () ) : \Prometheus\Gauge {
return $this -> registry -> getOrRegisterGauge (
$this -> namespace ,
$name ,
$help ,
$labels
);
}
/**
* Register a custom counter metric .
*
* @ param string $name Metric name .
* @ param string $help Metric description .
* @ param array $labels Label names .
* @ return \Prometheus\Counter
*/
public function register_counter ( string $name , string $help , array $labels = array () ) : \Prometheus\Counter {
return $this -> registry -> getOrRegisterCounter (
$this -> namespace ,
$name ,
$help ,
$labels
);
}
/**
* Register a custom histogram metric .
*
* @ param string $name Metric name .
* @ param string $help Metric description .
* @ param array $labels Label names .
* @ param array | null $buckets Histogram buckets .
* @ return \Prometheus\Histogram
*/
public function register_histogram ( string $name , string $help , array $labels = array (), ? array $buckets = null ) : \Prometheus\Histogram {
return $this -> registry -> getOrRegisterHistogram (
$this -> namespace ,
$name ,
$help ,
$labels ,
$buckets
);
}
}