ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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
12namespace Monolog\Handler;
13
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}
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:81
An exception for terminatinating execution or to throw for unit testing.
Buffers all records until closing the handler and then pass them as batch.
clear()
Clears the buffer without flushing any messages down to the wrapped handler.
Simple handler wrapper that deduplicates log records across multiple requests.
__construct(HandlerInterface $handler, $deduplicationStore=null, $deduplicationLevel=Logger::ERROR, $time=60, $bubble=true)
Monolog log channel.
Definition: Logger.php:28
static toMonologLevel($level)
Converts PSR-3 levels to Monolog ones if necessary.
Definition: Logger.php:473
const ERROR
Runtime errors.
Definition: Logger.php:57
const DEBUG
Detailed debug information.
Definition: Logger.php:32
$i
Definition: disco.tpl.php:19
if(! $oauthconfig->getBoolean('getUserInfo.enable', FALSE)) $store
Definition: getUserInfo.php:11
Interface that all Monolog Handlers must implement.
catch(Exception $e) $message