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\Object\Log;
25 * Parse a log line and offer some utility methods
29 const REGEXP = '/^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[^ ]*) (\w+) \[(\w*)\]: (.*)/';
38 public $context = null;
44 public $message = null;
50 public $source = null;
57 * @param string $logline Source log line to parse
59 public function __construct(int $id, string $logline)
62 $this->parse($logline);
65 private function parse($logline)
67 list($logline, $jsonsource) = explode(' - ', $logline);
71 if (strpos($logline, '{"') > 0) {
72 list($logline, $jsondata) = explode('{"', $logline, 2);
74 $jsondata = '{"' . $jsondata;
76 preg_match(self::REGEXP, $logline, $matches);
78 $this->date = $matches[1];
79 $this->context = $matches[2];
80 $this->level = $matches[3];
81 $this->message = $matches[4];
82 $this->data = $jsondata;
83 $this->source = $jsonsource;
84 $this->try_fix_json();
86 $this->logline = $logline;
90 * Fix message / data split
92 * In log boundary between message and json data is not specified.
93 * If message contains '{' the parser thinks there starts the json data.
94 * This method try to parse the found json and if it fails, search for next '{'
95 * in json data and retry
97 private function try_fix_json()
99 if (is_null($this->data) || $this->data == "") {
103 $d = json_decode($this->data, true, 512, JSON_THROW_ON_ERROR);
104 } catch (\JsonException $e) {
105 // try to find next { in $str and move string before to 'message'
107 $pos = strpos($this->data, '{', 1);
109 $this->message .= substr($this->data, 0, $pos);
110 $this->data = substr($this->data, $pos);
111 $this->try_fix_json();
116 * Return decoded `data` as array suitable for template
120 public function get_data()
122 $data = json_decode($this->data, true);
124 foreach ($data as $k => $v) {
125 $data[$k] = print_r($v, true);
132 * Return decoded `source` as array suitable for template
136 public function get_source()
138 return json_decode($this->source, true);