Mercurial > hg > isophonics-drupal-site
comparison core/lib/Drupal/Core/Logger/LoggerChannel.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | af1871eacc83 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Core\Logger; | |
4 | |
5 use Drupal\Core\Session\AccountInterface; | |
6 use Psr\Log\LoggerInterface; | |
7 use Psr\Log\LoggerTrait; | |
8 use Psr\Log\LogLevel; | |
9 use Symfony\Component\HttpFoundation\RequestStack; | |
10 | |
11 /** | |
12 * Defines a logger channel that most implementations will use. | |
13 */ | |
14 class LoggerChannel implements LoggerChannelInterface { | |
15 use LoggerTrait; | |
16 | |
17 /** | |
18 * Maximum call depth to self::log() for a single log message. | |
19 * | |
20 * It's very easy for logging channel code to call out to other library code | |
21 * that will create log messages. In that case, we will recurse back in to | |
22 * LoggerChannel::log() multiple times while processing a single originating | |
23 * message. To prevent infinite recursion, we track the call depth and bail | |
24 * out at LoggerChannel::MAX_CALL_DEPTH iterations. | |
25 * | |
26 * @var int | |
27 */ | |
28 const MAX_CALL_DEPTH = 5; | |
29 | |
30 /** | |
31 * Number of times LoggerChannel::log() has been called for a single message. | |
32 * | |
33 * @var int | |
34 */ | |
35 protected $callDepth = 0; | |
36 | |
37 /** | |
38 * The name of the channel of this logger instance. | |
39 * | |
40 * @var string | |
41 */ | |
42 protected $channel; | |
43 | |
44 /** | |
45 * Map of PSR3 log constants to RFC 5424 log constants. | |
46 * | |
47 * @var array | |
48 */ | |
49 protected $levelTranslation = [ | |
50 LogLevel::EMERGENCY => RfcLogLevel::EMERGENCY, | |
51 LogLevel::ALERT => RfcLogLevel::ALERT, | |
52 LogLevel::CRITICAL => RfcLogLevel::CRITICAL, | |
53 LogLevel::ERROR => RfcLogLevel::ERROR, | |
54 LogLevel::WARNING => RfcLogLevel::WARNING, | |
55 LogLevel::NOTICE => RfcLogLevel::NOTICE, | |
56 LogLevel::INFO => RfcLogLevel::INFO, | |
57 LogLevel::DEBUG => RfcLogLevel::DEBUG, | |
58 ]; | |
59 | |
60 /** | |
61 * An array of arrays of \Psr\Log\LoggerInterface keyed by priority. | |
62 * | |
63 * @var array | |
64 */ | |
65 protected $loggers = []; | |
66 | |
67 /** | |
68 * The request stack object. | |
69 * | |
70 * @var \Symfony\Component\HttpFoundation\RequestStack | |
71 */ | |
72 protected $requestStack; | |
73 | |
74 /** | |
75 * The current user object. | |
76 * | |
77 * @var \Drupal\Core\Session\AccountInterface | |
78 */ | |
79 protected $currentUser; | |
80 | |
81 /** | |
82 * Constructs a LoggerChannel object | |
83 * | |
84 * @param string $channel | |
85 * The channel name for this instance. | |
86 */ | |
87 public function __construct($channel) { | |
88 $this->channel = $channel; | |
89 } | |
90 | |
91 /** | |
92 * {@inheritdoc} | |
93 */ | |
94 public function log($level, $message, array $context = []) { | |
95 if ($this->callDepth == self::MAX_CALL_DEPTH) { | |
96 return; | |
97 } | |
98 $this->callDepth++; | |
99 | |
100 // Merge in defaults. | |
101 $context += [ | |
102 'channel' => $this->channel, | |
103 'link' => '', | |
104 'user' => NULL, | |
105 'uid' => 0, | |
106 'request_uri' => '', | |
107 'referer' => '', | |
108 'ip' => '', | |
109 'timestamp' => time(), | |
110 ]; | |
111 // Some context values are only available when in a request context. | |
112 if ($this->requestStack && $request = $this->requestStack->getCurrentRequest()) { | |
113 $context['request_uri'] = $request->getUri(); | |
114 $context['referer'] = $request->headers->get('Referer', ''); | |
115 $context['ip'] = $request->getClientIP(); | |
116 try { | |
117 if ($this->currentUser) { | |
118 $context['user'] = $this->currentUser; | |
119 $context['uid'] = $this->currentUser->id(); | |
120 } | |
121 } | |
122 catch (\Exception $e) { | |
123 // An exception might be thrown if the database connection is not | |
124 // available or due to another unexpected reason. It is more important | |
125 // to log the error that we already have so any additional exceptions | |
126 // are ignored. | |
127 } | |
128 } | |
129 | |
130 if (is_string($level)) { | |
131 // Convert to integer equivalent for consistency with RFC 5424. | |
132 $level = $this->levelTranslation[$level]; | |
133 } | |
134 // Call all available loggers. | |
135 foreach ($this->sortLoggers() as $logger) { | |
136 $logger->log($level, $message, $context); | |
137 } | |
138 | |
139 $this->callDepth--; | |
140 } | |
141 | |
142 /** | |
143 * {@inheritdoc} | |
144 */ | |
145 public function setRequestStack(RequestStack $requestStack = NULL) { | |
146 $this->requestStack = $requestStack; | |
147 } | |
148 | |
149 /** | |
150 * {@inheritdoc} | |
151 */ | |
152 public function setCurrentUser(AccountInterface $current_user = NULL) { | |
153 $this->currentUser = $current_user; | |
154 } | |
155 | |
156 /** | |
157 * {@inheritdoc} | |
158 */ | |
159 public function setLoggers(array $loggers) { | |
160 $this->loggers = $loggers; | |
161 } | |
162 | |
163 /** | |
164 * {@inheritdoc} | |
165 */ | |
166 public function addLogger(LoggerInterface $logger, $priority = 0) { | |
167 $this->loggers[$priority][] = $logger; | |
168 } | |
169 | |
170 /** | |
171 * Sorts loggers according to priority. | |
172 * | |
173 * @return array | |
174 * An array of sorted loggers by priority. | |
175 */ | |
176 protected function sortLoggers() { | |
177 $sorted = []; | |
178 krsort($this->loggers); | |
179 | |
180 foreach ($this->loggers as $loggers) { | |
181 $sorted = array_merge($sorted, $loggers); | |
182 } | |
183 return $sorted; | |
184 } | |
185 | |
186 } |