]> git.mxchange.org Git - friendica.git/blob - src/Core/Logger/Util/Introspection.php
Use the owner, not the author
[friendica.git] / src / Core / Logger / Util / Introspection.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2023, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Core\Logger\Util;
23
24 use Friendica\App\Request;
25 use Friendica\Core\Logger\Capability\IHaveCallIntrospections;
26
27 /**
28  * Get Introspection information about the current call
29  */
30 class Introspection implements IHaveCallIntrospections
31 {
32         /** @var string */
33         private $requestId;
34
35         /** @var int  */
36         private $skipStackFramesCount;
37
38         /** @var string[] */
39         private $skipClassesPartials;
40
41         private $skipFunctions = [
42                 'call_user_func',
43                 'call_user_func_array',
44         ];
45
46         /**
47          * @param string[] $skipClassesPartials  An array of classes to skip during logging
48          * @param int      $skipStackFramesCount If the logger should use information from other hierarchy levels of the call
49          */
50         public function __construct(Request $request, array $skipClassesPartials = [], int $skipStackFramesCount = 0)
51         {
52                 $this->requestId            = $request->getRequestId();
53                 $this->skipClassesPartials  = $skipClassesPartials;
54                 $this->skipStackFramesCount = $skipStackFramesCount;
55         }
56
57         /**
58          * Adds new classes to get skipped
59          *
60          * @param array $classNames
61          */
62         public function addClasses(array $classNames): void
63         {
64                 $this->skipClassesPartials = array_merge($this->skipClassesPartials, $classNames);
65         }
66
67         /**
68          * Returns the introspection record of the current call
69          *
70          * @return array
71          */
72         public function getRecord(): array
73         {
74                 $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
75
76                 $i = 1;
77
78                 while ($this->isTraceClassOrSkippedFunction($trace[$i] ?? [])) {
79                         $i++;
80                 }
81
82                 $i += $this->skipStackFramesCount;
83
84                 return [
85                         'file'       => isset($trace[$i - 1]['file']) ? basename($trace[$i - 1]['file']) : null,
86                         'line'       => $trace[$i - 1]['line'] ?? null,
87                         'function'   => $trace[$i]['function'] ?? null,
88                         'request-id' => $this->requestId,
89                 ];
90         }
91
92         /**
93          * Checks if the current trace class or function has to be skipped
94          *
95          * @param array $traceItem The current trace item
96          *
97          * @return bool True if the class or function should get skipped, otherwise false
98          */
99         private function isTraceClassOrSkippedFunction(array $traceItem): bool
100         {
101                 if (!$traceItem) {
102                         return false;
103                 }
104
105                 if (isset($traceItem['class'])) {
106                         foreach ($this->skipClassesPartials as $part) {
107                                 if (strpos($traceItem['class'], $part) === 0) {
108                                         return true;
109                                 }
110                         }
111                 } elseif (in_array($traceItem['function'], $this->skipFunctions)) {
112                         return true;
113                 }
114
115                 return false;
116         }
117 }