c4077a3f2ad4dd71a1e75293210d14e7dabe21d6
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Log / Processor / IntrospectionProcessor.php
1 <?php
2 namespace TYPO3\CMS\Core\Log\Processor;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 /**
18 * Introspection processor to automatically add where the log record came from.
19 *
20 * @author Ingo Renner <ingo@typo3.org>
21 */
22 class IntrospectionProcessor extends AbstractProcessor {
23
24 /**
25 * Add the full backtrace to the log entry or
26 * just the last entry of the backtrace
27 *
28 * @var bool
29 */
30 protected $appendFullBackTrace = FALSE;
31
32 /**
33 * Number of entries to shift from the backtrace
34 *
35 * @var int
36 */
37 protected $shiftBackTraceLevel = 0;
38
39 /**
40 * Temporary storage of the preceding backtrace line number
41 *
42 * @var string
43 */
44 private $precedingBacktraceLine = '';
45
46 /**
47 * Temporary storage of the preceding backtrace file
48 *
49 * @var string
50 */
51 private $precedingBacktraceFile = '';
52
53 /**
54 * Set the number of levels to be shift from the backtrace
55 *
56 * @param int $shiftBackTraceLevel Numbers of levels to shift
57 * @return \TYPO3\CMS\Core\Log\Writer\AbstractWriter
58 */
59 public function setShiftBackTraceLevel($shiftBackTraceLevel) {
60 $this->shiftBackTraceLevel = (int)$shiftBackTraceLevel;
61 return $this;
62 }
63
64 /**
65 * Set if the full backtrace should be added to the log or just the last item
66 *
67 * @param bool $appendFullBackTrace If the full backtrace should be added
68 * @return \TYPO3\CMS\Core\Log\Writer\AbstractWriter
69 */
70 public function setAppendFullBackTrace($appendFullBackTrace) {
71 $this->appendFullBackTrace = (bool)$appendFullBackTrace;
72 return $this;
73 }
74
75
76 /**
77 * Add debug backtrace information to logRecord
78 * It adds: filepath, line number, class and function name
79 *
80 * @param \TYPO3\CMS\Core\Log\LogRecord $logRecord The log record to process
81 * @return \TYPO3\CMS\Core\Log\LogRecord The processed log record with additional data
82 * @see debug_backtrace()
83 */
84 public function processLogRecord(\TYPO3\CMS\Core\Log\LogRecord $logRecord) {
85 $trace = $this->getDebugBacktrace();
86
87 // skip TYPO3\CMS\Core\Log classes
88 foreach ($trace as $traceEntry) {
89 if (isset($traceEntry['class']) && FALSE !== strpos($traceEntry['class'], \TYPO3\CMS\Core\Log::class)) {
90 $trace = $this->shiftBacktraceLevel($trace);
91 } else {
92 break;
93 }
94 }
95
96 // shift a given number of entries from the trace
97 for($i = 0; $i < $this->shiftBackTraceLevel; $i++) {
98 // shift only if afterwards there is at least one entry left after.
99 if (count($trace) > 1) {
100 $trace = $this->shiftBacktraceLevel($trace);
101 }
102 }
103
104 if ($this->appendFullBackTrace) {
105 // Add the line and file of the last entry that has these information
106 // to the first backtrace entry if it does not have this information.
107 // This is required in case we have shifted entries and the first entry
108 // is now a call_user_func that does not contain the line and file information.
109 if (!isset($trace[0]['line'])) {
110 $trace[0] = array('line' => $this->precedingBacktraceLine) + $trace[0];
111 }
112 if (!isset($trace[0]['file'])) {
113 $trace[0] = array('file' => $this->precedingBacktraceFile) + $trace[0];
114 }
115
116 $logRecord->addData(array(
117 'backtrace' => $trace
118 ));
119 } else {
120 $logRecord->addData(array(
121 'file' => isset($trace[0]['file']) ? $trace[0]['file'] : NULL,
122 'line' => isset($trace[0]['line']) ? $trace[0]['line'] : NULL,
123 'class' => isset($trace[0]['class']) ? $trace[0]['class'] : NULL,
124 'function' => isset($trace[0]['function']) ? $trace[0]['function'] : NULL
125 ));
126 }
127
128 return $logRecord;
129 }
130
131 /**
132 * Shift the first item from the backtrace
133 *
134 * @param array $backtrace
135 * @return array
136 */
137 protected function shiftBacktraceLevel(array $backtrace) {
138 if (isset($backtrace[0]['file'])) {
139 $this->precedingBacktraceFile = $backtrace[0]['file'];
140 }
141 if (isset($backtrace[0]['line'])) {
142 $this->precedingBacktraceLine = $backtrace[0]['line'];
143 }
144 array_shift($backtrace);
145
146 return $backtrace;
147 }
148
149 /**
150 * Get the debug backtrace
151 *
152 * @return array
153 */
154 protected function getDebugBacktrace() {
155 return debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
156 }
157
158 }