ILIAS  release_5-2 Revision v5.2.25-18-g3f80b82851
DeduplicationHandler.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the Monolog package.
5  *
6  * (c) Jordi Boggiano <j.boggiano@seld.be>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11 
12 namespace Monolog\Handler;
13 
14 use Monolog\Logger;
15 
37 {
42 
47 
51  protected $time;
52 
56  private $gc = false;
57 
66  {
67  parent::__construct($handler, 0, Logger::DEBUG, $bubble, false);
68 
69  $this->deduplicationStore = $deduplicationStore === null ? sys_get_temp_dir() . '/monolog-dedup-' . substr(md5(__FILE__), 0, 20) .'.log' : $deduplicationStore;
70  $this->deduplicationLevel = Logger::toMonologLevel($deduplicationLevel);
71  $this->time = $time;
72  }
73 
74  public function flush()
75  {
76  if ($this->bufferSize === 0) {
77  return;
78  }
79 
80  $passthru = null;
81 
82  foreach ($this->buffer as $record) {
83  if ($record['level'] >= $this->deduplicationLevel) {
84 
85  $passthru = $passthru || !$this->isDuplicate($record);
86  if ($passthru) {
87  $this->appendRecord($record);
88  }
89  }
90  }
91 
92  // default of null is valid as well as if no record matches duplicationLevel we just pass through
93  if ($passthru === true || $passthru === null) {
94  $this->handler->handleBatch($this->buffer);
95  }
96 
97  $this->clear();
98 
99  if ($this->gc) {
100  $this->collectLogs();
101  }
102  }
103 
104  private function isDuplicate(array $record)
105  {
106  if (!file_exists($this->deduplicationStore)) {
107  return false;
108  }
109 
110  $store = file($this->deduplicationStore, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
111  if (!is_array($store)) {
112  return false;
113  }
114 
115  $yesterday = time() - 86400;
116  $timestampValidity = $record['datetime']->getTimestamp() - $this->time;
117  $expectedMessage = preg_replace('{[\r\n].*}', '', $record['message']);
118 
119  for ($i = count($store) - 1; $i >= 0; $i--) {
120  list($timestamp, $level, $message) = explode(':', $store[$i], 3);
121 
122  if ($level === $record['level_name'] && $message === $expectedMessage && $timestamp > $timestampValidity) {
123  return true;
124  }
125 
126  if ($timestamp < $yesterday) {
127  $this->gc = true;
128  }
129  }
130 
131  return false;
132  }
133 
134  private function collectLogs()
135  {
136  if (!file_exists($this->deduplicationStore)) {
137  return false;
138  }
139 
140  $handle = fopen($this->deduplicationStore, 'rw+');
141  flock($handle, LOCK_EX);
142  $validLogs = array();
143 
144  $timestampValidity = time() - $this->time;
145 
146  while (!feof($handle)) {
147  $log = fgets($handle);
148  if (substr($log, 0, 10) >= $timestampValidity) {
149  $validLogs[] = $log;
150  }
151  }
152 
153  ftruncate($handle, 0);
154  rewind($handle);
155  foreach ($validLogs as $log) {
156  fwrite($handle, $log);
157  }
158 
159  flock($handle, LOCK_UN);
160  fclose($handle);
161 
162  $this->gc = false;
163  }
164 
165  private function appendRecord(array $record)
166  {
167  file_put_contents($this->deduplicationStore, $record['datetime']->getTimestamp() . ':' . $record['level_name'] . ':' . preg_replace('{[\r\n].*}', '', $record['message']) . "\n", FILE_APPEND);
168  }
169 }
const DEBUG
Detailed debug information.
Definition: Logger.php:32
__construct(HandlerInterface $handler, $deduplicationStore=null, $deduplicationLevel=Logger::ERROR, $time=60, $bubble=true)
const ERROR
Runtime errors.
Definition: Logger.php:57
static toMonologLevel($level)
Converts PSR-3 levels to Monolog ones if necessary.
Definition: Logger.php:473
Buffers all records until closing the handler and then pass them as batch.
Simple handler wrapper that deduplicates log records across multiple requests.
Reload workbook from saved file
Create styles array
The data for the language used.
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:81
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
Interface that all Monolog Handlers must implement.
clear()
Clears the buffer without flushing any messages down to the wrapped handler.