| 1 |
<?php |
| 2 |
|
| 3 |
namespace JetBackup\Log; |
| 4 |
|
| 5 |
use Exception; |
| 6 |
use JetBackup\Entities\Util; |
| 7 |
use JetBackup\Exception\LogException; |
| 8 |
use JetBackup\Wordpress\Helper; |
| 9 |
|
| 10 |
if (!defined( '__JETBACKUP__')) die('Direct access is not allowed'); |
| 11 |
|
| 12 |
class FileLogger implements Logger{ |
| 13 |
|
| 14 |
const DEFAULT_ADD_EVENT_PARAMS = Logger::PARAMS_NEW_LINE | Logger::PARAMS_BACK_START_LINE | Logger::PARAMS_ADD_DATE | Logger::PARAMS_ADD_IP; |
| 15 |
|
| 16 |
private $_fileptr; |
| 17 |
private string $_filepath; |
| 18 |
private int $_level; |
| 19 |
|
| 20 |
public function __construct(string $logfile, int $level=Logger::LOG_LEVEL_ERROR | Logger::LOG_LEVEL_WARNING | Logger::LOG_LEVEL_NOTICE | Logger::LOG_LEVEL_MESSAGE) { |
| 21 |
$this->_filepath = $logfile; |
| 22 |
$this->_level = $level; |
| 23 |
if(!$this->_filepath) throw new LogException("You must specify log files path."); |
| 24 |
$isStd = preg_match("/^php:\/\//", $this->_filepath); |
| 25 |
if(!$isStd && !file_exists(dirname($this->_filepath))) mkdir(dirname($this->_filepath), 0700, true); |
| 26 |
$this->_fileptr = fopen($this->_filepath, "a+"); |
| 27 |
if(!$this->_fileptr) throw new LogException($this->_filepath); |
| 28 |
} |
| 29 |
|
| 30 |
public function addEvent(string $message, int $level, int $params=self::DEFAULT_ADD_EVENT_PARAMS):void { |
| 31 |
if(($level & $this->_level) == 0) return; |
| 32 |
$format = $this->getLineFormat($params, $level); |
| 33 |
$message = sprintf($format, $message); |
| 34 |
if(fwrite($this->_fileptr, $message) === false) throw new LogException("Failed writing to file"); |
| 35 |
} |
| 36 |
|
| 37 |
/** |
| 38 |
* @return string |
| 39 |
*/ |
| 40 |
public function getFilePath():string { return $this->_filepath; } |
| 41 |
|
| 42 |
/** |
| 43 |
* @return int |
| 44 |
*/ |
| 45 |
public function getLevel():int { return $this->_level; } |
| 46 |
|
| 47 |
/** |
| 48 |
* @throws Exception |
| 49 |
*/ |
| 50 |
protected function getLineFormat(int $params, int $level):string { |
| 51 |
$format = "%s"; |
| 52 |
if(($params & Logger::PARAMS_BACK_START_LINE) > 0) $format = "$format\r"; |
| 53 |
if(($params & Logger::PARAMS_NEW_LINE) > 0) $format = "$format\n"; |
| 54 |
if(($params & Logger::PARAMS_ADD_LEVEL) > 0) $format = "[". @Logger::LOG_LEVEL_NAMES[$level] ."] $format"; |
| 55 |
if(($params & Logger::PARAMS_ADD_IP) > 0 && ($ip = Helper::getUserIP())) $format = "[$ip] $format"; |
| 56 |
if(($params & Logger::PARAMS_ADD_DATE) > 0) $format = "[".Util::date(Logger::DATE_FORMAT) . "] $format"; |
| 57 |
return $format; |
| 58 |
} |
| 59 |
|
| 60 |
public function __destruct(){ |
| 61 |
if (!$this->_fileptr) return; |
| 62 |
fflush($this->_fileptr); |
| 63 |
fclose($this->_fileptr); |
| 64 |
} |
| 65 |
|
| 66 |
/** |
| 67 |
* Emergency static logger for shutdown handlers where normal logging may not work. |
| 68 |
* Uses direct file_put_contents for maximum reliability. |
| 69 |
*/ |
| 70 |
public static function emergency(string $file, string $message): void { |
| 71 |
@file_put_contents( |
| 72 |
$file, |
| 73 |
date('[Y-m-d H:i:s] ') . $message . PHP_EOL, |
| 74 |
FILE_APPEND |
| 75 |
); |
| 76 |
} |
| 77 |
} |