From a67ffa84e8bee9a56cb0bc25755b28ab22258d40 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Wed, 24 Dec 2025 12:40:10 +0800 Subject: [PATCH 1/6] feat(sentry): add separate configuration options for pool and queue metrics - Add enable_pool_metrics and enable_queue_metrics config options - Add isPoolMetricsEnabled() and isQueueMetricsEnabled() methods to Feature class - Update PoolWatcher and QueueWatcher to use their respective enable flags - Move MetricFactoryReady event dispatch earlier in OnCoroutineServerStart for proper initialization - Remove Timer::STOP callback logic from timer tick handlers (no longer needed) - Refactor timer tick callback formatting for consistency --- src/sentry/publish/sentry.php | 2 + src/sentry/src/Feature.php | 18 +++++ .../src/Metrics/Listener/OnBeforeHandle.php | 55 ++++++++------ .../Listener/OnCoroutineServerStart.php | 53 +++++++------ .../Metrics/Listener/OnMetricFactoryReady.php | 69 +++++++++-------- .../src/Metrics/Listener/OnWorkerStart.php | 75 ++++++++++--------- .../src/Metrics/Listener/PoolWatcher.php | 67 ++++++++--------- .../src/Metrics/Listener/QueueWatcher.php | 65 ++++++++-------- 8 files changed, 211 insertions(+), 193 deletions(-) diff --git a/src/sentry/publish/sentry.php b/src/sentry/publish/sentry.php index d58338eea..39593fd29 100644 --- a/src/sentry/publish/sentry.php +++ b/src/sentry/publish/sentry.php @@ -65,6 +65,8 @@ 'enable_default_metrics' => env('SENTRY_ENABLE_DEFAULT_METRICS', true), 'enable_command_metrics' => env('SENTRY_ENABLE_COMMAND_METRICS', true), + 'enable_pool_metrics' => env('SENTRY_ENABLE_POOL_METRICS', true), + 'enable_queue_metrics' => env('SENTRY_ENABLE_QUEUE_METRICS', true), 'metrics_interval' => (int) env('SENTRY_METRICS_INTERVAL', 10), // @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#send_default_pii diff --git a/src/sentry/src/Feature.php b/src/sentry/src/Feature.php index c9e071fab..d14259860 100644 --- a/src/sentry/src/Feature.php +++ b/src/sentry/src/Feature.php @@ -54,6 +54,24 @@ public function isCommandMetricsEnabled(bool $default = true): bool return (bool) $this->config->get('sentry.enable_command_metrics', $default); } + public function isPoolMetricsEnabled(bool $default = true): bool + { + if (! $this->isMetricsEnabled()) { + return false; + } + + return (bool) $this->config->get('sentry.enable_pool_metrics', $default); + } + + public function isQueueMetricsEnabled(bool $default = true): bool + { + if (! $this->isMetricsEnabled()) { + return false; + } + + return (bool) $this->config->get('sentry.enable_queue_metrics', $default); + } + public function getMetricsInterval(int $default = 10): int { $interval = (int) $this->config->get('sentry.metrics_interval', $default); diff --git a/src/sentry/src/Metrics/Listener/OnBeforeHandle.php b/src/sentry/src/Metrics/Listener/OnBeforeHandle.php index 15472535a..dacc7b597 100644 --- a/src/sentry/src/Metrics/Listener/OnBeforeHandle.php +++ b/src/sentry/src/Metrics/Listener/OnBeforeHandle.php @@ -13,11 +13,14 @@ use FriendsOfHyperf\Sentry\Constants; use FriendsOfHyperf\Sentry\Feature; +use FriendsOfHyperf\Sentry\Metrics\Event\MetricFactoryReady; use FriendsOfHyperf\Sentry\Metrics\Traits\MetricSetter; use FriendsOfHyperf\Sentry\SentryContext; use Hyperf\Command\Event\BeforeHandle; use Hyperf\Coordinator\Timer; use Hyperf\Event\Contract\ListenerInterface; +use Psr\Container\ContainerInterface; +use Psr\EventDispatcher\EventDispatcherInterface; use Sentry\Unit; use function FriendsOfHyperf\Sentry\metrics; @@ -28,8 +31,10 @@ class OnBeforeHandle implements ListenerInterface protected Timer $timer; - public function __construct(protected Feature $feature) - { + public function __construct( + protected ContainerInterface $container, + protected Feature $feature + ) { $this->timer = new Timer(); } @@ -56,6 +61,9 @@ public function process(object $event): void Constants::$runningInCommand = true; + $eventDispatcher = $this->container->get(EventDispatcherInterface::class); + $eventDispatcher->dispatch(new MetricFactoryReady()); + if (! $this->feature->isDefaultMetricsEnabled()) { return; } @@ -87,28 +95,27 @@ public function process(object $event): void 'ru_stime_tv_sec', ]; - $this->timer->tick($this->feature->getMetricsInterval(), function ($isClosing = false) use ($metrics) { - if ($isClosing) { - return Timer::STOP; + $this->timer->tick( + $this->feature->getMetricsInterval(), + function ($isClosing = false) use ($metrics) { + $this->trySet('gc_', $metrics, gc_status()); + $this->trySet('', $metrics, getrusage()); + + metrics()->gauge( + 'memory_usage', + memory_get_usage(true) / 1024 / 1024, + ['worker' => '0'], + Unit::megabyte() + ); + metrics()->gauge( + 'memory_peak_usage', + memory_get_peak_usage(true) / 1024 / 1024, + ['worker' => '0'], + Unit::megabyte() + ); + + metrics()->flush(); } - - $this->trySet('gc_', $metrics, gc_status()); - $this->trySet('', $metrics, getrusage()); - - metrics()->gauge( - 'memory_usage', - memory_get_usage(true) / 1024 / 1024, - ['worker' => '0'], - Unit::megabyte() - ); - metrics()->gauge( - 'memory_peak_usage', - memory_get_peak_usage(true) / 1024 / 1024, - ['worker' => '0'], - Unit::megabyte() - ); - - metrics()->flush(); - }); + ); } } diff --git a/src/sentry/src/Metrics/Listener/OnCoroutineServerStart.php b/src/sentry/src/Metrics/Listener/OnCoroutineServerStart.php index 3fff861b6..2c44d7f3b 100644 --- a/src/sentry/src/Metrics/Listener/OnCoroutineServerStart.php +++ b/src/sentry/src/Metrics/Listener/OnCoroutineServerStart.php @@ -50,18 +50,16 @@ public function listen(): array */ public function process(object $event): void { - if (! $this->feature->isMetricsEnabled()) { - return; - } - if ($this->running) { return; } $this->running = true; - $eventDispatcher = $this->container->get(EventDispatcherInterface::class); - $eventDispatcher->dispatch(new MetricFactoryReady()); + if ($this->feature->isMetricsEnabled()) { + $eventDispatcher = $this->container->get(EventDispatcherInterface::class); + $eventDispatcher->dispatch(new MetricFactoryReady()); + } if (! $this->feature->isDefaultMetricsEnabled()) { return; @@ -96,28 +94,27 @@ public function process(object $event): void 'ru_stime_tv_sec', ]; - $this->timer->tick($this->feature->getMetricsInterval(), function ($isClosing = false) use ($metrics) { - if ($isClosing) { - return Timer::STOP; + $this->timer->tick( + $this->feature->getMetricsInterval(), + function ($isClosing = false) use ($metrics) { + $this->trySet('gc_', $metrics, gc_status()); + $this->trySet('', $metrics, getrusage()); + + metrics()->gauge( + 'memory_usage', + memory_get_usage(true) / 1024 / 1024, + ['worker' => '0'], + Unit::megabyte() + ); + metrics()->gauge( + 'memory_peak_usage', + memory_get_peak_usage(true) / 1024 / 1024, + ['worker' => '0'], + Unit::megabyte() + ); + + metrics()->flush(); } - - $this->trySet('gc_', $metrics, gc_status()); - $this->trySet('', $metrics, getrusage()); - - metrics()->gauge( - 'memory_usage', - memory_get_usage(true) / 1024 / 1024, - ['worker' => '0'], - Unit::megabyte() - ); - metrics()->gauge( - 'memory_peak_usage', - memory_get_peak_usage(true) / 1024 / 1024, - ['worker' => '0'], - Unit::megabyte() - ); - - metrics()->flush(); - }); + ); } } diff --git a/src/sentry/src/Metrics/Listener/OnMetricFactoryReady.php b/src/sentry/src/Metrics/Listener/OnMetricFactoryReady.php index 3496791cc..334147952 100644 --- a/src/sentry/src/Metrics/Listener/OnMetricFactoryReady.php +++ b/src/sentry/src/Metrics/Listener/OnMetricFactoryReady.php @@ -95,43 +95,42 @@ public function process(object $event): void } } - $this->timer->tick($this->feature->getMetricsInterval(), function ($isClosing = false) use ($metrics, $serverStatsFactory, $workerId) { - if ($isClosing) { - return Timer::STOP; - } - - $this->trySet('', $metrics, Coroutine::stats(), $workerId); - $this->trySet('timer_', $metrics, Timer::stats(), $workerId); + $this->timer->tick( + $this->feature->getMetricsInterval(), + function ($isClosing = false) use ($metrics, $serverStatsFactory, $workerId) { + $this->trySet('', $metrics, Coroutine::stats(), $workerId); + $this->trySet('timer_', $metrics, Timer::stats(), $workerId); + + if ($serverStatsFactory) { + $this->trySet('', $metrics, $serverStatsFactory(), $workerId); + } - if ($serverStatsFactory) { - $this->trySet('', $metrics, $serverStatsFactory(), $workerId); - } + if (class_exists('Swoole\Timer')) { + $this->trySet('swoole_timer_', $metrics, \Swoole\Timer::stats(), $workerId); + } - if (class_exists('Swoole\Timer')) { - $this->trySet('swoole_timer_', $metrics, \Swoole\Timer::stats(), $workerId); + $load = sys_getloadavg(); + + metrics()->gauge( + 'sys_load', + round($load[0] / System::getCpuCoresNum(), 2), + ['worker' => (string) $workerId], + ); + metrics()->gauge( + 'metric_process_memory_usage', + memory_get_usage(true) / 1024 / 1024, + ['worker' => (string) $workerId], + Unit::megabyte() + ); + metrics()->gauge( + 'metric_process_memory_peak_usage', + memory_get_peak_usage(true) / 1024 / 1024, + ['worker' => (string) $workerId], + Unit::megabyte() + ); + + metrics()->flush(); } - - $load = sys_getloadavg(); - - metrics()->gauge( - 'sys_load', - round($load[0] / System::getCpuCoresNum(), 2), - ['worker' => (string) $workerId], - ); - metrics()->gauge( - 'metric_process_memory_usage', - memory_get_usage(true) / 1024 / 1024, - ['worker' => (string) $workerId], - Unit::megabyte() - ); - metrics()->gauge( - 'metric_process_memory_peak_usage', - memory_get_peak_usage(true) / 1024 / 1024, - ['worker' => (string) $workerId], - Unit::megabyte() - ); - - metrics()->flush(); - }); + ); } } diff --git a/src/sentry/src/Metrics/Listener/OnWorkerStart.php b/src/sentry/src/Metrics/Listener/OnWorkerStart.php index a038813fc..fdb353e9b 100644 --- a/src/sentry/src/Metrics/Listener/OnWorkerStart.php +++ b/src/sentry/src/Metrics/Listener/OnWorkerStart.php @@ -49,14 +49,16 @@ public function listen(): array */ public function process(object $event): void { + if ($this->feature->isMetricsEnabled() && $event->workerId == 0) { + $workerId = $event->workerId; + $eventDispatcher = $this->container->get(EventDispatcherInterface::class); + $eventDispatcher->dispatch(new MetricFactoryReady($workerId)); + } + if (! $this->feature->isDefaultMetricsEnabled()) { return; } - $workerId = $event->workerId; - $eventDispatcher = $this->container->get(EventDispatcherInterface::class); - $eventDispatcher->dispatch(new MetricFactoryReady($workerId)); - // The following metrics MUST be collected in worker. $metrics = [ 'worker_request_count', @@ -86,40 +88,39 @@ public function process(object $event): void 'ru_stime_tv_sec', ]; - $this->timer->tick($this->feature->getMetricsInterval(), function ($isClosing = false) use ($metrics, $event) { - if ($isClosing) { - return Timer::STOP; - } - - $server = $this->container->get(Server::class); - $serverStats = $server->stats(); - $this->trySet('gc_', $metrics, gc_status()); - $this->trySet('', $metrics, getrusage()); + $this->timer->tick( + $this->feature->getMetricsInterval(), + function ($isClosing = false) use ($metrics, $event) { + $server = $this->container->get(Server::class); + $serverStats = $server->stats(); + $this->trySet('gc_', $metrics, gc_status()); + $this->trySet('', $metrics, getrusage()); - metrics()->gauge( - 'worker_request_count', - (float) $serverStats['worker_request_count'], - ['worker' => (string) ($event->workerId ?? 0)], - ); - metrics()->gauge( - 'worker_dispatch_count', - (float) $serverStats['worker_dispatch_count'], - ['worker' => (string) ($event->workerId ?? 0)], - ); - metrics()->gauge( - 'memory_usage', - memory_get_usage(true) / 1024 / 1024, - ['worker' => (string) ($event->workerId ?? 0)], - Unit::megabyte() - ); - metrics()->gauge( - 'memory_peak_usage', - memory_get_peak_usage(true) / 1024 / 1024, - ['worker' => (string) ($event->workerId ?? 0)], - Unit::megabyte() - ); + metrics()->gauge( + 'worker_request_count', + (float) $serverStats['worker_request_count'], + ['worker' => (string) ($event->workerId ?? 0)], + ); + metrics()->gauge( + 'worker_dispatch_count', + (float) $serverStats['worker_dispatch_count'], + ['worker' => (string) ($event->workerId ?? 0)], + ); + metrics()->gauge( + 'memory_usage', + memory_get_usage(true) / 1024 / 1024, + ['worker' => (string) ($event->workerId ?? 0)], + Unit::megabyte() + ); + metrics()->gauge( + 'memory_peak_usage', + memory_get_peak_usage(true) / 1024 / 1024, + ['worker' => (string) ($event->workerId ?? 0)], + Unit::megabyte() + ); - metrics()->flush(); - }); + metrics()->flush(); + } + ); } } diff --git a/src/sentry/src/Metrics/Listener/PoolWatcher.php b/src/sentry/src/Metrics/Listener/PoolWatcher.php index caab50d47..bec5ee3b1 100644 --- a/src/sentry/src/Metrics/Listener/PoolWatcher.php +++ b/src/sentry/src/Metrics/Listener/PoolWatcher.php @@ -57,45 +57,40 @@ abstract public function process(object $event): void; public function watch(Pool $pool, string $poolName, int $workerId): void { - if (! $this->feature->isMetricsEnabled()) { + if (! $this->feature->isPoolMetricsEnabled()) { return; } - $this->timer->tick($this->feature->getMetricsInterval(), function ($isClosing = false) use ( - $pool, - $workerId, - $poolName - ) { - if ($isClosing) { - return Timer::STOP; - } - - metrics()->gauge( - $this->getPrefix() . '_connections_in_use', - (float) $pool->getCurrentConnections(), - [ - 'pool' => $poolName, - 'worker' => (string) $workerId, - ] - ); - metrics()->gauge( - $this->getPrefix() . '_connections_in_waiting', - (float) $pool->getConnectionsInChannel(), - [ - 'pool' => $poolName, - 'worker' => (string) $workerId, - ] - ); - metrics()->gauge( - $this->getPrefix() . '_max_connections', - (float) $pool->getOption()->getMaxConnections(), - [ - 'pool' => $poolName, - 'worker' => (string) $workerId, - ] - ); + $this->timer->tick( + $this->feature->getMetricsInterval(), + function ($isClosing = false) use ($pool, $workerId, $poolName) { + metrics()->gauge( + $this->getPrefix() . '_connections_in_use', + (float) $pool->getCurrentConnections(), + [ + 'pool' => $poolName, + 'worker' => (string) $workerId, + ] + ); + metrics()->gauge( + $this->getPrefix() . '_connections_in_waiting', + (float) $pool->getConnectionsInChannel(), + [ + 'pool' => $poolName, + 'worker' => (string) $workerId, + ] + ); + metrics()->gauge( + $this->getPrefix() . '_max_connections', + (float) $pool->getOption()->getMaxConnections(), + [ + 'pool' => $poolName, + 'worker' => (string) $workerId, + ] + ); - metrics()->flush(); - }); + metrics()->flush(); + } + ); } } diff --git a/src/sentry/src/Metrics/Listener/QueueWatcher.php b/src/sentry/src/Metrics/Listener/QueueWatcher.php index c25c97699..804c39428 100644 --- a/src/sentry/src/Metrics/Listener/QueueWatcher.php +++ b/src/sentry/src/Metrics/Listener/QueueWatcher.php @@ -47,45 +47,44 @@ public function listen(): array */ public function process(object $event): void { - if (! $this->feature->isMetricsEnabled()) { + if (! $this->feature->isQueueMetricsEnabled()) { return; } - $this->timer->tick($this->feature->getMetricsInterval(), function ($isClosing = false) { - if ($isClosing) { - return Timer::STOP; - } + $this->timer->tick( + $this->feature->getMetricsInterval(), + function ($isClosing = false) { + $config = $this->container->get(ConfigInterface::class); + $queues = array_keys($config->get('async_queue', [])); - $config = $this->container->get(ConfigInterface::class); - $queues = array_keys($config->get('async_queue', [])); + foreach ($queues as $name) { + $queue = $this->container->get(DriverFactory::class)->get($name); + $info = $queue->info(); - foreach ($queues as $name) { - $queue = $this->container->get(DriverFactory::class)->get($name); - $info = $queue->info(); + metrics()->gauge( + 'queue_waiting', + (float) $info['waiting'], + ['queue' => $name] + ); + metrics()->gauge( + 'queue_delayed', + (float) $info['delayed'], + ['queue' => $name] + ); + metrics()->gauge( + 'queue_failed', + (float) $info['failed'], + ['queue' => $name] + ); + metrics()->gauge( + 'queue_timeout', + (float) $info['timeout'], + ['queue' => $name] + ); + } - metrics()->gauge( - 'queue_waiting', - (float) $info['waiting'], - ['queue' => $name] - ); - metrics()->gauge( - 'queue_delayed', - (float) $info['delayed'], - ['queue' => $name] - ); - metrics()->gauge( - 'queue_failed', - (float) $info['failed'], - ['queue' => $name] - ); - metrics()->gauge( - 'queue_timeout', - (float) $info['timeout'], - ['queue' => $name] - ); + metrics()->flush(); } - - metrics()->flush(); - }); + ); } } From 1ee1f9942aab88c59a5bab416e030036064501c5 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Wed, 24 Dec 2025 12:45:11 +0800 Subject: [PATCH 2/6] fix(sentry): alias Coroutine class for consistency in metric processing --- src/sentry/src/Metrics/Listener/OnMetricFactoryReady.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sentry/src/Metrics/Listener/OnMetricFactoryReady.php b/src/sentry/src/Metrics/Listener/OnMetricFactoryReady.php index 334147952..ca9587bec 100644 --- a/src/sentry/src/Metrics/Listener/OnMetricFactoryReady.php +++ b/src/sentry/src/Metrics/Listener/OnMetricFactoryReady.php @@ -17,7 +17,7 @@ use FriendsOfHyperf\Sentry\Metrics\Event\MetricFactoryReady; use FriendsOfHyperf\Sentry\Metrics\Traits\MetricSetter; use Hyperf\Coordinator\Timer; -use Hyperf\Engine\Coroutine; +use Hyperf\Engine\Coroutine as Co; use Hyperf\Event\Contract\ListenerInterface; use Hyperf\Support\System; use Psr\Container\ContainerInterface; @@ -98,7 +98,7 @@ public function process(object $event): void $this->timer->tick( $this->feature->getMetricsInterval(), function ($isClosing = false) use ($metrics, $serverStatsFactory, $workerId) { - $this->trySet('', $metrics, Coroutine::stats(), $workerId); + $this->trySet('', $metrics, Co::stats(), $workerId); $this->trySet('timer_', $metrics, Timer::stats(), $workerId); if ($serverStatsFactory) { From 7504512d9505fd0616e2230504923f268ab0b9b8 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Wed, 24 Dec 2025 12:48:02 +0800 Subject: [PATCH 3/6] fix(metrics): remove unused parameter from timer callback functions --- src/sentry/src/Metrics/Listener/OnBeforeHandle.php | 2 +- src/sentry/src/Metrics/Listener/OnCoroutineServerStart.php | 2 +- src/sentry/src/Metrics/Listener/OnMetricFactoryReady.php | 2 +- src/sentry/src/Metrics/Listener/OnWorkerStart.php | 2 +- src/sentry/src/Metrics/Listener/PoolWatcher.php | 2 +- src/sentry/src/Metrics/Listener/QueueWatcher.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sentry/src/Metrics/Listener/OnBeforeHandle.php b/src/sentry/src/Metrics/Listener/OnBeforeHandle.php index dacc7b597..2c2f989e0 100644 --- a/src/sentry/src/Metrics/Listener/OnBeforeHandle.php +++ b/src/sentry/src/Metrics/Listener/OnBeforeHandle.php @@ -97,7 +97,7 @@ public function process(object $event): void $this->timer->tick( $this->feature->getMetricsInterval(), - function ($isClosing = false) use ($metrics) { + function () use ($metrics) { $this->trySet('gc_', $metrics, gc_status()); $this->trySet('', $metrics, getrusage()); diff --git a/src/sentry/src/Metrics/Listener/OnCoroutineServerStart.php b/src/sentry/src/Metrics/Listener/OnCoroutineServerStart.php index 2c44d7f3b..41f72a51d 100644 --- a/src/sentry/src/Metrics/Listener/OnCoroutineServerStart.php +++ b/src/sentry/src/Metrics/Listener/OnCoroutineServerStart.php @@ -96,7 +96,7 @@ public function process(object $event): void $this->timer->tick( $this->feature->getMetricsInterval(), - function ($isClosing = false) use ($metrics) { + function () use ($metrics) { $this->trySet('gc_', $metrics, gc_status()); $this->trySet('', $metrics, getrusage()); diff --git a/src/sentry/src/Metrics/Listener/OnMetricFactoryReady.php b/src/sentry/src/Metrics/Listener/OnMetricFactoryReady.php index ca9587bec..e34c294a2 100644 --- a/src/sentry/src/Metrics/Listener/OnMetricFactoryReady.php +++ b/src/sentry/src/Metrics/Listener/OnMetricFactoryReady.php @@ -97,7 +97,7 @@ public function process(object $event): void $this->timer->tick( $this->feature->getMetricsInterval(), - function ($isClosing = false) use ($metrics, $serverStatsFactory, $workerId) { + function () use ($metrics, $serverStatsFactory, $workerId) { $this->trySet('', $metrics, Co::stats(), $workerId); $this->trySet('timer_', $metrics, Timer::stats(), $workerId); diff --git a/src/sentry/src/Metrics/Listener/OnWorkerStart.php b/src/sentry/src/Metrics/Listener/OnWorkerStart.php index fdb353e9b..a2b9d5b60 100644 --- a/src/sentry/src/Metrics/Listener/OnWorkerStart.php +++ b/src/sentry/src/Metrics/Listener/OnWorkerStart.php @@ -90,7 +90,7 @@ public function process(object $event): void $this->timer->tick( $this->feature->getMetricsInterval(), - function ($isClosing = false) use ($metrics, $event) { + function () use ($metrics, $event) { $server = $this->container->get(Server::class); $serverStats = $server->stats(); $this->trySet('gc_', $metrics, gc_status()); diff --git a/src/sentry/src/Metrics/Listener/PoolWatcher.php b/src/sentry/src/Metrics/Listener/PoolWatcher.php index bec5ee3b1..8371d5991 100644 --- a/src/sentry/src/Metrics/Listener/PoolWatcher.php +++ b/src/sentry/src/Metrics/Listener/PoolWatcher.php @@ -63,7 +63,7 @@ public function watch(Pool $pool, string $poolName, int $workerId): void $this->timer->tick( $this->feature->getMetricsInterval(), - function ($isClosing = false) use ($pool, $workerId, $poolName) { + function () use ($pool, $workerId, $poolName) { metrics()->gauge( $this->getPrefix() . '_connections_in_use', (float) $pool->getCurrentConnections(), diff --git a/src/sentry/src/Metrics/Listener/QueueWatcher.php b/src/sentry/src/Metrics/Listener/QueueWatcher.php index 804c39428..d58d64762 100644 --- a/src/sentry/src/Metrics/Listener/QueueWatcher.php +++ b/src/sentry/src/Metrics/Listener/QueueWatcher.php @@ -53,7 +53,7 @@ public function process(object $event): void $this->timer->tick( $this->feature->getMetricsInterval(), - function ($isClosing = false) { + function () { $config = $this->container->get(ConfigInterface::class); $queues = array_keys($config->get('async_queue', [])); From 34ffc893f9e9812fd940ebb04ca1c29d6467ede9 Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Wed, 24 Dec 2025 12:50:04 +0800 Subject: [PATCH 4/6] fix(metrics): check for EventDispatcherInterface existence before dispatching MetricFactoryReady event --- src/sentry/src/Metrics/Listener/OnBeforeHandle.php | 5 +++-- src/sentry/src/Metrics/Listener/OnCoroutineServerStart.php | 5 ++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sentry/src/Metrics/Listener/OnBeforeHandle.php b/src/sentry/src/Metrics/Listener/OnBeforeHandle.php index 2c2f989e0..c0b5a1cc8 100644 --- a/src/sentry/src/Metrics/Listener/OnBeforeHandle.php +++ b/src/sentry/src/Metrics/Listener/OnBeforeHandle.php @@ -61,8 +61,9 @@ public function process(object $event): void Constants::$runningInCommand = true; - $eventDispatcher = $this->container->get(EventDispatcherInterface::class); - $eventDispatcher->dispatch(new MetricFactoryReady()); + if ($this->container->has(EventDispatcherInterface::class)) { + $this->container->get(EventDispatcherInterface::class)->dispatch(new MetricFactoryReady()); + } if (! $this->feature->isDefaultMetricsEnabled()) { return; diff --git a/src/sentry/src/Metrics/Listener/OnCoroutineServerStart.php b/src/sentry/src/Metrics/Listener/OnCoroutineServerStart.php index 41f72a51d..aff237387 100644 --- a/src/sentry/src/Metrics/Listener/OnCoroutineServerStart.php +++ b/src/sentry/src/Metrics/Listener/OnCoroutineServerStart.php @@ -56,9 +56,8 @@ public function process(object $event): void $this->running = true; - if ($this->feature->isMetricsEnabled()) { - $eventDispatcher = $this->container->get(EventDispatcherInterface::class); - $eventDispatcher->dispatch(new MetricFactoryReady()); + if ($this->feature->isMetricsEnabled() && $this->container->has(EventDispatcherInterface::class)) { + $this->container->get(EventDispatcherInterface::class)->dispatch(new MetricFactoryReady()); } if (! $this->feature->isDefaultMetricsEnabled()) { From 98c76e240d48763282656203651d21cac86966bd Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Wed, 24 Dec 2025 12:51:38 +0800 Subject: [PATCH 5/6] fix(metrics): ensure command metrics are enabled before dispatching MetricFactoryReady event --- src/sentry/src/Metrics/Listener/OnBeforeHandle.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sentry/src/Metrics/Listener/OnBeforeHandle.php b/src/sentry/src/Metrics/Listener/OnBeforeHandle.php index c0b5a1cc8..f75d48f57 100644 --- a/src/sentry/src/Metrics/Listener/OnBeforeHandle.php +++ b/src/sentry/src/Metrics/Listener/OnBeforeHandle.php @@ -54,14 +54,13 @@ public function process(object $event): void ! $event instanceof BeforeHandle || SentryContext::getCronCheckInId() // Prevent duplicate metrics in cron job. || ! $event->getCommand()->getApplication()->isAutoExitEnabled() // Only enable in the command with auto exit. - || ! $this->feature->isCommandMetricsEnabled() ) { return; } Constants::$runningInCommand = true; - if ($this->container->has(EventDispatcherInterface::class)) { + if ($this->feature->isCommandMetricsEnabled() && $this->container->has(EventDispatcherInterface::class)) { $this->container->get(EventDispatcherInterface::class)->dispatch(new MetricFactoryReady()); } From 1ce119109f592aa99f15a1773cc8039f53e0cf4f Mon Sep 17 00:00:00 2001 From: Deeka Wong <8337659+huangdijia@users.noreply.github.com> Date: Wed, 24 Dec 2025 12:56:45 +0800 Subject: [PATCH 6/6] feat(sentry): add enable_queue_metrics and enable_pool_metrics options to ClientBuilderFactory --- src/sentry/src/Factory/ClientBuilderFactory.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sentry/src/Factory/ClientBuilderFactory.php b/src/sentry/src/Factory/ClientBuilderFactory.php index c8ab118dd..c508f7fa2 100644 --- a/src/sentry/src/Factory/ClientBuilderFactory.php +++ b/src/sentry/src/Factory/ClientBuilderFactory.php @@ -33,6 +33,8 @@ class ClientBuilderFactory 'logs_channel_level', 'enable_default_metrics', 'enable_command_metrics', + 'enable_queue_metrics', + 'enable_pool_metrics', 'metrics_interval', 'transport_channel_size', 'transport_concurrent_limit',