grommunio /
grommunio-sync
| 1 | <?php |
||||
| 2 | |||||
| 3 | /* |
||||
| 4 | * SPDX-License-Identifier: AGPL-3.0-only |
||||
| 5 | * SPDX-FileCopyrightText: Copyright 2007-2016 Zarafa Deutschland GmbH |
||||
| 6 | * SPDX-FileCopyrightText: Copyright 2020-2022 grommunio GmbH |
||||
| 7 | * |
||||
| 8 | * Logging functionalities |
||||
| 9 | */ |
||||
| 10 | |||||
| 11 | class Syslog extends Log { |
||||
| 12 | protected $program_name = ''; |
||||
| 13 | protected $host; |
||||
| 14 | protected $port; |
||||
| 15 | |||||
| 16 | /** |
||||
| 17 | * @return string |
||||
| 18 | */ |
||||
| 19 | public function GetProgramName() { |
||||
| 20 | return $this->program_name; |
||||
| 21 | } |
||||
| 22 | |||||
| 23 | /** |
||||
| 24 | * @param string $value |
||||
| 25 | */ |
||||
| 26 | public function SetProgramName($value) { |
||||
| 27 | $this->program_name = $value; |
||||
| 28 | } |
||||
| 29 | |||||
| 30 | /** |
||||
| 31 | * @return string |
||||
| 32 | */ |
||||
| 33 | public function GetHost() { |
||||
| 34 | return $this->host; |
||||
|
0 ignored issues
–
show
Bug
Best Practice
introduced
by
Loading history...
|
|||||
| 35 | } |
||||
| 36 | |||||
| 37 | /** |
||||
| 38 | * @param string $value |
||||
| 39 | */ |
||||
| 40 | public function SetHost($value) { |
||||
| 41 | $this->host = $value; |
||||
| 42 | } |
||||
| 43 | |||||
| 44 | /** |
||||
| 45 | * @return int |
||||
| 46 | */ |
||||
| 47 | public function GetPort() { |
||||
| 48 | return $this->port; |
||||
| 49 | } |
||||
| 50 | |||||
| 51 | /** |
||||
| 52 | * @param int $value |
||||
| 53 | */ |
||||
| 54 | public function SetPort($value) { |
||||
| 55 | if (is_numeric($value)) { |
||||
|
0 ignored issues
–
show
|
|||||
| 56 | $this->port = (int) $value; |
||||
| 57 | } |
||||
| 58 | } |
||||
| 59 | |||||
| 60 | /** |
||||
| 61 | * Constructor. |
||||
| 62 | * Sets configured values if no parameters are given. |
||||
| 63 | * |
||||
| 64 | * @param string $program_name |
||||
| 65 | * @param string $host |
||||
| 66 | * @param string $port |
||||
| 67 | */ |
||||
| 68 | public function __construct($program_name = null, $host = null, $port = null) { |
||||
| 69 | parent::__construct(); |
||||
| 70 | |||||
| 71 | if (is_null($program_name)) { |
||||
| 72 | $program_name = LOG_SYSLOG_PROGRAM; |
||||
| 73 | } |
||||
| 74 | if (is_null($host)) { |
||||
| 75 | $host = LOG_SYSLOG_HOST; |
||||
| 76 | } |
||||
| 77 | if (is_null($port)) { |
||||
| 78 | $port = LOG_SYSLOG_PORT; |
||||
| 79 | } |
||||
| 80 | |||||
| 81 | $this->SetProgramName($program_name); |
||||
| 82 | $this->SetHost($host); |
||||
|
0 ignored issues
–
show
It seems like
$host can also be of type false; however, parameter $value of Syslog::SetHost() does only seem to accept string, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 83 | $this->SetPort($port); |
||||
|
0 ignored issues
–
show
It seems like
$port can also be of type string; however, parameter $value of Syslog::SetPort() does only seem to accept integer, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 84 | } |
||||
| 85 | |||||
| 86 | /** |
||||
| 87 | * Return the full program name for syslog. |
||||
| 88 | * The name can be grommunio-sync/core or grommunio-sync/{backend} where backend is the backend that initiated the log. |
||||
| 89 | * |
||||
| 90 | * @return string |
||||
| 91 | */ |
||||
| 92 | protected function GenerateProgramName() { |
||||
| 93 | // @TODO Use another mechanism than debug_backtrace to determine to origin of the log |
||||
| 94 | $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); |
||||
| 95 | // Shift the "syslog.php" entry. |
||||
| 96 | array_shift($backtrace); |
||||
| 97 | foreach ($backtrace as $trace) { |
||||
| 98 | if (!isset($trace['file'])) { |
||||
| 99 | continue; |
||||
| 100 | } |
||||
| 101 | if (str_contains($trace['file'], REAL_BASE_PATH . 'backend/')) { |
||||
| 102 | preg_match('/\/backend\/([a-zA-Z]*)/', $trace['file'], $match); |
||||
| 103 | if (isset($match[1])) { |
||||
| 104 | return $this->GetProgramName() . '/' . $match[1]; |
||||
| 105 | } |
||||
| 106 | } |
||||
| 107 | elseif (basename($trace['file'], '.php') != 'slog') { |
||||
| 108 | return $this->GetProgramName() . '/core'; |
||||
| 109 | } |
||||
| 110 | } |
||||
| 111 | |||||
| 112 | return $this->GetProgramName() . '/core'; |
||||
| 113 | } |
||||
| 114 | |||||
| 115 | /** |
||||
| 116 | * Maps the grommunio-sync loglevel with those of syslog. |
||||
| 117 | * |
||||
| 118 | * @param int $loglevel |
||||
| 119 | * |
||||
| 120 | * @return int one of many LOG_* syslog level |
||||
| 121 | */ |
||||
| 122 | protected function GetGsyncLogLevelToSyslogLogLevel($loglevel) { |
||||
| 123 | return match ($loglevel) { |
||||
| 124 | LOGLEVEL_FATAL => LOG_ALERT, |
||||
| 125 | LOGLEVEL_ERROR => LOG_ERR, |
||||
| 126 | LOGLEVEL_WARN => LOG_WARNING, |
||||
| 127 | LOGLEVEL_INFO => LOG_INFO, |
||||
| 128 | LOGLEVEL_DEBUG => LOG_DEBUG, |
||||
| 129 | LOGLEVEL_WBXML => LOG_DEBUG, |
||||
| 130 | LOGLEVEL_DEVICEID => LOG_DEBUG, |
||||
| 131 | LOGLEVEL_WBXMLSTACK => LOG_DEBUG, |
||||
| 132 | default => null, |
||||
| 133 | }; |
||||
| 134 | } |
||||
| 135 | |||||
| 136 | /** |
||||
| 137 | * Build the log string for syslog. |
||||
| 138 | * |
||||
| 139 | * @param int $loglevel |
||||
| 140 | * @param string $message |
||||
| 141 | * @param bool $includeUserDevice puts username and device in the string, default: true |
||||
| 142 | * |
||||
| 143 | * @return string |
||||
| 144 | */ |
||||
| 145 | public function BuildLogString($loglevel, $message, $includeUserDevice = true) { |
||||
|
0 ignored issues
–
show
The parameter
$includeUserDevice is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. Loading history...
|
|||||
| 146 | $log = $this->GetLogLevelString($loglevel); // Never pad syslog log because syslog log are usually read with a software. |
||||
| 147 | // when the users differ, we need to log both |
||||
| 148 | if (strcasecmp($this->GetAuthUser(), $this->GetUser()) == 0) { |
||||
| 149 | $log .= ' [' . $this->GetUser() . ']'; |
||||
| 150 | } |
||||
| 151 | else { |
||||
| 152 | $log .= ' [' . $this->GetAuthUser() . Request::IMPERSONATE_DELIM . $this->GetUser() . ']'; |
||||
| 153 | } |
||||
| 154 | if ($loglevel >= LOGLEVEL_DEVICEID) { |
||||
| 155 | $log .= '[' . $this->GetDevid() . ']'; |
||||
| 156 | } |
||||
| 157 | $log .= ' ' . $message; |
||||
| 158 | |||||
| 159 | return $log; |
||||
| 160 | } |
||||
| 161 | |||||
| 162 | // |
||||
| 163 | // Implementation of Log |
||||
| 164 | // |
||||
| 165 | |||||
| 166 | /** |
||||
| 167 | * Writes a log message to the general log. |
||||
| 168 | * |
||||
| 169 | * @param int $loglevel |
||||
| 170 | * @param string $message |
||||
| 171 | */ |
||||
| 172 | protected function Write($loglevel, $message) { |
||||
| 173 | if ($this->GetHost() && $this->GetPort()) { |
||||
| 174 | $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); |
||||
| 175 | $facility = 1; // user level |
||||
| 176 | $pri = ($facility * 8) + $loglevel; // multiplying the Facility number by 8 + adding the level |
||||
| 177 | $data = $this->BuildLogString($loglevel, $message); |
||||
| 178 | if (strlen(trim($data)) > 0) { |
||||
| 179 | $syslog_message = "<{$pri}>" . date('M d H:i:s ') . '[' . $this->GetProgramName() . ']: ' . $data; |
||||
| 180 | socket_sendto($sock, $syslog_message, strlen($syslog_message), 0, $this->GetHost(), $this->GetPort()); |
||||
| 181 | } |
||||
| 182 | socket_close($sock); |
||||
| 183 | } |
||||
| 184 | else { |
||||
| 185 | openlog($this->GenerateProgramName(), LOG_PID, LOG_SYSLOG_FACILITY); |
||||
| 186 | syslog( |
||||
| 187 | $this->GetGsyncLogLevelToSyslogLogLevel($loglevel), |
||||
| 188 | $this->BuildLogString($loglevel, $message) |
||||
| 189 | ); |
||||
| 190 | } |
||||
| 191 | } |
||||
| 192 | |||||
| 193 | /** |
||||
| 194 | * This function is used as an event for log implementer. |
||||
| 195 | * It happens when the a call to the Log function is finished. |
||||
| 196 | * |
||||
| 197 | * @param mixed $loglevel |
||||
| 198 | * @param mixed $message |
||||
| 199 | */ |
||||
| 200 | public function WriteForUser($loglevel, $message) { |
||||
| 201 | $this->Write(LOGLEVEL_DEBUG, $message); // Always pass the logleveldebug so it uses syslog level LOG_DEBUG |
||||
| 202 | } |
||||
| 203 | } |
||||
| 204 |