3 * @copyright Copyright (C) 2021, Friendica
5 * @license GNU AGPL version 3 or any later version
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Affero General Public License for more details.
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 namespace Friendica\Model\Log;
24 use Friendica\Util\ReversedFileReader;
25 use Friendica\Object\Log\ParsedLogLine;
28 * An iterator which returns `\Friendica\Objec\Log\ParsedLogLine` instances
30 * Uses `\Friendica\Util\ReversedFileReader` to fetch log lines
31 * from newest to oldest.
33 class ParsedLogIterator implements \Iterator
38 /** @var ParsedLogLine current iterator value*/
39 private $value = null;
41 /** @var int max number of lines to read */
44 /** @var array filters per column */
45 private $filters = [];
47 /** @var string search term */
52 * @param ReversedFileReader $reader
54 public function __construct(ReversedFileReader $reader)
56 $this->reader = $reader;
60 * @param string $filename File to open
63 public function open(string $filename)
65 $this->reader->open($filename);
70 * @param int $limit Max num of lines to read
73 public function withLimit(int $limit)
75 $this->limit = $limit;
80 * @param array $filters filters per column
83 public function withFilters(array $filters)
85 $this->filters = $filters;
90 * @param string $search string to search to filter lines
93 public function withSearch(string $search)
95 $this->search = $search;
100 * Check if parsed log line match filters.
101 * Always match if no filters are set.
103 * @param ParsedLogLine $parsedlogline
106 private function filter($parsedlogline)
109 foreach ($this->filters as $filter => $filtervalue) {
112 $match = $match && ($parsedlogline->level == strtoupper($filtervalue));
115 $match = $match && ($parsedlogline->context == $filtervalue);
123 * Check if parsed log line match search.
124 * Always match if no search query is set.
126 * @param ParsedLogLine $parsedlogline
129 private function search($parsedlogline)
131 if ($this->search != "") {
132 return strstr($parsedlogline->logline, $this->search) !== false;
138 * Read a line from reader and parse.
139 * Returns null if limit is reached or the reader is invalid.
141 * @param ParsedLogLine $parsedlogline
142 * @return ?ParsedLogLine
144 private function read()
146 $this->reader->next();
147 if ($this->limit > 0 && $this->reader->key() > $this->limit || !$this->reader->valid()) {
151 $line = $this->reader->current();
152 return new ParsedLogLine($this->reader->key(), $line);
157 * Fetch next parsed log line which match with filters or search and
158 * set it as current iterator value.
160 * @see Iterator::next()
163 public function next()
165 $parsed = $this->read();
167 while (is_null($parsed) == false && !($this->filter($parsed) && $this->search($parsed))) {
168 $parsed = $this->read();
170 $this->value = $parsed;
175 * Rewind the iterator to the first matching log line
177 * @see Iterator::rewind()
180 public function rewind()
183 $this->reader->rewind();
188 * Return current parsed log line number
190 * @see Iterator::key()
191 * @see ReversedFileReader::key()
194 public function key()
196 return $this->reader->key();
200 * Return current iterator value
202 * @see Iterator::current()
203 * @return ?ParsedLogLing
205 public function current()
211 * Checks if current iterator value is valid, that is, not null
213 * @see Iterator::valid()
216 public function valid()
218 return ! is_null($this->value);