Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * $Header$
4
 *
5
 * @version $Revision: 224513 $
6
 * @package Log
7
 */
8
 
9
/**
10
 * The Log_file class is a concrete implementation of the Log abstract
11
 * class that logs messages to a text file.
12
 *
13
 * @author  Jon Parise <jon@php.net>
14
 * @author  Roman Neuhauser <neuhauser@bellavista.cz>
15
 * @since   Log 1.0
16
 * @package Log
17
 *
18
 * @example file.php    Using the file handler.
19
 */
20
class Log_file extends Log
21
{
22
    /**
23
     * String containing the name of the log file.
24
     * @var string
25
     * @access private
26
     */
27
    var $_filename = 'php.log';
28
 
29
    /**
30
     * Handle to the log file.
31
     * @var resource
32
     * @access private
33
     */
34
    var $_fp = false;
35
 
36
    /**
37
     * Should new log entries be append to an existing log file, or should the
38
     * a new log file overwrite an existing one?
39
     * @var boolean
40
     * @access private
41
     */
42
    var $_append = true;
43
 
44
    /**
45
     * Should advisory file locking (i.e., flock()) be used?
46
     * @var boolean
47
     * @access private
48
     */
49
    var $_locking = false;
50
 
51
    /**
52
     * Integer (in octal) containing the log file's permissions mode.
53
     * @var integer
54
     * @access private
55
     */
56
    var $_mode = 0644;
57
 
58
    /**
59
     * Integer (in octal) specifying the file permission mode that will be
60
     * used when creating directories that do not already exist.
61
     * @var integer
62
     * @access private
63
     */
64
    var $_dirmode = 0755;
65
 
66
    /**
67
     * String containing the format of a log line.
68
     * @var string
69
     * @access private
70
     */
71
    var $_lineFormat = '%1$s %2$s [%3$s] %4$s';
72
 
73
    /**
74
     * String containing the timestamp format.  It will be passed directly to
75
     * strftime().  Note that the timestamp string will generated using the
76
     * current locale.
77
     * @var string
78
     * @access private
79
     */
80
    var $_timeFormat = '%b %d %H:%M:%S';
81
 
82
    /**
83
     * String containing the end-on-line character sequence.
84
     * @var string
85
     * @access private
86
     */
87
    var $_eol = "\n";
88
 
89
    /**
90
     * Constructs a new Log_file object.
91
     *
92
     * @param string $name     Ignored.
93
     * @param string $ident    The identity string.
94
     * @param array  $conf     The configuration array.
95
     * @param int    $level    Log messages up to and including this level.
96
     * @access public
97
     */
98
    function Log_file($name, $ident = '', $conf = array(),
99
                      $level = PEAR_LOG_DEBUG)
100
    {
101
        $this->_id = md5(microtime());
102
        $this->_filename = $name;
103
        $this->_ident = $ident;
104
        $this->_mask = Log::UPTO($level);
105
 
106
        if (isset($conf['append'])) {
107
            $this->_append = $conf['append'];
108
        }
109
 
110
        if (isset($conf['locking'])) {
111
            $this->_locking = $conf['locking'];
112
        }
113
 
114
        if (!empty($conf['mode'])) {
115
            if (is_string($conf['mode'])) {
116
                $this->_mode = octdec($conf['mode']);
117
            } else {
118
                $this->_mode = $conf['mode'];
119
            }
120
        }
121
 
122
        if (!empty($conf['dirmode'])) {
123
            if (is_string($conf['dirmode'])) {
124
                $this->_dirmode = octdec($conf['dirmode']);
125
            } else {
126
                $this->_dirmode = $conf['dirmode'];
127
            }
128
        }
129
 
130
        if (!empty($conf['lineFormat'])) {
131
            $this->_lineFormat = str_replace(array_keys($this->_formatMap),
132
                                             array_values($this->_formatMap),
133
                                             $conf['lineFormat']);
134
        }
135
 
136
        if (!empty($conf['timeFormat'])) {
137
            $this->_timeFormat = $conf['timeFormat'];
138
        }
139
 
140
        if (!empty($conf['eol'])) {
141
            $this->_eol = $conf['eol'];
142
        } else {
143
            $this->_eol = (strstr(PHP_OS, 'WIN')) ? "\r\n" : "\n";
144
        }
145
 
146
        register_shutdown_function(array(&$this, '_Log_file'));
147
    }
148
 
149
    /**
150
     * Destructor
151
     */
152
    function _Log_file()
153
    {
154
        if ($this->_opened) {
155
            $this->close();
156
        }
157
    }
158
 
159
    /**
160
     * Creates the given directory path.  If the parent directories don't
161
     * already exist, they will be created, too.
162
     *
163
     * This implementation is inspired by Python's os.makedirs function.
164
     *
165
     * @param   string  $path       The full directory path to create.
166
     * @param   integer $mode       The permissions mode with which the
167
     *                              directories will be created.
168
     *
169
     * @return  True if the full path is successfully created or already
170
     *          exists.
171
     *
172
     * @access  private
173
     */
174
    function _mkpath($path, $mode = 0700)
175
    {
176
        /* Separate the last pathname component from the rest of the path. */
177
        $head = dirname($path);
178
        $tail = basename($path);
179
 
180
        /* Make sure we've split the path into two complete components. */
181
        if (empty($tail)) {
182
            $head = dirname($path);
183
            $tail = basename($path);
184
        }
185
 
186
        /* Recurse up the path if our current segment does not exist. */
187
        if (!empty($head) && !empty($tail) && !is_dir($head)) {
188
            $this->_mkpath($head, $mode);
189
        }
190
 
191
        /* Create this segment of the path. */
192
        return @mkdir($head, $mode);
193
    }
194
 
195
    /**
196
     * Opens the log file for output.  If the specified log file does not
197
     * already exist, it will be created.  By default, new log entries are
198
     * appended to the end of the log file.
199
     *
200
     * This is implicitly called by log(), if necessary.
201
     *
202
     * @access public
203
     */
204
    function open()
205
    {
206
        if (!$this->_opened) {
207
            /* If the log file's directory doesn't exist, create it. */
208
            if (!is_dir(dirname($this->_filename))) {
209
                $this->_mkpath($this->_filename, $this->_dirmode);
210
            }
211
 
212
            /* Determine whether the log file needs to be created. */
213
            $creating = !file_exists($this->_filename);
214
 
215
            /* Obtain a handle to the log file. */
216
            $this->_fp = fopen($this->_filename, ($this->_append) ? 'a' : 'w');
217
 
218
            /* We consider the file "opened" if we have a valid file pointer. */
219
            $this->_opened = ($this->_fp !== false);
220
 
221
            /* Attempt to set the file's permissions if we just created it. */
222
            if ($creating && $this->_opened) {
223
                chmod($this->_filename, $this->_mode);
224
            }
225
        }
226
 
227
        return $this->_opened;
228
    }
229
 
230
    /**
231
     * Closes the log file if it is open.
232
     *
233
     * @access public
234
     */
235
    function close()
236
    {
237
        /* If the log file is open, close it. */
238
        if ($this->_opened && fclose($this->_fp)) {
239
            $this->_opened = false;
240
        }
241
 
242
        return ($this->_opened === false);
243
    }
244
 
245
    /**
246
     * Flushes all pending data to the file handle.
247
     *
248
     * @access public
249
     * @since Log 1.8.2
250
     */
251
    function flush()
252
    {
253
        if (is_resource($this->_fp)) {
254
            return fflush($this->_fp);
255
        }
256
 
257
        return false;
258
    }
259
 
260
    /**
261
     * Logs $message to the output window.  The message is also passed along
262
     * to any Log_observer instances that are observing this Log.
263
     *
264
     * @param mixed  $message  String or object containing the message to log.
265
     * @param string $priority The priority of the message.  Valid
266
     *                  values are: PEAR_LOG_EMERG, PEAR_LOG_ALERT,
267
     *                  PEAR_LOG_CRIT, PEAR_LOG_ERR, PEAR_LOG_WARNING,
268
     *                  PEAR_LOG_NOTICE, PEAR_LOG_INFO, and PEAR_LOG_DEBUG.
269
     * @return boolean  True on success or false on failure.
270
     * @access public
271
     */
272
    function log($message, $priority = null)
273
    {
274
        /* If a priority hasn't been specified, use the default value. */
275
        if ($priority === null) {
276
            $priority = $this->_priority;
277
        }
278
 
279
        /* Abort early if the priority is above the maximum logging level. */
280
        if (!$this->_isMasked($priority)) {
281
            return false;
282
        }
283
 
284
        /* If the log file isn't already open, open it now. */
285
        if (!$this->_opened && !$this->open()) {
286
            return false;
287
        }
288
 
289
        /* Extract the string representation of the message. */
290
        $message = $this->_extractMessage($message);
291
 
292
        /* Build the string containing the complete log line. */
293
        $line = $this->_format($this->_lineFormat,
294
                               strftime($this->_timeFormat),
295
                               $priority, $message) . $this->_eol;
296
 
297
        /* If locking is enabled, acquire an exclusive lock on the file. */
298
        if ($this->_locking) {
299
            flock($this->_fp, LOCK_EX);
300
        }
301
 
302
        /* Write the log line to the log file. */
303
        $success = (fwrite($this->_fp, $line) !== false);
304
 
305
        /* Unlock the file now that we're finished writing to it. */
306
        if ($this->_locking) {
307
            flock($this->_fp, LOCK_UN);
308
        }
309
 
310
        /* Notify observers about this log message. */
311
        $this->_announce(array('priority' => $priority, 'message' => $message));
312
 
313
        return $success;
314
    }
315
 
316
}