403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /home/bitrix/ext_www/cvetdv.ru/bitrix/modules/yandex.market/lib/logger/reference/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/cvetdv.ru/bitrix/modules/yandex.market/lib/logger/reference/logger.php
<?php
namespace Yandex\Market\Logger\Reference;

use Yandex\Market\Result;
use Yandex\Market\Psr;
use Yandex\Market\Data\Type\CanonicalDateTime;
use Yandex\Market\Config;
use Yandex\Market\Reference\Storage;
use Yandex\Market\Logger\Level;
use Bitrix\Main;

abstract class Logger extends Psr\Log\AbstractLogger
{
	protected $level = Level::WARNING;
	protected $canTouchRows = true;
	protected $additionalGroupKeys = [];
	private $allowBatch = false;
	private $allowCheckExists = false;
	private $checkExistsFilter;
	private $allowRelease = false;
	private $elements = [];
	private $queue = [];
	private $context = [];
	private $chunkSize;

	public function __construct()
	{
		$this->chunkSize = max(1, (int)Config::getOption('log_flush_chunk_size', 100));
	}

	public function __destruct()
	{
		$this->flush();
	}

	/** @return class-string<Storage\Table> */
	abstract public function getDataClass();

	public function setLevel($level)
	{
		$this->level = (string)$level;
	}

	public function log($level, $message, array $context = [])
	{
		if (!Level::isMatch($this->level, $level))
		{
			if (isset($context['ENTITY_TYPE'], $context['ENTITY_ID']))
			{
				$this->registerElement($context['ENTITY_TYPE'], $context['ENTITY_ID']);
			}

			return;
		}

		$parsedMessage = $this->parseMessage($message);
		$context = $this->extendContext($message, $context);
		$context += $this->context;

		$row = $this->createRow($level, $parsedMessage, $context);

		$this->queue($row);
	}

	protected function parseMessage($message)
	{
		/**
		 * @noinspection PhpConditionCheckedByNextConditionInspection
		 * @noinspection PhpElementIsNotAvailableInCurrentPhpVersionInspection
		 * @noinspection NotOptimalIfConditionsInspection
		 */
		if ($message instanceof \Exception || $message instanceof \Throwable || $message instanceof Main\Error)
		{
			$errorCode = $message->getCode();
			$result = $message->getMessage() . (!empty($errorCode) ? ' #' . $errorCode : '');
		}
		else if ($message instanceof Main\Result || $message instanceof Result\Base)
		{
			$result = implode(PHP_EOL, $message->getErrorMessages());
		}
		else if (!is_scalar($message))
		{
			$result = print_r($message, true);
		}
		else
		{
			$result = (string)$message;
		}

		return $result;
	}

	public function resetContext(array $context)
	{
		$this->context = $context;
	}

	public function getFullContext()
	{
		return $this->context;
	}

	public function getContext($name)
	{
		return isset($this->context[$name]) ? $this->context[$name] : null;
	}

	public function setContext($name, $key)
	{
		$this->context[$name] = $key;
	}

	public function releaseContext()
	{
		$this->context = [];
	}

	/**
	 * @noinspection PhpElementIsNotAvailableInCurrentPhpVersionInspection
	 * @noinspection PhpConditionCheckedByNextConditionInspection
	 */
	protected function extendContext($message, $context)
	{
		if (
			($message instanceof \Exception || $message instanceof \Throwable)
			&& $this->isTracingOn()
		)
		{
			$context['TRACE'] = Main\Diag\ExceptionHandlerFormatter::format($message);
		}

		return $context;
	}

	protected function isTracingOn()
	{
		return true;
	}

	private function createRow($level, $message, array $context = [])
	{
		$row = $this->getRowDefaults() + [
			'TIMESTAMP_X' => new CanonicalDateTime(),
			'LEVEL' => $level,
			'MESSAGE' => $message,
		];
		$row = $this->passContextFields($row, $context);

		return $row;
	}

	protected function getContextFields()
	{
		return [];
	}

	protected function getRowDefaults()
	{
		return [];
	}

	private function passContextFields(array $row, array $context)
	{
		foreach ($this->getContextFields() as $name)
		{
			if (array_key_exists($name, $context))
			{
				$row[$name] = (string)$context[$name];
				unset($context[$name]);
			}
			else if (!isset($row[$name]))
			{
				$row[$name] = '';
			}
		}

		$row['CONTEXT'] = !empty($context) ? $context : null;

		return $row;
	}

	public function allowBatch()
	{
		$this->allowBatch = true;
	}

	/** @noinspection PhpUnused */
	public function disallowBatch()
	{
		$this->allowBatch = false;
	}

	public function allowCheckExists(array $filter = null)
	{
		$this->allowCheckExists = true;
		$this->checkExistsFilter = $filter;
	}

	/** @noinspection PhpUnused */
	public function disallowCheckExists()
	{
		$this->allowCheckExists = false;
	}

	public function allowRelease()
	{
		$this->allowRelease = true;
	}

	/** @noinspection PhpUnused */
	public function disallowRelease()
	{
		$this->allowRelease = false;
	}

	public function firstElement()
	{
		foreach ($this->elements as $entityType => $entityIds)
		{
			if (empty($entityIds)) { continue; }

			return [
				'ENTITY_TYPE' => $entityType,
				'ENTITY_ID' => reset($entityIds),
			];
		}

		return null;
	}

	public function registerElements($entityType, array $entityIds)
	{
		if (empty($entityIds)) { return; }

		if (!isset($this->elements[$entityType]))
		{
			$this->elements[$entityType] = [];
		}

		array_push($this->elements[$entityType], ...$entityIds);
	}

	public function registerElement($entityType, $entityId)
	{
		if (!isset($this->elements[$entityType]))
		{
			$this->elements[$entityType] = [];
		}

		$this->elements[$entityType][] = $entityId;
	}

	public function flush()
	{
		$queue = $this->queue;
		$elements = $this->elements;
		$this->queue = [];
		$this->elements = [];

		$this->write($queue, $elements);
	}

	private function queue(array $row)
	{
		if (!$this->allowBatch)
		{
			$elements = $this->elements;
			$this->elements = [];

			$this->write([ $row ], $elements);
			return;
		}

		$this->queue[] = $row;
	}

	private function write(array $rows, array $knownElements = null)
	{
		if ($this->allowCheckExists)
		{
			list($newRows, $updateIds, $deleteIds) = $this->splitExists($rows, $knownElements);

			$this->tableAdd($newRows);
			$this->tableUpdate($updateIds);
			$this->tableDelete($deleteIds);
			return;
		}

		$this->tableAdd($rows);
	}

	private function splitExists(array $rows, array $knownElements = null)
	{
		$exists = $this->tableExists($rows, $knownElements);
		$found = [];
		$deleteIds = [];

		foreach ($rows as $key => $row)
		{
			$groupKey = $this->rowGroupKey($row);

			if (!isset($exists[$groupKey])) { continue; }

			$id = array_search((string)$row['MESSAGE'], $exists[$groupKey], true);

			if ($id === false) { continue; }

			$found[$id] = true;
			unset($rows[$key]);
		}

		if ($this->allowRelease)
		{
			foreach ($exists as $group)
			{
				foreach ($group as $id => $message)
				{
					if (isset($found[$id])) { continue; }

					$deleteIds[] = $id;
				}
			}
		}

		return [ $rows, array_keys($found), $deleteIds ];
	}

	private function tableExists(array $rows, array $knownElements = null)
	{
		$rows = array_filter($rows, static function(array $row) { return $row['LEVEL'] !== Level::DEBUG; });
		$elementFilter = $this->existsElementFilter($this->rowsEntityGroups($rows, $knownElements));

		if ($elementFilter === null) { return []; }

		$result = [];
		$filter = $this->existsCommonFilter($rows);

		if ($this->checkExistsFilter !== null)
		{
			$filter = array_diff_key($filter, $this->checkExistsFilter) + $this->checkExistsFilter;
		}

		$filter[] = $elementFilter;

		$dataClass = $this->getDataClass();
		$query = $dataClass::getList([
			'filter' => $filter,
			'select' => array_merge($this->additionalGroupKeys, [
				'ID',
				'ENTITY_TYPE',
				'ENTITY_ID',
				'LEVEL',
				'MESSAGE',
			]),
		]);

		while ($row = $query->fetch())
		{
			$groupKey = $this->rowGroupKey($row);

			if (!isset($result[$groupKey])) { $result[$groupKey] = []; }

			$result[$groupKey][$row['ID']] = (string)$row['MESSAGE'];
		}

		return $result;
	}

	private function rowGroupKey(array $row)
	{
		$groupKey = "{$row['ENTITY_TYPE']}:{$row['ENTITY_ID']}:{$row['LEVEL']}";

		foreach ($this->additionalGroupKeys as $fieldKey)
		{
			$groupKey .= ':' . (isset($row[$fieldKey]) ? (string)$row[$fieldKey] : '');
		}

		return $groupKey;
	}

	abstract protected function existsCommonFilter(array $rows);

	private function rowsEntityGroups(array $rows, array $knownElements = null)
	{
		$known = $this->allowRelease && $knownElements !== null ? $knownElements : [];
		$result = $known;

		foreach ($rows as $row)
		{
			if (!isset($row['ENTITY_ID']) || (string)$row['ENTITY_ID'] === '' || isset($known[$row['ENTITY_TYPE']])) { continue; }

			if (!isset($result[$row['ENTITY_TYPE']]))
			{
				$result[$row['ENTITY_TYPE']] = [];
			}

			$result[$row['ENTITY_TYPE']][] = (string)$row['ENTITY_ID'];
		}

		return $result;
	}

	private function existsElementFilter(array $entityGroups)
	{
		$partials = [];

		foreach ($entityGroups as $entityType => $entityIds)
		{
			$partials[] = [
				'=ENTITY_TYPE' => $entityType,
				'=ENTITY_ID' => $entityIds,
			];
		}

		if (empty($partials)) { return null; }

		if (count($partials) === 1)
		{
			return $partials[0];
		}

		return [ 'LOGIC' => 'OR' ] + $partials;
	}

	private function tableAdd(array $rows)
	{
		foreach (array_chunk($rows, $this->chunkSize) as $chunk)
		{
			$dataClass = $this->getDataClass();
			$dataClass::addBatch($chunk);
		}
	}

	private function tableUpdate(array $ids)
	{
		if (!$this->canTouchRows) { return; }

		foreach (array_chunk($ids, $this->chunkSize) as $chunk)
		{
			$dataClass = $this->getDataClass();
			$dataClass::updateBatch([
				'filter' => [ '=ID' => $chunk ],
			], [
				'TIMESTAMP_X' => new CanonicalDateTime(),
			]);
		}
	}

	private function tableDelete(array $ids)
	{
		foreach (array_chunk($ids, $this->chunkSize) as $chunk)
		{
			$dataClass = $this->getDataClass();
			$dataClass::deleteBatch([
				'filter' => [ '=ID' => $chunk ],
			]);
		}
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit