using clearstatchache
[logging-log4php.git] / src / main / php / appenders / LoggerAppenderRollingFile.php
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 * @package log4php
19 */
20
21 /**
22 * LoggerAppenderRollingFile extends LoggerAppenderFile to backup the log files
23 * when they reach a certain size.
24 *
25 * This appender uses a layout.
26 *
27 * Parameters are:
28 * - file - The target file to write to
29 * - filename - The target file to write to (deprecated, use "file" instead).
30 * - append - Sets if the appender should append to the end of the file or overwrite content ("true" or "false")
31 * - maxBackupIndex - Set the maximum number of backup files to keep around (int)
32 * - maxFileSize - Set the maximum size that the output file is allowed to
33 * reach before being rolled over to backup files.
34 * Suffixes like "KB", "MB" or "GB" are allowed, f. e. "10KB" is interpreted as 10240
35 * - maximumFileSize - Alias to maxFileSize (deprecated, use "maxFileSize" instead)
36 *
37 * <p>Contributors: Sergio Strampelli.</p>
38 *
39 * An example:
40 *
41 * {@example ../../examples/php/appender_socket.php 19}
42 *
43 * {@example ../../examples/resources/appender_socket.properties 18}
44 *
45 * @version $Revision$
46 * @package log4php
47 * @subpackage appenders
48 */
49 class LoggerAppenderRollingFile extends LoggerAppenderFile {
50
51 /**
52 * Set the maximum size that the output file is allowed to reach
53 * before being rolled over to backup files.
54 *
55 * <p>In configuration files, the <var>MaxFileSize</var> option takes a
56 * long integer in the range 0 - 2^63. You can specify the value
57 * with the suffixes "KB", "MB" or "GB" so that the integer is
58 * interpreted being expressed respectively in kilobytes, megabytes
59 * or gigabytes. For example, the value "10KB" will be interpreted
60 * as 10240.</p>
61 * <p>The default maximum file size is 10MB.</p>
62 *
63 * <p>Note that MaxFileSize cannot exceed <b>2 GB</b>.</p>
64 *
65 * @var integer
66 */
67 private $maxFileSize = 10485760;
68
69 /**
70 * Set the maximum number of backup files to keep around.
71 *
72 * <p>The <var>MaxBackupIndex</var> option determines how many backup
73 * files are kept before the oldest is erased. This option takes
74 * a positive integer value. If set to zero, then there will be no
75 * backup files and the log file will be truncated when it reaches
76 * MaxFileSize.</p>
77 * <p>There is one backup file by default.</p>
78 *
79 * @var integer
80 */
81 private $maxBackupIndex = 1;
82
83 /**
84 * @var string the filename expanded
85 */
86 private $expandedFileName = null;
87
88 public function __destruct() {
89 parent::__destruct();
90 }
91
92 /**
93 * Returns the value of the MaxBackupIndex option.
94 * @return integer
95 */
96 private function getExpandedFileName() {
97 return $this->expandedFileName;
98 }
99
100 /**
101 * Get the maximum size that the output file is allowed to reach
102 * before being rolled over to backup files.
103 * @return integer
104 */
105 public function getMaximumFileSize() {
106 return $this->maxFileSize;
107 }
108
109 /**
110 * Implements the usual roll over behaviour.
111 *
112 * <p>If MaxBackupIndex is positive, then files File.1, ..., File.MaxBackupIndex -1 are renamed to File.2, ..., File.MaxBackupIndex.
113 * Moreover, File is renamed File.1 and closed. A new File is created to receive further log output.
114 *
115 * <p>If MaxBackupIndex is equal to zero, then the File is truncated with no backup files created.
116 */
117 private function rollOver() {
118 // If maxBackups <= 0, then there is no file renaming to be done.
119 if($this->maxBackupIndex > 0) {
120 $fileName = $this->getExpandedFileName();
121 // Delete the oldest file, to keep Windows happy.
122 $file = $fileName . '.' . $this->maxBackupIndex;
123 if(is_writable($file))
124 unlink($file);
125 // Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3, 2}
126 for($i = $this->maxBackupIndex - 1; $i >= 1; $i--) {
127 $file = $fileName . "." . $i;
128 if(is_readable($file)) {
129 $target = $fileName . '.' . ($i + 1);
130 rename($file, $target);
131 }
132 }
133
134 $this->close();
135
136 // Rename fileName to fileName.1
137 $target = $fileName . ".1";
138 $file = $fileName;
139 rename($file, $target);
140 }
141
142 //unset($this->fp);
143 $this->setFile($fileName);
144 $this->activateOptions();
145 }
146
147 public function setFile($fileName) {
148 $this->file = $fileName;
149 // As LoggerAppenderFile does not create the directory, it has to exist.
150 // realpath() fails if the argument does not exist so the filename is separated.
151 $this->expandedFileName = realpath(dirname($fileName));
152 if ($this->expandedFileName === false) throw new Exception("Directory of $fileName does not exist!");
153 $this->expandedFileName .= DIRECTORY_SEPARATOR . basename($fileName);
154 }
155
156
157 /**
158 * Set the maximum number of backup files to keep around.
159 *
160 * <p>The <b>MaxBackupIndex</b> option determines how many backup
161 * files are kept before the oldest is erased. This option takes
162 * a positive integer value. If set to zero, then there will be no
163 * backup files and the log file will be truncated when it reaches
164 * MaxFileSize.
165 *
166 * @param mixed $maxBackups
167 */
168 public function setMaxBackupIndex($maxBackups) {
169 if(is_numeric($maxBackups)) {
170 $this->maxBackupIndex = abs((int)$maxBackups);
171 }
172 }
173
174 /**
175 * Set the maximum size that the output file is allowed to reach
176 * before being rolled over to backup files.
177 *
178 * @param mixed $maxFileSize
179 * @see setMaxFileSize()
180 * @deprecated
181 */
182 public function setMaximumFileSize($maxFileSize) {
183 return $this->setMaxFileSize($maxFileSize);
184 }
185
186 /**
187 * Set the maximum size that the output file is allowed to reach
188 * before being rolled over to backup files.
189 * <p>In configuration files, the <b>maxFileSize</b> option takes an
190 * long integer in the range 0 - 2^63. You can specify the value
191 * with the suffixes "KB", "MB" or "GB" so that the integer is
192 * interpreted being expressed respectively in kilobytes, megabytes
193 * or gigabytes. For example, the value "10KB" will be interpreted
194 * as 10240.
195 *
196 * @param mixed $value
197 * @return the actual file size set
198 */
199 public function setMaxFileSize($value) {
200 $maxFileSize = null;
201 $numpart = substr($value,0, strlen($value) -2);
202 $suffix = strtoupper(substr($value, -2));
203
204 switch($suffix) {
205 case 'KB': $maxFileSize = (int)((int)$numpart * 1024); break;
206 case 'MB': $maxFileSize = (int)((int)$numpart * 1024 * 1024); break;
207 case 'GB': $maxFileSize = (int)((int)$numpart * 1024 * 1024 * 1024); break;
208 default:
209 if(is_numeric($value)) {
210 $maxFileSize = (int)$value;
211 }
212 }
213
214 if($maxFileSize !== null) {
215 $this->maxFileSize = abs($maxFileSize);
216 }
217 return $this->maxFileSize;
218 }
219
220 /**
221 * @param LoggerLoggingEvent $event
222 */
223 public function append(LoggerLoggingEvent $event) {
224 parent::append($event);
225 if((ftell($this->fp) > $this->getMaxFileSize()) && flock($this->fp, LOCK_EX)) {
226 clearstatcache();
227 if(ftell($this->fp) > $this->getMaxFileSize()) {
228 $this->rollOver();
229 }
230 }
231
232 }
233
234 /**
235 * @return Returns the maximum number of backup files to keep around.
236 */
237 public function getMaxBackupIndex() {
238 return $this->maxBackupIndex;
239 }
240
241 /**
242 * @return Returns the maximum size that the output file is allowed to reach
243 * before being rolled over to backup files.
244 */
245 public function getMaxFileSize() {
246 return $this->maxFileSize;
247 }
248 }