10ecde6ceSAndreas Gohr<?php 20ecde6ceSAndreas Gohr 30ecde6ceSAndreas Gohrnamespace dokuwiki; 40ecde6ceSAndreas Gohr 50ecde6ceSAndreas Gohrclass Logger 60ecde6ceSAndreas Gohr{ 70ecde6ceSAndreas Gohr const LOG_ERROR = 'error'; 80ecde6ceSAndreas Gohr const LOG_DEPRECATED = 'deprecated'; 90ecde6ceSAndreas Gohr const LOG_DEBUG = 'debug'; 100ecde6ceSAndreas Gohr 110ecde6ceSAndreas Gohr /** @var Logger[] */ 120ecde6ceSAndreas Gohr static protected $instances; 130ecde6ceSAndreas Gohr 140ecde6ceSAndreas Gohr /** @var string what kind of log is this */ 150ecde6ceSAndreas Gohr protected $facility; 160ecde6ceSAndreas Gohr 170ecde6ceSAndreas Gohr /** 180ecde6ceSAndreas Gohr * Logger constructor. 190ecde6ceSAndreas Gohr * 200ecde6ceSAndreas Gohr * @param string $facility The type of log 210ecde6ceSAndreas Gohr */ 220ecde6ceSAndreas Gohr protected function __construct($facility) 230ecde6ceSAndreas Gohr { 240ecde6ceSAndreas Gohr $this->facility = $facility; 250ecde6ceSAndreas Gohr } 260ecde6ceSAndreas Gohr 270ecde6ceSAndreas Gohr /** 280ecde6ceSAndreas Gohr * Return a Logger instance for the given facility 290ecde6ceSAndreas Gohr * 300ecde6ceSAndreas Gohr * @param string $facility The type of log 310ecde6ceSAndreas Gohr * @return Logger 320ecde6ceSAndreas Gohr */ 330ecde6ceSAndreas Gohr static public function getInstance($facility = self::LOG_ERROR) 340ecde6ceSAndreas Gohr { 350ecde6ceSAndreas Gohr if (self::$instances[$facility] === null) { 360ecde6ceSAndreas Gohr self::$instances[$facility] = new Logger($facility); 370ecde6ceSAndreas Gohr } 380ecde6ceSAndreas Gohr return self::$instances[$facility]; 390ecde6ceSAndreas Gohr } 400ecde6ceSAndreas Gohr 410ecde6ceSAndreas Gohr /** 420ecde6ceSAndreas Gohr * Log a message to the facility log 430ecde6ceSAndreas Gohr * 440ecde6ceSAndreas Gohr * @param string $message The log message 450ecde6ceSAndreas Gohr * @param mixed $details Any details that should be added to the log entry 460ecde6ceSAndreas Gohr * @param string $file A source filename if this is related to a source position 470ecde6ceSAndreas Gohr * @param int $line A line number for the above file 480ecde6ceSAndreas Gohr * @return bool 490ecde6ceSAndreas Gohr */ 500ecde6ceSAndreas Gohr public function log($message, $details = null, $file = '', $line = 0) 510ecde6ceSAndreas Gohr { 520ecde6ceSAndreas Gohr // details are logged indented 53*70cc2cbfSAndreas Gohr if ($details) { 54*70cc2cbfSAndreas Gohr if (!is_string($details)) { 550ecde6ceSAndreas Gohr $details = json_encode($details, JSON_PRETTY_PRINT); 56*70cc2cbfSAndreas Gohr } 570ecde6ceSAndreas Gohr $details = explode("\n", $details); 580ecde6ceSAndreas Gohr $loglines = array_map(function ($line) { 590ecde6ceSAndreas Gohr return ' ' . $line; 600ecde6ceSAndreas Gohr }, $details); 610ecde6ceSAndreas Gohr } elseif ($details) { 620ecde6ceSAndreas Gohr $loglines = [$details]; 630ecde6ceSAndreas Gohr } else { 640ecde6ceSAndreas Gohr $loglines = []; 650ecde6ceSAndreas Gohr } 660ecde6ceSAndreas Gohr 67*70cc2cbfSAndreas Gohr // datetime, fileline, message 68*70cc2cbfSAndreas Gohr $logline = gmdate('Y-m-d H:i:s') . "\t"; 690ecde6ceSAndreas Gohr if ($file) { 70*70cc2cbfSAndreas Gohr $logline .= $file; 710ecde6ceSAndreas Gohr if ($line) $logline .= "($line)"; 720ecde6ceSAndreas Gohr } 73*70cc2cbfSAndreas Gohr $logline .= "\t" . $message; 740ecde6ceSAndreas Gohr 750ecde6ceSAndreas Gohr array_unshift($loglines, $logline); 760ecde6ceSAndreas Gohr return $this->writeLogLines($loglines); 770ecde6ceSAndreas Gohr } 780ecde6ceSAndreas Gohr 790ecde6ceSAndreas Gohr /** 80*70cc2cbfSAndreas Gohr * Construct the log file for the given day 81*70cc2cbfSAndreas Gohr * 82*70cc2cbfSAndreas Gohr * @param false|string|int $date Date to access, false for today 83*70cc2cbfSAndreas Gohr * @return string 84*70cc2cbfSAndreas Gohr */ 85*70cc2cbfSAndreas Gohr public function getLogfile($date = false) 86*70cc2cbfSAndreas Gohr { 87*70cc2cbfSAndreas Gohr global $conf; 88*70cc2cbfSAndreas Gohr 89*70cc2cbfSAndreas Gohr if ($date !== null) $date = strtotime($date); 90*70cc2cbfSAndreas Gohr if (!$date) $date = time(); 91*70cc2cbfSAndreas Gohr 92*70cc2cbfSAndreas Gohr return $conf['logdir'] . '/' . $this->facility . '/' . date('Y-m-d', $date) . '.log'; 93*70cc2cbfSAndreas Gohr } 94*70cc2cbfSAndreas Gohr 95*70cc2cbfSAndreas Gohr /** 960ecde6ceSAndreas Gohr * Write the given lines to today's facility log 970ecde6ceSAndreas Gohr * 980ecde6ceSAndreas Gohr * @param string[] $lines the raw lines to append to the log 990ecde6ceSAndreas Gohr * @return bool true if the log was written 1000ecde6ceSAndreas Gohr */ 1010ecde6ceSAndreas Gohr protected function writeLogLines($lines) 1020ecde6ceSAndreas Gohr { 103*70cc2cbfSAndreas Gohr $logfile = $this->getLogfile(); 1040ecde6ceSAndreas Gohr return io_saveFile($logfile, join("\n", $lines) . "\n", true); 1050ecde6ceSAndreas Gohr } 1060ecde6ceSAndreas Gohr} 107