annotate vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php @ 0:c75dbcec494b

Initial commit from drush-created site
author Chris Cannam
date Thu, 05 Jul 2018 14:24:15 +0000
parents
children a9cd425dd02b
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /*
Chris@0 4 * This file is part of the Symfony package.
Chris@0 5 *
Chris@0 6 * (c) Fabien Potencier <fabien@symfony.com>
Chris@0 7 *
Chris@0 8 * For the full copyright and license information, please view the LICENSE
Chris@0 9 * file that was distributed with this source code.
Chris@0 10 */
Chris@0 11
Chris@0 12 namespace Symfony\Component\HttpKernel\DataCollector;
Chris@0 13
Chris@0 14 use Symfony\Component\Debug\Exception\SilencedErrorContext;
Chris@0 15 use Symfony\Component\HttpFoundation\Request;
Chris@0 16 use Symfony\Component\HttpFoundation\Response;
Chris@0 17 use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
Chris@0 18
Chris@0 19 /**
Chris@0 20 * LogDataCollector.
Chris@0 21 *
Chris@0 22 * @author Fabien Potencier <fabien@symfony.com>
Chris@0 23 */
Chris@0 24 class LoggerDataCollector extends DataCollector implements LateDataCollectorInterface
Chris@0 25 {
Chris@0 26 private $logger;
Chris@0 27 private $containerPathPrefix;
Chris@0 28
Chris@0 29 public function __construct($logger = null, $containerPathPrefix = null)
Chris@0 30 {
Chris@0 31 if (null !== $logger && $logger instanceof DebugLoggerInterface) {
Chris@0 32 if (!method_exists($logger, 'clear')) {
Chris@0 33 @trigger_error(sprintf('Implementing "%s" without the "clear()" method is deprecated since Symfony 3.4 and will be unsupported in 4.0 for class "%s".', DebugLoggerInterface::class, \get_class($logger)), E_USER_DEPRECATED);
Chris@0 34 }
Chris@0 35
Chris@0 36 $this->logger = $logger;
Chris@0 37 }
Chris@0 38
Chris@0 39 $this->containerPathPrefix = $containerPathPrefix;
Chris@0 40 }
Chris@0 41
Chris@0 42 /**
Chris@0 43 * {@inheritdoc}
Chris@0 44 */
Chris@0 45 public function collect(Request $request, Response $response, \Exception $exception = null)
Chris@0 46 {
Chris@0 47 // everything is done as late as possible
Chris@0 48 }
Chris@0 49
Chris@0 50 /**
Chris@0 51 * {@inheritdoc}
Chris@0 52 */
Chris@0 53 public function reset()
Chris@0 54 {
Chris@0 55 if ($this->logger && method_exists($this->logger, 'clear')) {
Chris@0 56 $this->logger->clear();
Chris@0 57 }
Chris@0 58 $this->data = array();
Chris@0 59 }
Chris@0 60
Chris@0 61 /**
Chris@0 62 * {@inheritdoc}
Chris@0 63 */
Chris@0 64 public function lateCollect()
Chris@0 65 {
Chris@0 66 if (null !== $this->logger) {
Chris@0 67 $containerDeprecationLogs = $this->getContainerDeprecationLogs();
Chris@0 68 $this->data = $this->computeErrorsCount($containerDeprecationLogs);
Chris@0 69 $this->data['compiler_logs'] = $this->getContainerCompilerLogs();
Chris@0 70 $this->data['logs'] = $this->sanitizeLogs(array_merge($this->logger->getLogs(), $containerDeprecationLogs));
Chris@0 71 $this->data = $this->cloneVar($this->data);
Chris@0 72 }
Chris@0 73 }
Chris@0 74
Chris@0 75 /**
Chris@0 76 * Gets the logs.
Chris@0 77 *
Chris@0 78 * @return array An array of logs
Chris@0 79 */
Chris@0 80 public function getLogs()
Chris@0 81 {
Chris@0 82 return isset($this->data['logs']) ? $this->data['logs'] : array();
Chris@0 83 }
Chris@0 84
Chris@0 85 public function getPriorities()
Chris@0 86 {
Chris@0 87 return isset($this->data['priorities']) ? $this->data['priorities'] : array();
Chris@0 88 }
Chris@0 89
Chris@0 90 public function countErrors()
Chris@0 91 {
Chris@0 92 return isset($this->data['error_count']) ? $this->data['error_count'] : 0;
Chris@0 93 }
Chris@0 94
Chris@0 95 public function countDeprecations()
Chris@0 96 {
Chris@0 97 return isset($this->data['deprecation_count']) ? $this->data['deprecation_count'] : 0;
Chris@0 98 }
Chris@0 99
Chris@0 100 public function countWarnings()
Chris@0 101 {
Chris@0 102 return isset($this->data['warning_count']) ? $this->data['warning_count'] : 0;
Chris@0 103 }
Chris@0 104
Chris@0 105 public function countScreams()
Chris@0 106 {
Chris@0 107 return isset($this->data['scream_count']) ? $this->data['scream_count'] : 0;
Chris@0 108 }
Chris@0 109
Chris@0 110 public function getCompilerLogs()
Chris@0 111 {
Chris@0 112 return isset($this->data['compiler_logs']) ? $this->data['compiler_logs'] : array();
Chris@0 113 }
Chris@0 114
Chris@0 115 /**
Chris@0 116 * {@inheritdoc}
Chris@0 117 */
Chris@0 118 public function getName()
Chris@0 119 {
Chris@0 120 return 'logger';
Chris@0 121 }
Chris@0 122
Chris@0 123 private function getContainerDeprecationLogs()
Chris@0 124 {
Chris@0 125 if (null === $this->containerPathPrefix || !file_exists($file = $this->containerPathPrefix.'Deprecations.log')) {
Chris@0 126 return array();
Chris@0 127 }
Chris@0 128
Chris@0 129 $bootTime = filemtime($file);
Chris@0 130 $logs = array();
Chris@0 131 foreach (unserialize(file_get_contents($file)) as $log) {
Chris@0 132 $log['context'] = array('exception' => new SilencedErrorContext($log['type'], $log['file'], $log['line'], $log['trace'], $log['count']));
Chris@0 133 $log['timestamp'] = $bootTime;
Chris@0 134 $log['priority'] = 100;
Chris@0 135 $log['priorityName'] = 'DEBUG';
Chris@0 136 $log['channel'] = '-';
Chris@0 137 $log['scream'] = false;
Chris@0 138 unset($log['type'], $log['file'], $log['line'], $log['trace'], $log['trace'], $log['count']);
Chris@0 139 $logs[] = $log;
Chris@0 140 }
Chris@0 141
Chris@0 142 return $logs;
Chris@0 143 }
Chris@0 144
Chris@0 145 private function getContainerCompilerLogs()
Chris@0 146 {
Chris@0 147 if (null === $this->containerPathPrefix || !file_exists($file = $this->containerPathPrefix.'Compiler.log')) {
Chris@0 148 return array();
Chris@0 149 }
Chris@0 150
Chris@0 151 $logs = array();
Chris@0 152 foreach (file($file, FILE_IGNORE_NEW_LINES) as $log) {
Chris@0 153 $log = explode(': ', $log, 2);
Chris@0 154 if (!isset($log[1]) || !preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)++$/', $log[0])) {
Chris@0 155 $log = array('Unknown Compiler Pass', implode(': ', $log));
Chris@0 156 }
Chris@0 157
Chris@0 158 $logs[$log[0]][] = array('message' => $log[1]);
Chris@0 159 }
Chris@0 160
Chris@0 161 return $logs;
Chris@0 162 }
Chris@0 163
Chris@0 164 private function sanitizeLogs($logs)
Chris@0 165 {
Chris@0 166 $sanitizedLogs = array();
Chris@0 167 $silencedLogs = array();
Chris@0 168
Chris@0 169 foreach ($logs as $log) {
Chris@0 170 if (!$this->isSilencedOrDeprecationErrorLog($log)) {
Chris@0 171 $sanitizedLogs[] = $log;
Chris@0 172
Chris@0 173 continue;
Chris@0 174 }
Chris@0 175
Chris@0 176 $message = $log['message'];
Chris@0 177 $exception = $log['context']['exception'];
Chris@0 178
Chris@0 179 if ($exception instanceof SilencedErrorContext) {
Chris@0 180 if (isset($silencedLogs[$h = spl_object_hash($exception)])) {
Chris@0 181 continue;
Chris@0 182 }
Chris@0 183 $silencedLogs[$h] = true;
Chris@0 184
Chris@0 185 if (!isset($sanitizedLogs[$message])) {
Chris@0 186 $sanitizedLogs[$message] = $log + array(
Chris@0 187 'errorCount' => 0,
Chris@0 188 'scream' => true,
Chris@0 189 );
Chris@0 190 }
Chris@0 191 $sanitizedLogs[$message]['errorCount'] += $exception->count;
Chris@0 192
Chris@0 193 continue;
Chris@0 194 }
Chris@0 195
Chris@0 196 $errorId = md5("{$exception->getSeverity()}/{$exception->getLine()}/{$exception->getFile()}\0{$message}", true);
Chris@0 197
Chris@0 198 if (isset($sanitizedLogs[$errorId])) {
Chris@0 199 ++$sanitizedLogs[$errorId]['errorCount'];
Chris@0 200 } else {
Chris@0 201 $log += array(
Chris@0 202 'errorCount' => 1,
Chris@0 203 'scream' => false,
Chris@0 204 );
Chris@0 205
Chris@0 206 $sanitizedLogs[$errorId] = $log;
Chris@0 207 }
Chris@0 208 }
Chris@0 209
Chris@0 210 return array_values($sanitizedLogs);
Chris@0 211 }
Chris@0 212
Chris@0 213 private function isSilencedOrDeprecationErrorLog(array $log)
Chris@0 214 {
Chris@0 215 if (!isset($log['context']['exception'])) {
Chris@0 216 return false;
Chris@0 217 }
Chris@0 218
Chris@0 219 $exception = $log['context']['exception'];
Chris@0 220
Chris@0 221 if ($exception instanceof SilencedErrorContext) {
Chris@0 222 return true;
Chris@0 223 }
Chris@0 224
Chris@0 225 if ($exception instanceof \ErrorException && in_array($exception->getSeverity(), array(E_DEPRECATED, E_USER_DEPRECATED), true)) {
Chris@0 226 return true;
Chris@0 227 }
Chris@0 228
Chris@0 229 return false;
Chris@0 230 }
Chris@0 231
Chris@0 232 private function computeErrorsCount(array $containerDeprecationLogs)
Chris@0 233 {
Chris@0 234 $silencedLogs = array();
Chris@0 235 $count = array(
Chris@0 236 'error_count' => $this->logger->countErrors(),
Chris@0 237 'deprecation_count' => 0,
Chris@0 238 'warning_count' => 0,
Chris@0 239 'scream_count' => 0,
Chris@0 240 'priorities' => array(),
Chris@0 241 );
Chris@0 242
Chris@0 243 foreach ($this->logger->getLogs() as $log) {
Chris@0 244 if (isset($count['priorities'][$log['priority']])) {
Chris@0 245 ++$count['priorities'][$log['priority']]['count'];
Chris@0 246 } else {
Chris@0 247 $count['priorities'][$log['priority']] = array(
Chris@0 248 'count' => 1,
Chris@0 249 'name' => $log['priorityName'],
Chris@0 250 );
Chris@0 251 }
Chris@0 252 if ('WARNING' === $log['priorityName']) {
Chris@0 253 ++$count['warning_count'];
Chris@0 254 }
Chris@0 255
Chris@0 256 if ($this->isSilencedOrDeprecationErrorLog($log)) {
Chris@0 257 $exception = $log['context']['exception'];
Chris@0 258 if ($exception instanceof SilencedErrorContext) {
Chris@0 259 if (isset($silencedLogs[$h = spl_object_hash($exception)])) {
Chris@0 260 continue;
Chris@0 261 }
Chris@0 262 $silencedLogs[$h] = true;
Chris@0 263 $count['scream_count'] += $exception->count;
Chris@0 264 } else {
Chris@0 265 ++$count['deprecation_count'];
Chris@0 266 }
Chris@0 267 }
Chris@0 268 }
Chris@0 269
Chris@0 270 foreach ($containerDeprecationLogs as $deprecationLog) {
Chris@0 271 $count['deprecation_count'] += $deprecationLog['context']['exception']->count;
Chris@0 272 }
Chris@0 273
Chris@0 274 ksort($count['priorities']);
Chris@0 275
Chris@0 276 return $count;
Chris@0 277 }
Chris@0 278 }