| Code Coverage
| Classes and Traits | Functions and Methods | Lines
Total |  | 0.00% | 0 / 1 |  | 42.86% | 6 / 14 | CRAP |  | 60.56% | 43 / 71
LoggerAppenderFile |  | 0.00% | 0 / 1 |  | 42.86% | 6 / 14 | 76.09 |  | 60.56% | 43 / 71
getTargetFile() |  | 100.00% | 1 / 1 | 1 |  | 100.00% | 1 / 1
openFile() |  | 0.00% | 0 / 1 | 11.03 |  | 56.52% | 13 / 23
write($string) |  | 0.00% | 0 / 1 | 4.18 |  | 77.78% | 7 / 9
writeWithLocking($string) |  | 0.00% | 0 / 1 | 4.12 |  | 50.00% | 5 / 10
writeWithoutLocking($string) |  | 0.00% | 0 / 1 | 6 |  | 0.00% | 0 / 5
activateOptions() |  | 0.00% | 0 / 1 | 2.26 |  | 60.00% | 3 / 5
close() |  | 100.00% | 1 / 1 | 2 |  | 100.00% | 7 / 7
append(LoggerLoggingEvent $event) |  | 100.00% | 1 / 1 | 1 |  | 100.00% | 2 / 2
setFile($file) |  | 100.00% | 1 / 1 | 1 |  | 100.00% | 2 / 2
getFile() |  | 100.00% | 1 / 1 | 1 |  | 100.00% | 1 / 1
getAppend() |  | 0.00% | 0 / 1 | 2 |  | 0.00% | 0 / 1
setAppend($append) |  | 100.00% | 1 / 1 | 1 |  | 100.00% | 2 / 2
setFileName($fileName) |  | 0.00% | 0 / 1 | 2 |  | 0.00% | 0 / 2
getFileName() |  | 0.00% | 0 / 1 | 2 |  | 0.00% | 0 / 1

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 | }