mirror of
https://github.com/Seldaek/monolog.git
synced 2025-09-01 17:12:41 +02:00
Add method in Utils to convert memory values from php_ini into bytes, and use lower amount of chunk size based on memory limit
This commit is contained in:
@@ -25,8 +25,12 @@ use Monolog\Utils;
|
||||
*/
|
||||
class StreamHandler extends AbstractProcessingHandler
|
||||
{
|
||||
protected const MAX_CHUNK_SIZE = 2147483647;
|
||||
|
||||
/** @const int */
|
||||
const SAFE_MEMORY_OFFSET = 1024;
|
||||
/** @const int */
|
||||
const MAX_CHUNK_SIZE = 2147483647;
|
||||
/** @var int */
|
||||
protected $streamChunkSize = self::MAX_CHUNK_SIZE;
|
||||
/** @var resource|null */
|
||||
protected $stream;
|
||||
/** @var ?string */
|
||||
@@ -50,9 +54,26 @@ class StreamHandler extends AbstractProcessingHandler
|
||||
public function __construct($stream, $level = Logger::DEBUG, bool $bubble = true, ?int $filePermission = null, bool $useLocking = false)
|
||||
{
|
||||
parent::__construct($level, $bubble);
|
||||
|
||||
if ($phpMemoryLimit = ini_get('memory_limit')) {
|
||||
if (($memoryInByes = Utils::memoryIniValueToBytes($phpMemoryLimit))) {
|
||||
$memoryUsage = memory_get_usage(true);
|
||||
if (($memoryInByes - $memoryUsage) < $this->streamChunkSize) {
|
||||
$this->streamChunkSize = $memoryInByes - $memoryUsage - self::SAFE_MEMORY_OFFSET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_resource($stream)) {
|
||||
$this->stream = $stream;
|
||||
stream_set_chunk_size($this->stream, self::MAX_CHUNK_SIZE);
|
||||
|
||||
try {
|
||||
stream_set_chunk_size($this->stream, $this->streamChunkSize);
|
||||
} catch (\Exception $exception) {
|
||||
throw new \RuntimeException('Impossible to set the stream chunk size.'
|
||||
.PHP_EOL.'Error: '.$exception->getMessage()
|
||||
.PHP_EOL.'Trace: '.$exception->getTraceAsString());
|
||||
}
|
||||
} elseif (is_string($stream)) {
|
||||
$this->url = Utils::canonicalizePath($stream);
|
||||
} else {
|
||||
@@ -95,6 +116,14 @@ class StreamHandler extends AbstractProcessingHandler
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getStreamChunkSize() : int
|
||||
{
|
||||
return $this->streamChunkSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@@ -118,7 +147,7 @@ class StreamHandler extends AbstractProcessingHandler
|
||||
|
||||
throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened in append mode: '.$this->errorMessage, $url));
|
||||
}
|
||||
stream_set_chunk_size($stream, self::MAX_CHUNK_SIZE);
|
||||
stream_set_chunk_size($stream, $this->streamChunkSize);
|
||||
$this->stream = $stream;
|
||||
}
|
||||
|
||||
|
@@ -226,4 +226,52 @@ final class Utils
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string with a valid 'memory_limit' format, to bytes.
|
||||
* Reference: Function code from https://www.php.net/manual/en/function.ini-get.php
|
||||
* @param string|int $val
|
||||
* @return int|false Returns an integer representing bytes. Returns FALSE in case of error.
|
||||
*/
|
||||
public static function memoryIniValueToBytes($val)
|
||||
{
|
||||
if (!is_string($val) && !is_integer($val)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$val = trim((string)$val);
|
||||
|
||||
if (empty($val)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$valLen = strlen($val);
|
||||
$last = strtolower($val[$valLen - 1]);
|
||||
|
||||
if (preg_match('/[a-zA-Z]/', $last)) {
|
||||
if ($valLen == 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$val = substr($val, 0, -1);
|
||||
}
|
||||
|
||||
if (!is_numeric($val) || $val < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//Lets be explicit here
|
||||
$val = (int)($val);
|
||||
|
||||
switch ($last) {
|
||||
case 'g':
|
||||
$val *= 1024;
|
||||
case 'm':
|
||||
$val *= 1024;
|
||||
case 'k':
|
||||
$val *= 1024;
|
||||
}
|
||||
|
||||
return $val;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user