Completed
Pull Request — globalErrorHandling (#3230)
by Andreas
08:33 queued 05:45
created

Logger::getInstance()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace dokuwiki;
4
5
class Logger
6
{
7
    const LOG_ERROR = 'error';
8
    const LOG_DEPRECATED = 'deprecated';
9
    const LOG_DEBUG = 'debug';
10
11
    /** @var Logger[] */
12
    static protected $instances;
13
14
    /** @var string what kind of log is this */
15
    protected $facility;
16
17
    protected $isLogging = true;
18
19
    /**
20
     * Logger constructor.
21
     *
22
     * @param string $facility The type of log
23
     */
24
    protected function __construct($facility)
25
    {
26
        global $conf;
27
        $this->facility = $facility;
28
29
        // Should logging be disabled for this facility?
30
        $dontlog = explode(',', $conf['dontlog']);
31
        $dontlog = array_map('trim', $dontlog);
32
        if (in_array($facility, $dontlog)) $this->isLogging = false;
33
    }
34
35
    /**
36
     * Return a Logger instance for the given facility
37
     *
38
     * @param string $facility The type of log
39
     * @return Logger
40
     */
41
    static public function getInstance($facility = self::LOG_ERROR)
42
    {
43
        if (self::$instances[$facility] === null) {
44
            self::$instances[$facility] = new Logger($facility);
45
        }
46
        return self::$instances[$facility];
47
    }
48
49
    /**
50
     * Convenience method to directly log to the error log
51
     *
52
     * @param string $message The log message
53
     * @param mixed $details Any details that should be added to the log entry
54
     * @param string $file A source filename if this is related to a source position
55
     * @param int $line A line number for the above file
56
     * @return bool has a log been written?
57
     */
58
    static public function error($message, $details = null, $file = '', $line = 0)
59
    {
60
        return self::getInstance(self::LOG_ERROR)->log(
61
            $message, $details, $file, $line
62
        );
63
    }
64
65
    /**
66
     * Convenience method to directly log to the debug log
67
     *
68
     * @param string $message The log message
69
     * @param mixed $details Any details that should be added to the log entry
70
     * @param string $file A source filename if this is related to a source position
71
     * @param int $line A line number for the above file
72
     * @return bool has a log been written?
73
     */
74
    static public function debug($message, $details = null, $file = '', $line = 0)
75
    {
76
        return self::getInstance(self::LOG_DEBUG)->log(
77
            $message, $details, $file, $line
78
        );
79
    }
80
81
    /**
82
     * Convenience method to directly log to the deprecation log
83
     *
84
     * @param string $message The log message
85
     * @param mixed $details Any details that should be added to the log entry
86
     * @param string $file A source filename if this is related to a source position
87
     * @param int $line A line number for the above file
88
     * @return bool has a log been written?
89
     */
90
    static public function deprecated($message, $details = null, $file = '', $line = 0)
91
    {
92
        return self::getInstance(self::LOG_DEPRECATED)->log(
93
            $message, $details, $file, $line
94
        );
95
    }
96
97
    /**
98
     * Log a message to the facility log
99
     *
100
     * @param string $message The log message
101
     * @param mixed $details Any details that should be added to the log entry
102
     * @param string $file A source filename if this is related to a source position
103
     * @param int $line A line number for the above file
104
     * @return bool has a log been written?
105
     */
106
    public function log($message, $details = null, $file = '', $line = 0)
107
    {
108
        if(!$this->isLogging) return false;
109
110
        // details are logged indented
111
        if ($details) {
112
            if (!is_string($details)) {
113
                $details = json_encode($details, JSON_PRETTY_PRINT);
114
            }
115
            $details = explode("\n", $details);
116
            $loglines = array_map(function ($line) {
117
                return '  ' . $line;
118
            }, $details);
119
        } elseif ($details) {
120
            $loglines = [$details];
121
        } else {
122
            $loglines = [];
123
        }
124
125
        // datetime, fileline, message
126
        $logline = gmdate('Y-m-d H:i:s') . "\t";
127
        if ($file) {
128
            $logline .= $file;
129
            if ($line) $logline .= "($line)";
130
        }
131
        $logline .= "\t" . $message;
132
133
        array_unshift($loglines, $logline);
134
        return $this->writeLogLines($loglines);
135
    }
136
137
    /**
138
     * Construct the log file for the given day
139
     *
140
     * @param false|string|int $date Date to access, false for today
141
     * @return string
142
     */
143
    public function getLogfile($date = false)
144
    {
145
        global $conf;
146
147
        if ($date !== null) $date = strtotime($date);
148
        if (!$date) $date = time();
149
150
        return $conf['logdir'] . '/' . $this->facility . '/' . date('Y-m-d', $date) . '.log';
151
    }
152
153
    /**
154
     * Write the given lines to today's facility log
155
     *
156
     * @param string[] $lines the raw lines to append to the log
157
     * @return bool true if the log was written
158
     */
159
    protected function writeLogLines($lines)
160
    {
161
        $logfile = $this->getLogfile();
162
        return io_saveFile($logfile, join("\n", $lines) . "\n", true);
163
    }
164
}
165