xref: /dokuwiki/inc/Logger.php (revision 70cc2cbf41ee65a6048aab5aab40e124b337e295)
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