2021-03-27 13:28:09 -04:00
|
|
|
<?php
|
|
|
|
/**
|
2022-01-02 04:49:50 -05:00
|
|
|
* @copyright Copyright (C) 2010-2022, the Friendica project
|
2021-03-27 13:28:09 -04:00
|
|
|
*
|
|
|
|
* @license GNU AGPL version 3 or any later version
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Affero General Public License as
|
|
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Affero General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2021-05-24 16:05:02 -04:00
|
|
|
namespace Friendica\Model\Log;
|
2021-03-27 13:28:09 -04:00
|
|
|
|
2021-05-24 16:05:02 -04:00
|
|
|
use Friendica\Util\ReversedFileReader;
|
2021-08-20 03:47:53 -04:00
|
|
|
use Friendica\Object\Log\ParsedLogLine;
|
2021-03-27 13:28:09 -04:00
|
|
|
|
|
|
|
/**
|
2021-08-20 03:47:53 -04:00
|
|
|
* An iterator which returns `\Friendica\Objec\Log\ParsedLogLine` instances
|
2021-03-27 13:28:09 -04:00
|
|
|
*
|
|
|
|
* Uses `\Friendica\Util\ReversedFileReader` to fetch log lines
|
2021-05-24 15:47:10 -04:00
|
|
|
* from newest to oldest.
|
2021-03-27 13:28:09 -04:00
|
|
|
*/
|
|
|
|
class ParsedLogIterator implements \Iterator
|
|
|
|
{
|
2021-05-24 15:47:10 -04:00
|
|
|
/** @var \Iterator */
|
|
|
|
private $reader;
|
|
|
|
|
2021-08-20 03:47:53 -04:00
|
|
|
/** @var ParsedLogLine current iterator value*/
|
2021-08-19 07:03:45 -04:00
|
|
|
private $value = null;
|
2021-05-24 15:47:10 -04:00
|
|
|
|
|
|
|
/** @var int max number of lines to read */
|
2021-08-19 07:03:45 -04:00
|
|
|
private $limit = 0;
|
2021-05-24 15:47:10 -04:00
|
|
|
|
|
|
|
/** @var array filters per column */
|
2021-08-19 07:03:45 -04:00
|
|
|
private $filters = [];
|
2021-05-24 15:47:10 -04:00
|
|
|
|
|
|
|
/** @var string search term */
|
2021-08-19 07:03:45 -04:00
|
|
|
private $search = "";
|
2021-05-24 15:47:10 -04:00
|
|
|
|
|
|
|
|
2021-08-19 07:03:45 -04:00
|
|
|
/**
|
|
|
|
* @param ReversedFileReader $reader
|
|
|
|
*/
|
|
|
|
public function __construct(ReversedFileReader $reader)
|
|
|
|
{
|
|
|
|
$this->reader = $reader;
|
|
|
|
}
|
|
|
|
|
2021-05-24 15:47:10 -04:00
|
|
|
/**
|
|
|
|
* @param string $filename File to open
|
2021-08-19 07:03:45 -04:00
|
|
|
* @return $this
|
|
|
|
*/
|
2022-06-16 12:28:38 -04:00
|
|
|
public function open(string $filename): ParsedLogIterator
|
2021-08-19 07:03:45 -04:00
|
|
|
{
|
|
|
|
$this->reader->open($filename);
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-05-24 15:47:10 -04:00
|
|
|
* @param int $limit Max num of lines to read
|
2021-08-19 07:03:45 -04:00
|
|
|
* @return $this
|
2021-05-24 15:47:10 -04:00
|
|
|
*/
|
2022-06-16 12:28:38 -04:00
|
|
|
public function withLimit(int $limit): ParsedLogIterator
|
2021-08-19 07:03:45 -04:00
|
|
|
{
|
|
|
|
$this->limit = $limit;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param array $filters filters per column
|
|
|
|
* @return $this
|
|
|
|
*/
|
2022-06-16 12:28:38 -04:00
|
|
|
public function withFilters(array $filters): ParsedLogIterator
|
2021-03-27 13:28:09 -04:00
|
|
|
{
|
2021-05-24 15:47:10 -04:00
|
|
|
$this->filters = $filters;
|
2021-08-19 07:03:45 -04:00
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $search string to search to filter lines
|
|
|
|
* @return $this
|
|
|
|
*/
|
2022-06-16 12:28:38 -04:00
|
|
|
public function withSearch(string $search): ParsedLogIterator
|
2021-08-19 07:03:45 -04:00
|
|
|
{
|
|
|
|
$this->search = $search;
|
|
|
|
return $this;
|
2021-03-27 13:28:09 -04:00
|
|
|
}
|
|
|
|
|
2021-05-24 15:47:10 -04:00
|
|
|
/**
|
|
|
|
* Check if parsed log line match filters.
|
|
|
|
* Always match if no filters are set.
|
2021-05-24 16:05:02 -04:00
|
|
|
*
|
2022-06-16 12:28:38 -04:00
|
|
|
* @param ParsedLogLine $parsedlogline ParsedLogLine instance
|
|
|
|
* @return bool Wether the parse log line matches
|
2021-05-24 15:47:10 -04:00
|
|
|
*/
|
2022-06-16 12:28:38 -04:00
|
|
|
private function filter(ParsedLogLine $parsedlogline): bool
|
2021-03-27 13:28:09 -04:00
|
|
|
{
|
2021-05-24 15:47:10 -04:00
|
|
|
$match = true;
|
|
|
|
foreach ($this->filters as $filter => $filtervalue) {
|
2021-05-24 16:05:02 -04:00
|
|
|
switch ($filter) {
|
2021-05-24 15:47:10 -04:00
|
|
|
case "level":
|
2021-08-20 03:47:53 -04:00
|
|
|
$match = $match && ($parsedlogline->level == strtoupper($filtervalue));
|
2021-05-24 15:47:10 -04:00
|
|
|
break;
|
|
|
|
case "context":
|
2021-08-20 03:47:53 -04:00
|
|
|
$match = $match && ($parsedlogline->context == $filtervalue);
|
2021-05-24 15:47:10 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $match;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if parsed log line match search.
|
|
|
|
* Always match if no search query is set.
|
2021-05-24 16:05:02 -04:00
|
|
|
*
|
2021-08-20 03:47:53 -04:00
|
|
|
* @param ParsedLogLine $parsedlogline
|
2021-05-24 15:47:10 -04:00
|
|
|
* @return bool
|
|
|
|
*/
|
2022-06-16 12:28:38 -04:00
|
|
|
private function search(ParsedLogLine $parsedlogline): bool
|
2021-05-24 15:47:10 -04:00
|
|
|
{
|
|
|
|
if ($this->search != "") {
|
2021-08-20 03:47:53 -04:00
|
|
|
return strstr($parsedlogline->logline, $this->search) !== false;
|
2021-03-27 13:28:09 -04:00
|
|
|
}
|
2021-05-24 16:05:02 -04:00
|
|
|
return true;
|
2021-05-24 15:47:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read a line from reader and parse.
|
|
|
|
* Returns null if limit is reached or the reader is invalid.
|
2021-05-24 16:05:02 -04:00
|
|
|
*
|
2021-08-20 03:47:53 -04:00
|
|
|
* @param ParsedLogLine $parsedlogline
|
|
|
|
* @return ?ParsedLogLine
|
2021-05-24 15:47:10 -04:00
|
|
|
*/
|
|
|
|
private function read()
|
|
|
|
{
|
|
|
|
$this->reader->next();
|
2021-05-24 16:05:02 -04:00
|
|
|
if ($this->limit > 0 && $this->reader->key() > $this->limit || !$this->reader->valid()) {
|
2021-05-24 15:47:10 -04:00
|
|
|
return null;
|
2021-03-27 13:28:09 -04:00
|
|
|
}
|
2021-05-24 15:47:10 -04:00
|
|
|
|
|
|
|
$line = $this->reader->current();
|
2021-08-20 03:47:53 -04:00
|
|
|
return new ParsedLogLine($this->reader->key(), $line);
|
2021-03-27 13:28:09 -04:00
|
|
|
}
|
|
|
|
|
2021-08-20 03:47:53 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Fetch next parsed log line which match with filters or search and
|
|
|
|
* set it as current iterator value.
|
2021-08-20 05:09:35 -04:00
|
|
|
*
|
2021-08-20 03:47:53 -04:00
|
|
|
* @see Iterator::next()
|
|
|
|
* @return void
|
|
|
|
*/
|
2021-05-24 15:47:10 -04:00
|
|
|
public function next()
|
|
|
|
{
|
|
|
|
$parsed = $this->read();
|
|
|
|
|
2021-05-24 16:05:02 -04:00
|
|
|
while (is_null($parsed) == false && !($this->filter($parsed) && $this->search($parsed))) {
|
2021-05-24 15:47:10 -04:00
|
|
|
$parsed = $this->read();
|
|
|
|
}
|
|
|
|
$this->value = $parsed;
|
|
|
|
}
|
2021-03-27 13:28:09 -04:00
|
|
|
|
2021-08-20 03:47:53 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Rewind the iterator to the first matching log line
|
2021-08-20 05:09:35 -04:00
|
|
|
*
|
2021-08-20 03:47:53 -04:00
|
|
|
* @see Iterator::rewind()
|
|
|
|
* @return void
|
|
|
|
*/
|
2021-03-27 13:28:09 -04:00
|
|
|
public function rewind()
|
|
|
|
{
|
2021-05-24 15:47:10 -04:00
|
|
|
$this->value = null;
|
2021-03-27 13:28:09 -04:00
|
|
|
$this->reader->rewind();
|
|
|
|
$this->next();
|
|
|
|
}
|
|
|
|
|
2021-08-20 03:47:53 -04:00
|
|
|
/**
|
|
|
|
* Return current parsed log line number
|
2021-08-20 05:09:35 -04:00
|
|
|
*
|
2021-08-20 03:47:53 -04:00
|
|
|
* @see Iterator::key()
|
|
|
|
* @see ReversedFileReader::key()
|
|
|
|
* @return int
|
|
|
|
*/
|
2021-03-27 13:28:09 -04:00
|
|
|
public function key()
|
|
|
|
{
|
|
|
|
return $this->reader->key();
|
|
|
|
}
|
|
|
|
|
2021-08-20 03:47:53 -04:00
|
|
|
/**
|
|
|
|
* Return current iterator value
|
2021-08-20 05:09:35 -04:00
|
|
|
*
|
2021-08-20 03:47:53 -04:00
|
|
|
* @see Iterator::current()
|
|
|
|
* @return ?ParsedLogLing
|
|
|
|
*/
|
2021-03-27 13:28:09 -04:00
|
|
|
public function current()
|
|
|
|
{
|
2021-05-24 15:47:10 -04:00
|
|
|
return $this->value;
|
2021-03-27 13:28:09 -04:00
|
|
|
}
|
|
|
|
|
2021-08-20 03:47:53 -04:00
|
|
|
/**
|
|
|
|
* Checks if current iterator value is valid, that is, not null
|
2021-08-20 05:09:35 -04:00
|
|
|
*
|
2021-08-20 03:47:53 -04:00
|
|
|
* @see Iterator::valid()
|
|
|
|
* @return bool
|
|
|
|
*/
|
2021-03-27 13:28:09 -04:00
|
|
|
public function valid()
|
|
|
|
{
|
2021-05-24 15:47:10 -04:00
|
|
|
return ! is_null($this->value);
|
2021-03-27 13:28:09 -04:00
|
|
|
}
|
|
|
|
}
|