1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-11-30 08:39:00 +01:00

Switch to danog/better-prometheus

This commit is contained in:
Daniil Gentili 2024-05-03 17:40:57 +02:00
parent ca81b3865a
commit 59b14bca76
8 changed files with 54 additions and 115 deletions

View File

@ -840,10 +840,6 @@ Want to add your own open-source project to this list? [Click here!](https://doc
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getAllDrafts.html" name="messages.getAllDrafts">Return all message drafts.: messages.getAllDrafts</a> * <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getAllDrafts.html" name="messages.getAllDrafts">Return all message drafts.: messages.getAllDrafts</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getSettings" name="getSettings">Return current settings: getSettings</a> * <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getSettings" name="getSettings">Return current settings: getSettings</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.getAuthorizationForm.html" name="account.getAuthorizationForm">Returns a Telegram Passport authorization form for sharing data with a service: account.getAuthorizationForm</a> * <a href="https://docs.madelineproto.xyz/API_docs/methods/account.getAuthorizationForm.html" name="account.getAuthorizationForm">Returns a Telegram Passport authorization form for sharing data with a service: account.getAuthorizationForm</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getPromCounter" name="getPromCounter">Returns a closure linked to the specified prometheus counter: getPromCounter</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getPromGauge" name="getPromGauge">Returns a closure linked to the specified prometheus gauge: getPromGauge</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getPromHistogram" name="getPromHistogram">Returns a closure linked to the specified prometheus histogram: getPromHistogram</a>
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#getPromSummary" name="getPromSummary">Returns a closure linked to the specified prometheus summary: getPromSummary</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.getWallPapers.html" name="account.getWallPapers">Returns a list of available wallpapers: account.getWallPapers</a> * <a href="https://docs.madelineproto.xyz/API_docs/methods/account.getWallPapers.html" name="account.getWallPapers">Returns a list of available wallpapers: account.getWallPapers</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getEmojiURL.html" name="messages.getEmojiURL">Returns an HTTP URL which can be used to automatically log in into translation platform and suggest new emoji keywords ». The URL will be valid for 30 seconds after generation: messages.getEmojiURL</a> * <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getEmojiURL.html" name="messages.getEmojiURL">Returns an HTTP URL which can be used to automatically log in into translation platform and suggest new emoji keywords ». The URL will be valid for 30 seconds after generation: messages.getEmojiURL</a>
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getAttachMenuBot.html" name="messages.getAttachMenuBot">Returns attachment menu entry for a bot mini app that can be launched from the attachment menu »: messages.getAttachMenuBot</a> * <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.getAttachMenuBot.html" name="messages.getAttachMenuBot">Returns attachment menu entry for a bot mini app that can be launched from the attachment menu »: messages.getAttachMenuBot</a>

View File

@ -62,7 +62,7 @@
"danog/async-orm": "^1.0.2", "danog/async-orm": "^1.0.2",
"symfony/thanks": "^1.3", "symfony/thanks": "^1.3",
"danog/telegram-entities": "^1.0.2", "danog/telegram-entities": "^1.0.2",
"promphp/prometheus_client_php": "^2.10" "danog/better-prometheus": "^0.1.0"
}, },
"require-dev": { "require-dev": {
"ext-ctype": "*", "ext-ctype": "*",

2
docs

@ -1 +1 @@
Subproject commit ab4b4782f8582ca413bcd7c94eb4900c828fd970 Subproject commit 1ff83e3b9bd2857c53cc00aba359151e7de06aa7

View File

@ -20,6 +20,9 @@ use Amp\Http\Client\HttpClientBuilder;
use Amp\Http\Client\Request; use Amp\Http\Client\Request;
use Amp\SignalException; use Amp\SignalException;
use AssertionError; use AssertionError;
use danog\BetterPrometheus\BetterCollectorRegistry;
use danog\BetterPrometheus\BetterGauge;
use Prometheus\Storage\InMemory;
use ReflectionFiber; use ReflectionFiber;
use Revolt\EventLoop; use Revolt\EventLoop;
use Throwable; use Throwable;
@ -56,6 +59,10 @@ final class GarbageCollector
*/ */
private static int $memoryConsumption = 0; private static int $memoryConsumption = 0;
private static BetterCollectorRegistry $prometheus;
private static BetterGauge $alloc;
private static BetterGauge $inuse;
public static function start(): void public static function start(): void
{ {
if (self::$started) { if (self::$started) {
@ -63,11 +70,20 @@ final class GarbageCollector
} }
self::$started = true; self::$started = true;
$counter = Magic::getCounter("", "explicit_gc_count", "Number of times the GC was explicitly invoked", []); self::$prometheus = new BetterCollectorRegistry(new InMemory);
$promLabels = ['madeline_version' => API::RELEASE];
if (Magic::$pid !== null) {
$promLabels['pid'] = (string) Magic::$pid;
}
self::$alloc = self::$prometheus->registerGauge("", "php_memstats_alloc_bytes", "RAM allocated by the PHP memory pool", $promLabels);
self::$inuse = self::$prometheus->registerGauge("", "php_memstats_inuse_bytes", "RAM actually used by PHP", $promLabels);
$counter = self::$prometheus->registerCounter("", "explicit_gc_count", "Number of times the GC was explicitly invoked", $promLabels);
EventLoop::unreference(EventLoop::repeat(1, static function () use ($counter): void { EventLoop::unreference(EventLoop::repeat(1, static function () use ($counter): void {
$currentMemory = self::getMemoryConsumption(); $currentMemory = self::getMemoryConsumption();
if ($currentMemory > self::$memoryConsumption + self::$memoryDiffMb) { if ($currentMemory > self::$memoryConsumption + self::$memoryDiffMb) {
$counter(); $counter->inc();
gc_collect_cycles(); gc_collect_cycles();
self::$memoryConsumption = self::getMemoryConsumption(); self::$memoryConsumption = self::getMemoryConsumption();
/*self::$memoryConsumption = self::getMemoryConsumption(); /*self::$memoryConsumption = self::getMemoryConsumption();
@ -161,7 +177,10 @@ final class GarbageCollector
private static function getMemoryConsumption(): int private static function getMemoryConsumption(): int
{ {
//self::$map ??= new WeakMap; //self::$map ??= new WeakMap;
$memory = round(memory_get_usage()/1024/1024, 1); self::$alloc->set(memory_get_usage(true));
$inuse = memory_get_usage();
self::$inuse->set($inuse);
$memory = round($inuse/1024/1024, 1);
/*if (!Magic::$suspendPeriodicLogging) { /*if (!Magic::$suspendPeriodicLogging) {
Logger::log("Memory consumption: $memory Mb", Logger::ULTRA_VERBOSE); Logger::log("Memory consumption: $memory Mb", Logger::ULTRA_VERBOSE);
}*/ }*/

View File

@ -25,7 +25,7 @@ use Amp\DeferredFuture;
use Amp\Future; use Amp\Future;
use Amp\Ipc\IpcServer; use Amp\Ipc\IpcServer;
use Amp\Ipc\Sync\ChannelledSocket; use Amp\Ipc\Sync\ChannelledSocket;
use Closure; use danog\BetterPrometheus\BetterGauge;
use danog\Loop\Loop; use danog\Loop\Loop;
use danog\MadelineProto\Exception; use danog\MadelineProto\Exception;
use danog\MadelineProto\Ipc\Runner\ProcessRunner; use danog\MadelineProto\Ipc\Runner\ProcessRunner;
@ -53,10 +53,7 @@ abstract class AbstractServer extends Loop
use InternalLoop { use InternalLoop {
__construct as private internalInit; __construct as private internalInit;
} }
/** private BetterGauge $connectionGauge;
* @var Closure(int): void
*/
private Closure $connectionGauge;
public function __construct(MTProto $API) public function __construct(MTProto $API)
{ {
$this->internalInit($API); $this->internalInit($API);
@ -217,7 +214,7 @@ abstract class AbstractServer extends Loop
{ {
$this->API->waitForInit(); $this->API->waitForInit();
$this->API->logger('Accepted IPC client connection!'); $this->API->logger('Accepted IPC client connection!');
($this->connectionGauge)(1); $this->connectionGauge->inc();
$id = 0; $id = 0;
$payload = null; $payload = null;
@ -228,7 +225,7 @@ abstract class AbstractServer extends Loop
} catch (Throwable $e) { } catch (Throwable $e) {
Logger::log("Exception in IPC connection: $e"); Logger::log("Exception in IPC connection: $e");
} finally { } finally {
($this->connectionGauge)(-1); $this->connectionGauge->dec();
EventLoop::queue(function () use ($socket, $payload): void { EventLoop::queue(function () use ($socket, $payload): void {
try { try {
$socket->disconnect(); $socket->disconnect();

View File

@ -32,7 +32,6 @@ use Amp\Http\Client\Request;
use Amp\SignalException; use Amp\SignalException;
use Amp\Sync\LocalKeyedMutex; use Amp\Sync\LocalKeyedMutex;
use Amp\Sync\LocalMutex; use Amp\Sync\LocalMutex;
use Closure;
use danog\AsyncOrm\Annotations\OrmMappedArray; use danog\AsyncOrm\Annotations\OrmMappedArray;
use danog\AsyncOrm\DbArray; use danog\AsyncOrm\DbArray;
use danog\AsyncOrm\DbArrayBuilder; use danog\AsyncOrm\DbArrayBuilder;
@ -40,6 +39,11 @@ use danog\AsyncOrm\Driver\MemoryArray;
use danog\AsyncOrm\KeyType; use danog\AsyncOrm\KeyType;
use danog\AsyncOrm\Settings as OrmSettings; use danog\AsyncOrm\Settings as OrmSettings;
use danog\AsyncOrm\ValueType; use danog\AsyncOrm\ValueType;
use danog\BetterPrometheus\BetterCollectorRegistry;
use danog\BetterPrometheus\BetterCounter;
use danog\BetterPrometheus\BetterGauge;
use danog\BetterPrometheus\BetterHistogram;
use danog\BetterPrometheus\BetterSummary;
use danog\MadelineProto\Broadcast\Broadcast; use danog\MadelineProto\Broadcast\Broadcast;
use danog\MadelineProto\EventHandler\Message; use danog\MadelineProto\EventHandler\Message;
use danog\MadelineProto\Ipc\Server; use danog\MadelineProto\Ipc\Server;
@ -77,6 +81,7 @@ use danog\MadelineProto\Wrappers\Start;
use Prometheus\Counter; use Prometheus\Counter;
use Prometheus\Gauge; use Prometheus\Gauge;
use Prometheus\Histogram; use Prometheus\Histogram;
use Prometheus\Storage\InMemory;
use Prometheus\Summary; use Prometheus\Summary;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
use Revolt\EventLoop; use Revolt\EventLoop;
@ -512,17 +517,15 @@ final class MTProto implements TLCallback, LoggerGetter, SettingsGetter
} }
/** /**
* Returns a closure linked to the specified prometheus gauge. * Creates and returns a prometheus gauge.
* *
* @internal * @internal
* *
* @param array<string, string> $labels * @param array<string, string> $labels
*
* @return Closure(int|float): void
*/ */
public function getPromGauge(string $namespace, string $name, string $help, array $labels = []): Closure public function getPromGauge(string $namespace, string $name, string $help, array $labels = []): BetterGauge
{ {
return Magic::getGauge( return $this->prometheus->getOrRegisterGauge(
$namespace, $namespace,
$name, $name,
$help, $help,
@ -531,17 +534,15 @@ final class MTProto implements TLCallback, LoggerGetter, SettingsGetter
} }
/** /**
* Returns a closure linked to the specified prometheus counter. * Creates and returns a prometheus counter.
* *
* @internal * @internal
* *
* @param array<string, string> $labels * @param array<string, string> $labels
*
* @return Closure(): void Call to increment the counter
*/ */
public function getPromCounter(string $namespace, string $name, string $help, array $labels = []): Closure public function getPromCounter(string $namespace, string $name, string $help, array $labels = []): BetterCounter
{ {
return Magic::getCounter( return $this->prometheus->getOrRegisterCounter(
$namespace, $namespace,
$name, $name,
$help, $help,
@ -550,18 +551,16 @@ final class MTProto implements TLCallback, LoggerGetter, SettingsGetter
} }
/** /**
* Returns a closure linked to the specified prometheus summary. * Creates and returns a prometheus summary.
* *
* @internal * @internal
* *
* @param array<string, string> $labels * @param array<string, string> $labels
* @param ?list<float> $quantiles * @param ?non-empty-list<float> $quantiles
*
* @return Closure(float): void
*/ */
public function getPromSummary(string $namespace, string $name, string $help, array $labels = [], int $maxAgeSeconds = 600, ?array $quantiles = null): Closure public function getPromSummary(string $namespace, string $name, string $help, array $labels = [], int $maxAgeSeconds = 600, ?array $quantiles = null): BetterSummary
{ {
return Magic::getSummary( return $this->prometheus->getOrRegisterSummary(
$namespace, $namespace,
$name, $name,
$help, $help,
@ -572,18 +571,16 @@ final class MTProto implements TLCallback, LoggerGetter, SettingsGetter
} }
/** /**
* Returns a closure linked to the specified prometheus histogram. * Creates and returns a prometheus histogram.
* *
* @internal * @internal
* *
* @param array<string, string> $labels * @param array<string, string> $labels
* @param ?list<float> $buckets * @param ?non-empty-list<float> $buckets
*
* @return Closure(float): void
*/ */
public function getPromHistogram(string $namespace, string $name, string $help, array $labels = [], ?array $buckets = null): Closure public function getPromHistogram(string $namespace, string $name, string $help, array $labels = [], ?array $buckets = null): BetterHistogram
{ {
return Magic::getHistogram( return $this->prometheus->getOrRegisterHistogram(
$namespace, $namespace,
$name, $name,
$help, $help,
@ -897,6 +894,8 @@ final class MTProto implements TLCallback, LoggerGetter, SettingsGetter
$this->ipcServer = null; $this->ipcServer = null;
} }
} }
private BetterCollectorRegistry $prometheus;
/** /**
* Clean up properties from previous versions of MadelineProto. * Clean up properties from previous versions of MadelineProto.
* *
@ -904,6 +903,7 @@ final class MTProto implements TLCallback, LoggerGetter, SettingsGetter
*/ */
private function cleanupProperties(): void private function cleanupProperties(): void
{ {
$this->prometheus ??= new BetterCollectorRegistry(new InMemory, false);
$this->updateCtr = $this->getPromCounter("", "update_count", "Number of received updates since the session was created"); $this->updateCtr = $this->getPromCounter("", "update_count", "Number of received updates since the session was created");
// Start IPC server // Start IPC server
if (!$this->ipcServer) { if (!$this->ipcServer) {

View File

@ -28,11 +28,11 @@ use Amp\Http\Client\Request;
use Amp\Http\Client\Response; use Amp\Http\Client\Response;
use Amp\TimeoutException; use Amp\TimeoutException;
use AssertionError; use AssertionError;
use Closure;
use danog\AsyncOrm\Annotations\OrmMappedArray; use danog\AsyncOrm\Annotations\OrmMappedArray;
use danog\AsyncOrm\DbArray; use danog\AsyncOrm\DbArray;
use danog\AsyncOrm\KeyType; use danog\AsyncOrm\KeyType;
use danog\AsyncOrm\ValueType; use danog\AsyncOrm\ValueType;
use danog\BetterPrometheus\BetterCounter;
use danog\MadelineProto\API; use danog\MadelineProto\API;
use danog\MadelineProto\EventHandler\AbstractMessage; use danog\MadelineProto\EventHandler\AbstractMessage;
use danog\MadelineProto\EventHandler\BotCommands; use danog\MadelineProto\EventHandler\BotCommands;
@ -1261,11 +1261,10 @@ trait UpdateHandler
$this->handleUpdate($update); $this->handleUpdate($update);
} }
/** @var Closure(): void */ private BetterCounter $updateCtr;
private Closure $updateCtr;
private function handleUpdate(array $update): void private function handleUpdate(array $update): void
{ {
($this->updateCtr)(['type' => $update['_']]); $this->updateCtr->inc(['type' => $update['_']]);
/** @var UpdateHandlerType::EVENT_HANDLER|UpdateHandlerType::WEBHOOK|UpdateHandlerType::GET_UPDATES $this->updateHandlerType */ /** @var UpdateHandlerType::EVENT_HANDLER|UpdateHandlerType::WEBHOOK|UpdateHandlerType::GET_UPDATES $this->updateHandlerType */
match ($this->updateHandlerType) { match ($this->updateHandlerType) {
UpdateHandlerType::EVENT_HANDLER => $this->eventUpdateHandler($update), UpdateHandlerType::EVENT_HANDLER => $this->eventUpdateHandler($update),

View File

@ -22,11 +22,8 @@ namespace danog\MadelineProto;
use Amp\DeferredFuture; use Amp\DeferredFuture;
use Amp\SignalException; use Amp\SignalException;
use Closure;
use danog\MadelineProto\TL\Conversion\Extension; use danog\MadelineProto\TL\Conversion\Extension;
use phpseclib3\Math\BigInteger; use phpseclib3\Math\BigInteger;
use Prometheus\CollectorRegistry;
use Prometheus\Storage\InMemory;
use Revolt\EventLoop; use Revolt\EventLoop;
use Throwable; use Throwable;
@ -207,9 +204,6 @@ final class Magic
* Whether there's a basedir limitation. * Whether there's a basedir limitation.
*/ */
public static bool $hasBasedirLimitation = false; public static bool $hasBasedirLimitation = false;
private static CollectorRegistry $prometheus;
/** @var array<string, string> */
private static array $promLabels;
/** /**
* Encoded emojis. * Encoded emojis.
* *
@ -343,75 +337,9 @@ final class Magic
} }
} }
} }
self::$prometheus = new CollectorRegistry(new InMemory);
self::$promLabels = ['release' => API::RELEASE];
if (self::$pid !== null) {
self::$promLabels['pid'] = (string) self::$pid;
}
$alloc = self::getGauge("", "php_memstats_alloc_bytes", "RAM allocated by the PHP memory pool", []);
$inuse = self::getGauge("", "php_memstats_inuse_bytes", "RAM actually used by PHP", []);
EventLoop::unreference(EventLoop::repeat(1.0, static function () use ($alloc, $inuse): void {
$alloc(memory_get_usage(true));
$inuse(memory_get_usage(false));
}));
GarbageCollector::start(); GarbageCollector::start();
self::$inited = true; self::$inited = true;
} }
/**
* @param array<string, string> $labels
* @return Closure(int|float): void
*/
public static function getGauge(string $namespace, string $name, string $help, array $labels): Closure
{
$labels += self::$promLabels;
$gauge = self::$prometheus->getOrRegisterGauge($namespace, $name, $help, array_keys($labels));
$labels = array_values($labels);
return static function (int|float $by) use ($labels, $gauge): void {
$gauge->incBy($by);
};
}
/**
* @param array<string, string> $labels
* @return Closure(): void
*/
public static function getCounter(string $namespace, string $name, string $help, array $labels): Closure
{
$labels += self::$promLabels;
$gauge = self::$prometheus->getOrRegisterCounter($namespace, $name, $help, array_keys($labels));
$labels = array_values($labels);
return static function () use ($labels, $gauge): void {
$gauge->inc($labels);
};
}
/**
* @param array<string, string> $labels
* @param ?list<float> $buckets
* @return Closure(float): void
*/
public static function getHistogram(string $namespace, string $name, string $help, array $labels, ?array $buckets = null): Closure
{
$labels += self::$promLabels;
$gauge = self::$prometheus->getOrRegisterHistogram($namespace, $name, $help, array_keys($labels), $buckets);
$labels = array_values($labels);
return static function (float $value) use ($labels, $gauge): void {
$gauge->observe($value, $labels);
};
}
/**
* @param array<string, string> $labels
* @param ?list<float> $quantiles
* @return Closure(float): void
*/
public static function getSummary(string $namespace, string $name, string $help, array $labels, int $maxAgeSeconds = 600, ?array $quantiles = null): Closure
{
$labels += self::$promLabels;
$gauge = self::$prometheus->getOrRegisterSummary($namespace, $name, $help, array_keys($labels), $maxAgeSeconds, $quantiles);
$labels = array_values($labels);
return static function (float $value) use ($labels, $gauge): void {
$gauge->observe($value, $labels);
};
}
/** /**
* Check if this is a POSIX fork of the main PHP process. * Check if this is a POSIX fork of the main PHP process.
*/ */