ILIAS  release_10 Revision v10.1-43-ga1241a92c2f
class.ilLoggerFactory.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
22 use Monolog\Logger;
31 
39 {
40  protected const DEFAULT_FORMAT = "[%suid%] [%datetime%] %channel%.%level_name%: %message% %context% %extra%\n";
41 
42  protected const ROOT_LOGGER = 'root';
43  protected const COMPONENT_ROOT = 'log_root';
44  protected const SETUP_LOGGER = 'setup';
45 
46  private static ?ilLoggerFactory $instance = null;
47 
49  protected Container $dic;
50 
51  private bool $enabled = false; //ToDo PHP8 Review: This is a private var never read only written and should probably be removed.
52 
56  private array $loggers = array();
57 
58  protected function __construct(ilLoggingSettings $settings)
59  {
60  global $DIC;
61 
62  $this->dic = $DIC;
63  $this->settings = $settings;
64  $this->enabled = $this->getSettings()->isEnabled();
65  }
66 
67  public static function getInstance(): ilLoggerFactory
68  {
69  if (!static::$instance instanceof ilLoggerFactory) {
71  static::$instance = new ilLoggerFactory($settings);
72  }
73  return static::$instance;
74  }
75 
76  public static function newInstance(ilLoggingSettings $settings): ilLoggerFactory
77  {
78  return static::$instance = new self($settings);
79  }
80 
81  public function isLoggingEnabled(): bool
82  {
83  return $this->enabled;
84  }
85 
86 
90  public static function getLogger(string $a_component_id): ilLogger
91  {
92  $factory = self::getInstance();
93  return $factory->getComponentLogger($a_component_id);
94  }
95 
99  public static function getRootLogger(): ilLogger
100  {
101  $factory = self::getInstance();
102  return $factory->getComponentLogger(self::ROOT_LOGGER);
103  }
104 
105 
109  public function initUser(string $a_login): void
110  {
111  if (!$this->getSettings()->isBrowserLogEnabledForUser($a_login)) {
112  return;
113  }
114 
115  foreach ($this->loggers as $a_component_id => $logger) {
116  if ($this->isConsoleAvailable()) {
117  $browser_handler = new BrowserConsoleHandler();
118  $browser_handler->setLevel($this->getSettings()->getLevelByComponent($a_component_id));
119  $browser_handler->setFormatter(new ilLineFormatter(static::DEFAULT_FORMAT, 'Y-m-d H:i:s.u', true, true));
120  $logger->getLogger()->pushHandler($browser_handler);
121  }
122  }
123  }
124 
128  protected function isConsoleAvailable(): bool
129  {
131  return false;
132  }
133  if (
134  $this->dic->isDependencyAvailable('ctrl') && $this->dic->ctrl()->isAsynch() ||
135  (
136  $this->dic->isDependencyAvailable('http') &&
137  strtolower($this->dic->http()->request()->getServerParams()['HTTP_X_REQUESTED_WITH'] ?? '') === 'xmlhttprequest'
138  )
139  ) {
140  return false;
141  }
142 
143  if (
144  $this->dic->isDependencyAvailable('http') &&
145  strpos($this->dic->http()->request()->getServerParams()['HTTP_ACCEPT'], 'text/html') !== false
146  ) {
147  return true;
148  }
149  if (
150  $this->dic->isDependencyAvailable('http') &&
151  strpos($this->dic->http()->request()->getServerParams()['HTTP_ACCEPT'], 'application/json') !== false
152  ) {
153  return false;
154  }
155  return true;
156  }
157 
158  public function getSettings(): ilLoggingSettings
159  {
160  return $this->settings;
161  }
162 
166  protected function getLoggers(): array
167  {
168  return $this->loggers;
169  }
170 
171  public function getComponentLogger(string $a_component_id): ilLogger
172  {
173  if (isset($this->loggers[$a_component_id])) {
174  return $this->loggers[$a_component_id];
175  }
176 
177  $loggerNamePrefix = '';
178  if (defined('CLIENT_ID')) {
179  $loggerNamePrefix = CLIENT_ID . '_';
180  }
181 
182  switch ($a_component_id) {
183  case 'root':
184  $logger = new Logger($loggerNamePrefix . 'root');
185  break;
186 
187  default:
188  $logger = new Logger($loggerNamePrefix . $a_component_id);
189  break;
190  }
191 
192  if (!$this->isLoggingEnabled()) {
193  $null_handler = new NullHandler();
194  $logger->pushHandler($null_handler);
195 
196  return $this->loggers[$a_component_id] = new ilComponentLogger($logger);
197  }
198 
199 
200  // standard stream handler
201  $stream_handler = new StreamHandler(
202  $this->getSettings()->getLogDir() . '/' . $this->getSettings()->getLogFile(),
203  Logger::DEBUG, // default minimum level, will be overwritten by component log level
204  true
205  );
206 
207  if ($a_component_id == self::ROOT_LOGGER) {
208  $stream_handler->setLevel($this->getSettings()->getLevelByComponent(self::COMPONENT_ROOT));
209  } else {
210  $stream_handler->setLevel($this->getSettings()->getLevelByComponent($a_component_id));
211  }
212 
213  // format lines
214  $line_formatter = new ilLineFormatter(static::DEFAULT_FORMAT, 'Y-m-d H:i:s.u', true, true);
215  $stream_handler->setFormatter($line_formatter);
216 
217  if ($this->getSettings()->isCacheEnabled()) {
218  // add new finger crossed handler
219  $finger_crossed_handler = new FingersCrossedHandler(
220  $stream_handler,
221  new ErrorLevelActivationStrategy($this->getSettings()->getCacheLevel()),
222  1000
223  );
224  $logger->pushHandler($finger_crossed_handler);
225  } else {
226  $logger->pushHandler($stream_handler);
227  }
228 
229  if (
230  $this->dic->offsetExists('ilUser') &&
231  $this->dic->user() instanceof ilObjUser
232  ) {
233  if ($this->getSettings()->isBrowserLogEnabledForUser($this->dic->user()->getLogin())) {
234  if ($this->isConsoleAvailable()) {
235  $browser_handler = new BrowserConsoleHandler();
236  $browser_handler->setLevel($this->getSettings()->getLevel());
237  $browser_handler->setFormatter($line_formatter);
238  $logger->pushHandler($browser_handler);
239  }
240  }
241  }
242 
243 
244  // suid log
245  $logger->pushProcessor(function ($record) {
246  $record['suid'] = substr(session_id(), 0, 5);
247  return $record;
248  });
249 
250  // append trace
251  $logger->pushProcessor(new ilTraceProcessor(ilLogLevel::DEBUG));
252 
253  // Interpolate context variables.
254  $logger->pushProcessor(new PsrLogMessageProcessor());
255 
256  // register new logger
257  $this->loggers[$a_component_id] = new ilComponentLogger($logger);
258 
259  return $this->loggers[$a_component_id];
260  }
261 }
static getLogger(string $a_component_id)
Get component logger.
static newInstance(ilLoggingSettings $settings)
Component logger with individual log levels by component id.
Customizing of pimple-DIC for ILIAS.
Definition: Container.php:35
ilLoggingSettings $settings
isConsoleAvailable()
Check if console handler is available.
const CLIENT_ID
Definition: constants.php:41
global $DIC
Definition: shib_login.php:25
static ilLoggerFactory $instance
Custom line formatter.
getComponentLogger(string $a_component_id)
const CONTEXT_WEB
__construct(ilLoggingSettings $settings)
static getType()
Get context type.
initUser(string $a_login)
Init user specific log options.
static getRootLogger()
The unique root logger has a fixed error level.