xref: /dokuwiki/inc/Logger.php (revision c2050393228b5814b1f89804a01f19ad90502ce7)
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    /**
42*c2050393SAndreas Gohr     * Convenience method to directly log to the error log
43*c2050393SAndreas Gohr     *
44*c2050393SAndreas Gohr     * @param string $message The log message
45*c2050393SAndreas Gohr     * @param mixed $details Any details that should be added to the log entry
46*c2050393SAndreas Gohr     * @param string $file A source filename if this is related to a source position
47*c2050393SAndreas Gohr     * @param int $line A line number for the above file
48*c2050393SAndreas Gohr     * @return bool
49*c2050393SAndreas Gohr     */
50*c2050393SAndreas Gohr    static public function error($message, $details = null, $file = '', $line = 0)
51*c2050393SAndreas Gohr    {
52*c2050393SAndreas Gohr        return self::getInstance(self::LOG_ERROR)->log(
53*c2050393SAndreas Gohr            $message, $details, $file, $line
54*c2050393SAndreas Gohr        );
55*c2050393SAndreas Gohr    }
56*c2050393SAndreas Gohr
57*c2050393SAndreas Gohr    /**
58*c2050393SAndreas Gohr     * Convenience method to directly log to the debug log
59*c2050393SAndreas Gohr     *
60*c2050393SAndreas Gohr     * @param string $message The log message
61*c2050393SAndreas Gohr     * @param mixed $details Any details that should be added to the log entry
62*c2050393SAndreas Gohr     * @param string $file A source filename if this is related to a source position
63*c2050393SAndreas Gohr     * @param int $line A line number for the above file
64*c2050393SAndreas Gohr     * @return bool
65*c2050393SAndreas Gohr     */
66*c2050393SAndreas Gohr    static public function debug($message, $details = null, $file = '', $line = 0)
67*c2050393SAndreas Gohr    {
68*c2050393SAndreas Gohr        return self::getInstance(self::LOG_DEBUG)->log(
69*c2050393SAndreas Gohr            $message, $details, $file, $line
70*c2050393SAndreas Gohr        );
71*c2050393SAndreas Gohr    }
72*c2050393SAndreas Gohr
73*c2050393SAndreas Gohr    /**
74*c2050393SAndreas Gohr     * Convenience method to directly log to the deprecation log
75*c2050393SAndreas Gohr     *
76*c2050393SAndreas Gohr     * @param string $message The log message
77*c2050393SAndreas Gohr     * @param mixed $details Any details that should be added to the log entry
78*c2050393SAndreas Gohr     * @param string $file A source filename if this is related to a source position
79*c2050393SAndreas Gohr     * @param int $line A line number for the above file
80*c2050393SAndreas Gohr     * @return bool
81*c2050393SAndreas Gohr     */
82*c2050393SAndreas Gohr    static public function deprecated($message, $details = null, $file = '', $line = 0)
83*c2050393SAndreas Gohr    {
84*c2050393SAndreas Gohr        return self::getInstance(self::LOG_DEPRECATED)->log(
85*c2050393SAndreas Gohr            $message, $details, $file, $line
86*c2050393SAndreas Gohr        );
87*c2050393SAndreas Gohr    }
88*c2050393SAndreas Gohr
89*c2050393SAndreas Gohr    /**
900ecde6ceSAndreas Gohr     * Log a message to the facility log
910ecde6ceSAndreas Gohr     *
920ecde6ceSAndreas Gohr     * @param string $message The log message
930ecde6ceSAndreas Gohr     * @param mixed $details Any details that should be added to the log entry
940ecde6ceSAndreas Gohr     * @param string $file A source filename if this is related to a source position
950ecde6ceSAndreas Gohr     * @param int $line A line number for the above file
960ecde6ceSAndreas Gohr     * @return bool
970ecde6ceSAndreas Gohr     */
980ecde6ceSAndreas Gohr    public function log($message, $details = null, $file = '', $line = 0)
990ecde6ceSAndreas Gohr    {
1000ecde6ceSAndreas Gohr        // details are logged indented
10170cc2cbfSAndreas Gohr        if ($details) {
10270cc2cbfSAndreas Gohr            if (!is_string($details)) {
1030ecde6ceSAndreas Gohr                $details = json_encode($details, JSON_PRETTY_PRINT);
10470cc2cbfSAndreas Gohr            }
1050ecde6ceSAndreas Gohr            $details = explode("\n", $details);
1060ecde6ceSAndreas Gohr            $loglines = array_map(function ($line) {
1070ecde6ceSAndreas Gohr                return '  ' . $line;
1080ecde6ceSAndreas Gohr            }, $details);
1090ecde6ceSAndreas Gohr        } elseif ($details) {
1100ecde6ceSAndreas Gohr            $loglines = [$details];
1110ecde6ceSAndreas Gohr        } else {
1120ecde6ceSAndreas Gohr            $loglines = [];
1130ecde6ceSAndreas Gohr        }
1140ecde6ceSAndreas Gohr
11570cc2cbfSAndreas Gohr        // datetime, fileline, message
11670cc2cbfSAndreas Gohr        $logline = gmdate('Y-m-d H:i:s') . "\t";
1170ecde6ceSAndreas Gohr        if ($file) {
11870cc2cbfSAndreas Gohr            $logline .= $file;
1190ecde6ceSAndreas Gohr            if ($line) $logline .= "($line)";
1200ecde6ceSAndreas Gohr        }
12170cc2cbfSAndreas Gohr        $logline .= "\t" . $message;
1220ecde6ceSAndreas Gohr
1230ecde6ceSAndreas Gohr        array_unshift($loglines, $logline);
1240ecde6ceSAndreas Gohr        return $this->writeLogLines($loglines);
1250ecde6ceSAndreas Gohr    }
1260ecde6ceSAndreas Gohr
1270ecde6ceSAndreas Gohr    /**
12870cc2cbfSAndreas Gohr     * Construct the log file for the given day
12970cc2cbfSAndreas Gohr     *
13070cc2cbfSAndreas Gohr     * @param false|string|int $date Date to access, false for today
13170cc2cbfSAndreas Gohr     * @return string
13270cc2cbfSAndreas Gohr     */
13370cc2cbfSAndreas Gohr    public function getLogfile($date = false)
13470cc2cbfSAndreas Gohr    {
13570cc2cbfSAndreas Gohr        global $conf;
13670cc2cbfSAndreas Gohr
13770cc2cbfSAndreas Gohr        if ($date !== null) $date = strtotime($date);
13870cc2cbfSAndreas Gohr        if (!$date) $date = time();
13970cc2cbfSAndreas Gohr
14070cc2cbfSAndreas Gohr        return $conf['logdir'] . '/' . $this->facility . '/' . date('Y-m-d', $date) . '.log';
14170cc2cbfSAndreas Gohr    }
14270cc2cbfSAndreas Gohr
14370cc2cbfSAndreas Gohr    /**
1440ecde6ceSAndreas Gohr     * Write the given lines to today's facility log
1450ecde6ceSAndreas Gohr     *
1460ecde6ceSAndreas Gohr     * @param string[] $lines the raw lines to append to the log
1470ecde6ceSAndreas Gohr     * @return bool true if the log was written
1480ecde6ceSAndreas Gohr     */
1490ecde6ceSAndreas Gohr    protected function writeLogLines($lines)
1500ecde6ceSAndreas Gohr    {
15170cc2cbfSAndreas Gohr        $logfile = $this->getLogfile();
1520ecde6ceSAndreas Gohr        return io_saveFile($logfile, join("\n", $lines) . "\n", true);
1530ecde6ceSAndreas Gohr    }
1540ecde6ceSAndreas Gohr}
155