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 }