00001 /******************************************************************************* 00002 00003 @file FileAppender.d 00004 00005 Copyright (c) 2004 Kris Bell 00006 00007 This software is provided 'as-is', without any express or implied 00008 warranty. In no event will the authors be held liable for damages 00009 of any kind arising from the use of this software. 00010 00011 Permission is hereby granted to anyone to use this software for any 00012 purpose, including commercial applications, and to alter it and/or 00013 redistribute it freely, subject to the following restrictions: 00014 00015 1. The origin of this software must not be misrepresented; you must 00016 not claim that you wrote the original software. If you use this 00017 software in a product, an acknowledgment within documentation of 00018 said product would be appreciated but is not required. 00019 00020 2. Altered source versions must be plainly marked as such, and must 00021 not be misrepresented as being the original software. 00022 00023 3. This notice may not be removed or altered from any distribution 00024 of the source. 00025 00026 4. Derivative works are permitted, but they must carry this notice 00027 in full and credit the original source. 00028 00029 00030 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00031 00032 00033 @version Initial version, May 2004 00034 @author Kris 00035 00036 00037 *******************************************************************************/ 00038 00039 module mango.log.FileAppender; 00040 00041 private import mango.log.Appender; 00042 00043 version (Isolated) 00044 { 00045 private import std.stream; 00046 00047 /******************************************************************************* 00048 00049 Append log messages to a file. This basic version has no rollover 00050 support, so it just keeps on adding to the file. There's also a 00051 RollingFileAppender that may suit your needs. 00052 00053 *******************************************************************************/ 00054 00055 public class FileAppender : Appender 00056 { 00057 private static uint mask; 00058 private File file; 00059 00060 /*********************************************************************** 00061 00062 Get a unique fingerprint for this class 00063 00064 ***********************************************************************/ 00065 00066 static this() 00067 { 00068 mask = nextMask(); 00069 } 00070 00071 /*********************************************************************** 00072 00073 ***********************************************************************/ 00074 00075 protected this () 00076 { 00077 } 00078 00079 /*********************************************************************** 00080 00081 Create a basic FileAppender to a file with the specified 00082 path. 00083 00084 ***********************************************************************/ 00085 00086 this (char[] fp) 00087 { 00088 setFile (new File (fp, FileMode.OutNew)); 00089 } 00090 00091 /*********************************************************************** 00092 00093 Create a basic FileAppender to a file with the specified 00094 path, and with the given Layout 00095 00096 ***********************************************************************/ 00097 00098 this (char[] fp, Layout layout) 00099 { 00100 this (fp); 00101 setLayout (layout); 00102 } 00103 00104 /*********************************************************************** 00105 00106 Return the file 00107 00108 ***********************************************************************/ 00109 00110 File getFile () 00111 { 00112 return file; 00113 } 00114 00115 /*********************************************************************** 00116 00117 Set the file 00118 00119 ***********************************************************************/ 00120 00121 protected void setFile (File file) 00122 { 00123 this.file = file; 00124 } 00125 00126 /*********************************************************************** 00127 00128 Return the fingerprint for this class 00129 00130 ***********************************************************************/ 00131 00132 uint getMask () 00133 { 00134 return mask; 00135 } 00136 00137 /*********************************************************************** 00138 00139 Return the name of this class 00140 00141 ***********************************************************************/ 00142 00143 char[] getName () 00144 { 00145 return this.classinfo.name; 00146 } 00147 00148 /*********************************************************************** 00149 00150 Append an event to the output. 00151 00152 ***********************************************************************/ 00153 00154 synchronized void append (Event event) 00155 { 00156 Layout layout = getLayout; 00157 file.writeString (layout.header (event)); 00158 file.writeString (layout.content (event)); 00159 file.writeString (layout.footer (event)); 00160 file.writeLine (null); 00161 file.flush (); 00162 } 00163 00164 /*********************************************************************** 00165 00166 Close the file associated with this Appender 00167 00168 ***********************************************************************/ 00169 00170 synchronized void close () 00171 { 00172 if (file) 00173 { 00174 file.close(); 00175 file = null; 00176 } 00177 } 00178 } 00179 } 00180 00181 else 00182 00183 { 00184 private import mango.io.Buffer, 00185 mango.io.FileConst, 00186 mango.io.FileConduit; 00187 00188 private import mango.io.model.IConduit; 00189 00190 /******************************************************************************* 00191 00192 Append log messages to a file. This basic version has no rollover 00193 support, so it just keeps on adding to the file. There's also a 00194 RollingFileAppender that may suit your needs. 00195 00196 *******************************************************************************/ 00197 00198 public class FileAppender : Appender 00199 { 00200 private static uint mask; 00201 private Buffer buffer; 00202 private IConduit conduit; 00203 00204 /*********************************************************************** 00205 00206 Get a unique fingerprint for this class 00207 00208 ***********************************************************************/ 00209 00210 static this() 00211 { 00212 mask = nextMask(); 00213 } 00214 00215 /*********************************************************************** 00216 00217 ***********************************************************************/ 00218 00219 protected this () 00220 { 00221 } 00222 00223 /*********************************************************************** 00224 00225 Create a basic FileAppender to a file with the specified 00226 path. 00227 00228 ***********************************************************************/ 00229 00230 this (FilePath fp) 00231 { 00232 setConduit (new FileConduit (fp, FileStyle.WriteAppending)); 00233 } 00234 00235 /*********************************************************************** 00236 00237 Create a basic FileAppender to a file with the specified 00238 path, and with the given Layout 00239 00240 ***********************************************************************/ 00241 00242 this (FilePath fp, Layout layout) 00243 { 00244 this (fp); 00245 setLayout (layout); 00246 } 00247 00248 /*********************************************************************** 00249 00250 Return the conduit 00251 00252 ***********************************************************************/ 00253 00254 IConduit getConduit () 00255 { 00256 return conduit; 00257 } 00258 00259 /*********************************************************************** 00260 00261 Set the conduit 00262 00263 ***********************************************************************/ 00264 00265 protected Buffer setConduit (IConduit conduit) 00266 { 00267 // create a new buffer upon this conduit 00268 this.conduit = conduit; 00269 return (buffer = new Buffer(conduit)); 00270 } 00271 00272 /*********************************************************************** 00273 00274 Return the fingerprint for this class 00275 00276 ***********************************************************************/ 00277 00278 uint getMask () 00279 { 00280 return mask; 00281 } 00282 00283 /*********************************************************************** 00284 00285 Return the name of this class 00286 00287 ***********************************************************************/ 00288 00289 char[] getName () 00290 { 00291 return this.classinfo.name; 00292 } 00293 00294 /*********************************************************************** 00295 00296 Append an event to the output. 00297 00298 ***********************************************************************/ 00299 00300 synchronized void append (Event event) 00301 { 00302 Layout layout = getLayout; 00303 buffer.append (layout.header (event)); 00304 buffer.append (layout.content (event)); 00305 buffer.append (layout.footer (event)) 00306 .append (FileConst.NewlineString) 00307 .flush (); 00308 } 00309 00310 /*********************************************************************** 00311 00312 Close the file associated with this Appender 00313 00314 ***********************************************************************/ 00315 00316 synchronized void close () 00317 { 00318 if (conduit) 00319 { 00320 conduit.close(); 00321 conduit = null; 00322 } 00323 } 00324 } 00325 } 00326