From 3866ef8d2505731aec99ca1463d1a18f19aedf80 Mon Sep 17 00:00:00 2001 From: Daniil Gentili Date: Wed, 15 May 2024 22:17:03 +0200 Subject: [PATCH] Finalize prometheus settings --- examples/bot.php | 11 +++++++++ schemas | 2 +- src/GarbageCollector.php | 9 ++++---- src/MTProto.php | 23 +++++++++++++++---- src/Magic.php | 5 ++++ src/Settings/Prometheus.php | 46 ++++++++++++++++++++++++++----------- 6 files changed, 73 insertions(+), 23 deletions(-) diff --git a/examples/bot.php b/examples/bot.php index ea22cb369..6ecd8777a 100755 --- a/examples/bot.php +++ b/examples/bot.php @@ -45,6 +45,8 @@ use danog\MadelineProto\Settings\Database\Redis; use danog\MadelineProto\SimpleEventHandler; use danog\MadelineProto\VoIP; +use function Amp\Socket\SocketAddress\fromString; + // MadelineProto is already loaded if (class_exists(API::class)) { // Otherwise, if a stable version of MadelineProto was installed via composer, load composer autoloader @@ -310,6 +312,15 @@ $settings->getLogger()->setLevel(Logger::LEVEL_ULTRA_VERBOSE); // $settings->setDb((new Postgres)->setDatabase('MadelineProto')->setUsername('daniil')->setPassword('pony')); // $settings->setDb((new Mysql)->setDatabase('MadelineProto')->setUsername('daniil')->setPassword('pony')); +// You can also enable collection of prometheus metrics. +// $settings->getPrometheus()->setEnableCollection(true); + +// Metrics can be returned by an autoconfigured http://127.0.0.1:12345 HTTP server. +// $settings->getPrometheus()->setMetricsBindTo(fromString("127.0.0.1:12345")); + +// Metrics can also be returned by the current script via web, if called with a ?metrics query string +// $settings->getPrometheus()->setReturnMetricsFromStartAndLoop(true); + // For users or bots MyEventHandler::startAndLoop('bot.madeline', $settings); diff --git a/schemas b/schemas index da7d066ee..6fc533efe 160000 --- a/schemas +++ b/schemas @@ -1 +1 @@ -Subproject commit da7d066eee5fa53e5ef43a964032d56197810de9 +Subproject commit 6fc533efe6e1ce440f6da4b0d7037460f73ce96b diff --git a/src/GarbageCollector.php b/src/GarbageCollector.php index 01f2a24a1..9329d61f1 100644 --- a/src/GarbageCollector.php +++ b/src/GarbageCollector.php @@ -70,10 +70,11 @@ final class GarbageCollector } self::$started = true; - self::$prometheus = new BetterCollectorRegistry(new InMemory); - $promLabels = ['madeline_version' => API::RELEASE]; - if (Magic::$pid !== null) { - $promLabels['pid'] = (string) Magic::$pid; + self::$prometheus = new BetterCollectorRegistry(new InMemory, false); + $promLabels = []; + $pid = Magic::getPid(); + if ($pid !== null) { + $promLabels['pid'] = (string) $pid; } self::$alloc = self::$prometheus->registerGauge("", "php_memstats_alloc_bytes", "RAM allocated by the PHP memory pool", $promLabels); diff --git a/src/MTProto.php b/src/MTProto.php index 7712e757d..7017a6c6d 100644 --- a/src/MTProto.php +++ b/src/MTProto.php @@ -543,7 +543,7 @@ final class MTProto implements TLCallback, LoggerGetter, SettingsGetter */ public function getPromGauge(string $namespace, string $name, string $help, array $labels = []): ?BetterGauge { - if (!$this->getSettings()->getPrometheus()->getEnablePrometheus()) { + if (!$this->getSettings()->getPrometheus()->getEnableCollection()) { return null; } return GarbageCollector::$prometheus->getOrRegisterGauge( @@ -563,7 +563,7 @@ final class MTProto implements TLCallback, LoggerGetter, SettingsGetter */ public function getPromCounter(string $namespace, string $name, string $help, array $labels = []): ?BetterCounter { - if (!$this->getSettings()->getPrometheus()->getEnablePrometheus()) { + if (!$this->getSettings()->getPrometheus()->getEnableCollection()) { return null; } return GarbageCollector::$prometheus->getOrRegisterCounter( @@ -584,7 +584,7 @@ final class MTProto implements TLCallback, LoggerGetter, SettingsGetter */ public function getPromSummary(string $namespace, string $name, string $help, array $labels = [], int $maxAgeSeconds = 600, ?array $quantiles = null): ?BetterSummary { - if (!$this->getSettings()->getPrometheus()->getEnablePrometheus()) { + if (!$this->getSettings()->getPrometheus()->getEnableCollection()) { return null; } return GarbageCollector::$prometheus->getOrRegisterSummary( @@ -607,7 +607,7 @@ final class MTProto implements TLCallback, LoggerGetter, SettingsGetter */ public function getPromHistogram(string $namespace, string $name, string $help, array $labels = [], ?array $buckets = null): ?BetterHistogram { - if (!$this->getSettings()->getPrometheus()->getEnablePrometheus()) { + if (!$this->getSettings()->getPrometheus()->getEnableCollection()) { return null; } return GarbageCollector::$prometheus->getOrRegisterHistogram( @@ -933,11 +933,19 @@ final class MTProto implements TLCallback, LoggerGetter, SettingsGetter */ private function cleanupProperties(): void { - $endpoint = $this->getSettings()->getPrometheus()->getPrometheusEndpoint(); + $info = $this->getPromGauge("MadelineProto", "version", "Info about the MadelineProto instance"); + $info?->set(1, [ + 'php_version' => PHP_VERSION, + 'php_version_id' => PHP_VERSION_ID, + 'madeline_version' => API::RELEASE, + 'pid' => Magic::getPid() ?? 'unknown', + ]); + $endpoint = $this->getSettings()->getPrometheus()->getMetricsBindTo(); $this->promServer?->stop(); if ($endpoint === null) { $this->promServer = null; } else { + /** @psalm-suppress ImpureMethodCall */ $this->promServer = SocketHttpServer::createForDirectAccess( $this->getPsrLogger() ); @@ -1310,6 +1318,11 @@ final class MTProto implements TLCallback, LoggerGetter, SettingsGetter $this->cleanupProperties(); $this->settings->getDb()->applyChanges(); } + if ($this->settings->getPrometheus()->hasChanged()) { + $this->logger->logger("The prometheus settings have changed!", Logger::WARNING); + $this->cleanupProperties(); + $this->settings->getPrometheus()->applyChanges(); + } if ($this->settings->getSerialization()->hasChanged()) { $this->logger->logger("The serialization settings have changed!", Logger::WARNING); if (isset($this->serializeLoop)) { diff --git a/src/Magic.php b/src/Magic.php index 30c45aca8..7aba732af 100644 --- a/src/Magic.php +++ b/src/Magic.php @@ -360,6 +360,11 @@ final class Magic return self::$can_getmypid = false; } } + public static function getPid(): ?int + { + self::isFork(); + return self::$pid; + } /** * Get current working directory. */ diff --git a/src/Settings/Prometheus.php b/src/Settings/Prometheus.php index a14120848..ea3509e28 100644 --- a/src/Settings/Prometheus.php +++ b/src/Settings/Prometheus.php @@ -25,44 +25,64 @@ use danog\MadelineProto\SettingsAbstract; final class Prometheus extends SettingsAbstract { /** - * Whether to enable prometheus stat reporting for this session. + * Whether to enable prometheus stat collection for this session. */ - protected bool $enablePrometheus = false; + protected bool $enableCollection = false; /** * Whether to expose prometheus metrics on the specified endpoint via HTTP. */ - protected ?SocketAddress $prometheusEndpoint = null; + protected ?SocketAddress $metricsBindTo = null; + /** + * Whether to expose prometheus metrics with startAndLoop, by providing a ?metrics query string. + */ + protected bool $returnMetricsFromStartAndLoop = false; /** - * Whether to enable additional prometheus stat reporting for this session. + * Whether to expose prometheus metrics with startAndLoop, by providing a ?metrics query string. */ - public function setEnablePrometheus(bool $enable): self + public function setReturnMetricsFromStartAndLoop(bool $enable): self { - $this->enablePrometheus = $enable; + $this->returnMetricsFromStartAndLoop = $enable; return $this; } /** - * Whether additional prometheus stat reporting is enabled for this session. + * Whether to expose prometheus metrics with startAndLoop, by providing a ?metrics query string. */ - public function getEnablePrometheus(): bool + public function getReturnMetricsFromStartAndLoop(): bool { - return $this->enablePrometheus; + return $this->returnMetricsFromStartAndLoop; + } + + /** + * Whether to enable additional prometheus stat collection for this session. + */ + public function setEnableCollection(bool $enable): self + { + $this->enableCollection = $enable; + return $this; + } + /** + * Whether additional prometheus stat collection is enabled for this session. + */ + public function getEnableCollection(): bool + { + return $this->enableCollection; } /** * Whether to expose prometheus metrics on the specified endpoint via HTTP. */ - public function setPrometheusEndpoint(?SocketAddress $endpoint): self + public function setMetricsBindTo(?SocketAddress $metricsBindTo): self { - $this->prometheusEndpoint = $endpoint; + $this->metricsBindTo = $metricsBindTo; return $this; } /** * Whether to expose prometheus metrics on the specified endpoint via HTTP. */ - public function getPrometheusEndpoint(): ?SocketAddress + public function getMetricsBindTo(): ?SocketAddress { - return $this->prometheusEndpoint; + return $this->metricsBindTo; } }