1
0
mirror of https://github.com/danog/MadelineProto.git synced 2025-01-22 21:31:28 +01:00

Increase performance with buffered logging

This commit is contained in:
Daniil Gentili 2023-08-29 16:23:26 +02:00
parent 16c43d2678
commit fd654fd9b4
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
3 changed files with 53 additions and 18 deletions

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.14.1@b9d355e0829c397b9b3b47d0c0ed042a8a70284d">
<files psalm-version="dev-master@d3463e30f3768de1f61d1ef4834b4bcd8aa179ef">
<file src="src/API.php">
<ArgumentTypeCoercion>
<code>$settings</code>
@ -824,7 +824,6 @@
<PropertyNotSetInConstructor>
<code>$callback</code>
<code>$server</code>
<code>$settings</code>
</PropertyNotSetInConstructor>
<TypeDoesNotContainType>
<code>$payload === self::SHUTDOWN</code>
@ -893,14 +892,12 @@
: Magic::$script_cwd.DIRECTORY_SEPARATOR.'MadelineProto.log']]></code>
<code><![CDATA[$this->optional]]></code>
<code><![CDATA[$this->optional]]></code>
<code><![CDATA[$this->stdout->getResource()]]></code>
<code><![CDATA[$this->optional]]></code>
<code><![CDATA[$this->stdoutUnbuffered->getResource()]]></code>
</PossiblyInvalidArgument>
<PossiblyInvalidOperand>
<code>$optional</code>
</PossiblyInvalidOperand>
<PossiblyNullFunctionCall>
<code><![CDATA[\call_user_func_array($this->optional, [$param, $level])]]></code>
</PossiblyNullFunctionCall>
<PossiblyUndefinedArrayOffset>
<code><![CDATA[\debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1)[0]['file']]]></code>
<code><![CDATA[\debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 1)[0]['file']]]></code>
@ -908,6 +905,7 @@
<PropertyNotSetInConstructor>
<code>$colors</code>
<code>$stdout</code>
<code>$stdoutUnbuffered</code>
</PropertyNotSetInConstructor>
<UninitializedProperty>
<code><![CDATA[$this->colors]]></code>
@ -1448,6 +1446,7 @@
</PossiblyNullArgument>
<PossiblyUndefinedArrayOffset>
<code><![CDATA[$_SERVER['REQUEST_METHOD']]]></code>
<code><![CDATA[$_SERVER['REQUEST_METHOD']]]></code>
</PossiblyUndefinedArrayOffset>
<PossiblyUndefinedMethod>
<code>seek</code>
@ -2238,9 +2237,6 @@
<InaccessibleProperty>
<code><![CDATA[$this->udp]]></code>
</InaccessibleProperty>
<InvalidReturnType>
<code>?array</code>
</InvalidReturnType>
<MissingParamType>
<code>$stream</code>
</MissingParamType>

View File

@ -20,8 +20,10 @@ declare(strict_types=1);
namespace danog\MadelineProto;
use Amp\ByteStream\Pipe;
use Amp\ByteStream\WritableResourceStream;
use Amp\ByteStream\WritableStream;
use danog\Loop\Loop;
use danog\MadelineProto\Settings\Logger as SettingsLogger;
use Psr\Log\LoggerInterface;
use Revolt\EventLoop;
@ -39,8 +41,10 @@ use const PATHINFO_DIRNAME;
use const PHP_EOL;
use const PHP_SAPI;
use function Amp\async;
use function Amp\ByteStream\getStderr;
use function Amp\ByteStream\getStdout;
use function Amp\ByteStream\pipe;
/**
* Logger class.
@ -99,6 +103,15 @@ final class Logger
*
*/
private readonly WritableStream $stdout;
/**
* Unbuffered logfile.
*
*/
private readonly WritableStream $stdoutUnbuffered;
/**
* @var array<int, list{WritableStream, \Amp\Future}>
*/
private static array $closePromises = [];
/**
* Log rotation loop ID.
*/
@ -265,15 +278,15 @@ final class Logger
$this->colors[self::FATAL_ERROR] = \implode(';', [self::FOREGROUND['red'], self::SET['bold'], self::BACKGROUND['light_gray']]);
$this->newline = PHP_EOL;
if ($this->mode === self::ECHO_LOGGER) {
$this->stdout = getStdout();
$stdout = getStdout();
if (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg') {
$this->newline = '<br>'.$this->newline;
}
} elseif ($this->mode === self::FILE_LOGGER) {
$this->stdout = new WritableResourceStream(\fopen($this->optional, 'a'));
$stdout = new WritableResourceStream(\fopen($this->optional, 'a'));
if ($maxSize !== -1) {
$optional = $this->optional;
$stdout = $this->stdout;
$stdout = $stdout;
$this->rotateId = EventLoop::repeat(
10,
static function () use ($maxSize, $optional, $stdout): void {
@ -289,14 +302,29 @@ final class Logger
} elseif ($this->mode === self::DEFAULT_LOGGER) {
$result = @\ini_get('error_log');
if ($result === 'syslog') {
$this->stdout = getStderr();
$stdout = getStderr();
} elseif ($result) {
$this->stdout = new WritableResourceStream(\fopen($result, 'a+'));
$stdout = new WritableResourceStream(\fopen($result, 'a+'));
} else {
$this->stdout = getStderr();
$stdout = getStderr();
}
}
if (isset($stdout)) {
$pipe = new Pipe(PHP_INT_MAX);
$this->stdoutUnbuffered = $stdout;
$this->stdout = $pipe->getSink();
$source = $pipe->getSource();
$promise = async(static function () use ($source, $stdout, &$promise): void {
try {
pipe($source, $stdout);
} finally {
unset(self::$closePromises[\spl_object_id($promise)]);
}
});
self::$closePromises[\spl_object_id($promise)] = [$this->stdout, $promise];
}
self::$default = $this;
if (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg') {
try {
@ -326,8 +354,18 @@ final class Logger
public function truncate(): void
{
if ($this->mode === self::FILE_LOGGER) {
Assert::true($this->stdout instanceof WritableResourceStream);
\ftruncate($this->stdout->getResource(), 0);
Assert::true($this->stdoutUnbuffered instanceof WritableResourceStream);
\ftruncate($this->stdoutUnbuffered->getResource(), 0);
}
}
/**
* @internal Internal function used to flush the log buffer on shutdown.
*/
public static function finalize(): void
{
foreach (self::$closePromises as [$stdout, $promise]) {
$stdout->close();
$promise->await();
}
}
/**
@ -371,7 +409,7 @@ final class Logger
}
if ($this->mode === self::CALLABLE_LOGGER) {
\call_user_func_array($this->optional, [$param, $level]);
EventLoop::queue($this->optional, $param, $level);
return;
}
$prefix = $this->prefix;

View File

@ -73,6 +73,7 @@ final class Shutdown
}
API::finalize();
MTProto::serializeAll();
Logger::finalize();
if (\class_exists(Installer::class)) {
Installer::unlock();
}