[FEATURE] Add Log Module to AdminPanel
[Packages/TYPO3.CMS.git] / typo3 / sysext / adminpanel / Classes / Log / InMemoryLogWriter.php
1 <?php
2 declare(strict_types = 1);
3
4 namespace TYPO3\CMS\Adminpanel\Log;
5
6 /*
7 * This file is part of the TYPO3 CMS project.
8 *
9 * It is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License, either version 2
11 * of the License, or any later version.
12 *
13 * For the full copyright and license information, please read the
14 * LICENSE.txt file that was distributed with this source code.
15 *
16 * The TYPO3 project - inspiring people to share!
17 */
18
19 use TYPO3\CMS\Core\Log\LogLevel;
20 use TYPO3\CMS\Core\Log\LogRecord;
21 use TYPO3\CMS\Core\Log\Writer\AbstractWriter;
22 use TYPO3\CMS\Core\Utility\GeneralUtility;
23
24 /**
25 * Log writer that writes the log records into a static public class variable
26 * for InMemory processing
27 */
28 class InMemoryLogWriter extends AbstractWriter
29 {
30 public static $log = [];
31
32 private const MINIMAL_PERCENT_OF_FREE_MEMORY = 0.30;
33
34 private static $memoryLock = false;
35
36 /**
37 * Writes the log record
38 *
39 * @param LogRecord $record Log record
40 * @return self
41 * @throws \RuntimeException
42 */
43 public function writeLog(LogRecord $record): self
44 {
45 // Guard: Locked Writer
46 if (self::$memoryLock === true) {
47 return $this;
48 }
49
50 // Guard: Memory Usage
51 if (!self::$memoryLock && $this->isMemoryConsumptionTooHigh()) {
52 $this->lockWriter();
53 return $this;
54 }
55
56 self::$log[] = $record;
57
58 return $this;
59 }
60
61 /**
62 * Checks memory usage used in current process - this is no guarantee for not running out of memory
63 * but should prevent memory exhaustion due to the InMemoryLogger in most cases.
64 *
65 * The logger will stop logging once the amount of free memory falls below the threshold (see
66 * MINIMAL_PERCENT_OF_FREE_MEMORY const).
67 *
68 * @return bool
69 */
70 protected function isMemoryConsumptionTooHigh(): bool
71 {
72 $iniLimit = ini_get('memory_limit');
73 $memoryLimit = $iniLimit === '-1' ? -1 : GeneralUtility::getBytesFromSizeMeasurement($iniLimit);
74 $freeMemory = $memoryLimit - memory_get_usage(true);
75
76 return $memoryLimit > 0 && $freeMemory < (self::MINIMAL_PERCENT_OF_FREE_MEMORY * $memoryLimit);
77 }
78
79 /**
80 * Lock writer and add a info message that there may potentially be more entries.
81 */
82 protected function lockWriter(): void
83 {
84 self::$memoryLock = true;
85 /** @var LogRecord $record */
86 $record = GeneralUtility::makeInstance(
87 LogRecord::class,
88 'TYPO3.CMS.AdminPanel.Log.InMemoryLogWriter',
89 LogLevel::INFO,
90 '... Further log entries omitted, memory usage too high.'
91 );
92 self::$log[] = $record;
93 }
94 }