|
1 <?php |
|
2 /** |
|
3 * Licensed to the Apache Software Foundation (ASF) under one or more |
|
4 * contributor license agreements. See the NOTICE file distributed with |
|
5 * this work for additional information regarding copyright ownership. |
|
6 * The ASF licenses this file to You under the Apache License, Version 2.0 |
|
7 * (the "License"); you may not use this file except in compliance with |
|
8 * the License. You may obtain a copy of the License at |
|
9 * |
|
10 * http://www.apache.org/licenses/LICENSE-2.0 |
|
11 * |
|
12 * Unless required by applicable law or agreed to in writing, software |
|
13 * distributed under the License is distributed on an "AS IS" BASIS, |
|
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
15 * See the License for the specific language governing permissions and |
|
16 * limitations under the License. |
|
17 */ |
|
18 |
|
19 /** |
|
20 * LoggerAppenderFile appends log events to a file. |
|
21 * |
|
22 * This appender uses a layout. |
|
23 * |
|
24 * ## Configurable parameters: ## |
|
25 * |
|
26 * - **file** - Path to the target file. Relative paths are resolved based on |
|
27 * the working directory. |
|
28 * - **append** - If set to true, the appender will append to the file, |
|
29 * otherwise the file contents will be overwritten. |
|
30 * |
|
31 * @version $Revision: 1382274 $ |
|
32 * @package log4php |
|
33 * @subpackage appenders |
|
34 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 |
|
35 * @link http://logging.apache.org/log4php/docs/appenders/file.html Appender documentation |
|
36 */ |
|
37 class LoggerAppenderFile extends LoggerAppender { |
|
38 |
|
39 /** |
|
40 * If set to true, the file is locked before appending. This allows |
|
41 * concurrent access. However, appending without locking is faster so |
|
42 * it should be used where appropriate. |
|
43 * |
|
44 * TODO: make this a configurable parameter |
|
45 * |
|
46 * @var boolean |
|
47 */ |
|
48 protected $locking = true; |
|
49 |
|
50 /** |
|
51 * If set to true, appends to file. Otherwise overwrites it. |
|
52 * @var boolean |
|
53 */ |
|
54 protected $append = true; |
|
55 |
|
56 /** |
|
57 * Path to the target file. |
|
58 * @var string |
|
59 */ |
|
60 protected $file; |
|
61 |
|
62 /** |
|
63 * The file resource. |
|
64 * @var resource |
|
65 */ |
|
66 protected $fp; |
|
67 |
|
68 /** |
|
69 * Helper function which can be easily overriden by daily file appender. |
|
70 */ |
|
71 protected function getTargetFile() { |
|
72 return $this->file; |
|
73 } |
|
74 |
|
75 /** |
|
76 * Acquires the target file resource, creates the destination folder if |
|
77 * necessary. Writes layout header to file. |
|
78 * |
|
79 * @return boolean FALSE if opening failed |
|
80 */ |
|
81 protected function openFile() { |
|
82 $file = $this->getTargetFile(); |
|
83 |
|
84 // Create the target folder if needed |
|
85 if (!is_file($file)) { |
|
86 $dir = dirname($file); |
|
87 |
|
88 if (!is_dir($dir)) { |
|
89 $success = mkdir($dir, 0777, true); |
|
90 if ($success === false) { |
|
91 $this->warn("Failed creating target directory [$dir]. Closing appender."); |
|
92 $this->closed = true; |
|
93 return false; |
|
94 } |
|
95 } |
|
96 } |
|
97 |
|
98 $mode = $this->append ? 'a' : 'w'; |
|
99 $this->fp = fopen($file, $mode); |
|
100 if ($this->fp === false) { |
|
101 $this->warn("Failed opening target file. Closing appender."); |
|
102 $this->fp = null; |
|
103 $this->closed = true; |
|
104 return false; |
|
105 } |
|
106 |
|
107 // Required when appending with concurrent access |
|
108 if ($this->append) { |
|
109 fseek($this->fp, 0, SEEK_END); |
|
110 } |
|
111 |
|
112 // Write the header |
|
113 $this->write($this->layout->getHeader()); |
|
114 } |
|
115 |
|
116 /** |
|
117 * Writes a string to the target file. Opens file if not already open. |
|
118 * @param string $string Data to write. |
|
119 */ |
|
120 protected function write($string) { |
|
121 // Lazy file open |
|
122 if (!isset($this->fp)) { |
|
123 if ($this->openFile() === false) { |
|
124 return; // Do not write if file open failed. |
|
125 } |
|
126 } |
|
127 |
|
128 if ($this->locking) { |
|
129 $this->writeWithLocking($string); |
|
130 } else { |
|
131 $this->writeWithoutLocking($string); |
|
132 } |
|
133 } |
|
134 |
|
135 protected function writeWithLocking($string) { |
|
136 if (flock($this->fp, LOCK_EX)) { |
|
137 if (fwrite($this->fp, $string) === false) { |
|
138 $this->warn("Failed writing to file. Closing appender."); |
|
139 $this->closed = true; |
|
140 } |
|
141 flock($this->fp, LOCK_UN); |
|
142 } else { |
|
143 $this->warn("Failed locking file for writing. Closing appender."); |
|
144 $this->closed = true; |
|
145 } |
|
146 } |
|
147 |
|
148 protected function writeWithoutLocking($string) { |
|
149 if (fwrite($this->fp, $string) === false) { |
|
150 $this->warn("Failed writing to file. Closing appender."); |
|
151 $this->closed = true; |
|
152 } |
|
153 } |
|
154 |
|
155 public function activateOptions() { |
|
156 if (empty($this->file)) { |
|
157 $this->warn("Required parameter 'file' not set. Closing appender."); |
|
158 $this->closed = true; |
|
159 return; |
|
160 } |
|
161 } |
|
162 |
|
163 public function close() { |
|
164 if (is_resource($this->fp)) { |
|
165 $this->write($this->layout->getFooter()); |
|
166 fclose($this->fp); |
|
167 } |
|
168 $this->fp = null; |
|
169 $this->closed = true; |
|
170 } |
|
171 |
|
172 public function append(LoggerLoggingEvent $event) { |
|
173 $this->write($this->layout->format($event)); |
|
174 } |
|
175 |
|
176 /** |
|
177 * Sets the 'file' parameter. |
|
178 * @param string $file |
|
179 */ |
|
180 public function setFile($file) { |
|
181 $this->setString('file', $file); |
|
182 } |
|
183 |
|
184 /** |
|
185 * Returns the 'file' parameter. |
|
186 * @return string |
|
187 */ |
|
188 public function getFile() { |
|
189 return $this->file; |
|
190 } |
|
191 |
|
192 /** |
|
193 * Returns the 'append' parameter. |
|
194 * @return boolean |
|
195 */ |
|
196 public function getAppend() { |
|
197 return $this->append; |
|
198 } |
|
199 |
|
200 /** |
|
201 * Sets the 'append' parameter. |
|
202 * @param boolean $append |
|
203 */ |
|
204 public function setAppend($append) { |
|
205 $this->setBoolean('append', $append); |
|
206 } |
|
207 |
|
208 /** |
|
209 * Sets the 'file' parmeter. Left for legacy reasons. |
|
210 * @param string $fileName |
|
211 * @deprecated Use setFile() instead. |
|
212 */ |
|
213 public function setFileName($fileName) { |
|
214 $this->setFile($fileName); |
|
215 } |
|
216 |
|
217 /** |
|
218 * Returns the 'file' parmeter. Left for legacy reasons. |
|
219 * @return string |
|
220 * @deprecated Use getFile() instead. |
|
221 */ |
|
222 public function getFileName() { |
|
223 return $this->getFile(); |
|
224 } |
|
225 } |