Mercurial > projects > ldc
diff tango/tango/util/log/RollingFileAppender.d @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tango/tango/util/log/RollingFileAppender.d Fri Jan 11 17:57:40 2008 +0100 @@ -0,0 +1,177 @@ +/******************************************************************************* + + copyright: Copyright (c) 2004 Kris Bell. All rights reserved + + license: BSD style: $(LICENSE) + + version: Initial release: May 2004 + + author: Kris + +*******************************************************************************/ + +module tango.util.log.RollingFileAppender; + +private import tango.time.Time; + +private import tango.io.FilePath, + tango.io.FileConst, + tango.io.FileConduit; + +private import tango.io.model.IBuffer; + +private import tango.util.log.Appender, + tango.util.log.FileAppender; + +/******************************************************************************* + + Append log messages to a file set. + +*******************************************************************************/ + +public class RollingFileAppender : FileAppender +{ + private Mask mask; + private FilePath[] paths; + private int index; + private IBuffer buffer; + private ulong maxSize, + fileSize; + + /*********************************************************************** + + Create a RollingFileAppender upon a file-set with the + specified path and optional layout. + + Where a file set already exists, we resume appending to + the one with the most recent activity timestamp. + + ***********************************************************************/ + + this (char[] path, int count, ulong maxSize, EventLayout layout = null) + { + assert (path); + assert (count > 1 && count < 10); + + // Get a unique fingerprint for this instance + mask = register (path); + + char[1] x; + Time mostRecent; + + for (int i=0; i < count; ++i) + { + x[0] = '0' + i; + + auto p = new FilePath (path); + p.name = p.name ~ x; + paths ~= p; + + // use the most recent file in the set + if (p.exists) + { + auto modified = p.modified; + if (modified > mostRecent) + { + mostRecent = modified; + index = i; + } + } + } + + // remember the maximum size + this.maxSize = maxSize; + + // adjust index and open the appropriate log file + --index; + nextFile (false); + + // set provided layout (ignored when null) + setLayout (layout); + } + + /*********************************************************************** + + Return the fingerprint for this class + + ***********************************************************************/ + + Mask getMask () + { + return mask; + } + + /*********************************************************************** + + Return the name of this class + + ***********************************************************************/ + + char[] getName () + { + return this.classinfo.name; + } + + /*********************************************************************** + + Append an event to the output. + + ***********************************************************************/ + + synchronized void append (Event event) + { + char[] msg; + + // file already full? + if (fileSize >= maxSize) + nextFile (true); + + // bump file size + fileSize += FileConst.NewlineString.length; + + // write log message and flush it + auto layout = getLayout (); + msg = layout.header (event); + fileSize += msg.length; + buffer.append (msg); + + msg = layout.content (event); + fileSize += msg.length; + buffer.append (msg); + + msg = layout.footer (event); + fileSize += msg.length; + buffer.append (msg); + + buffer.append(FileConst.NewlineString).flush; + } + + /*********************************************************************** + + Switch to the next file within the set + + ***********************************************************************/ + + private void nextFile (bool reset) + { + // select next file in the set + if (++index >= paths.length) + index = 0; + + // reset file size + fileSize = 0; + + // close any existing conduit + close; + + // make it shareable for read + auto style = FileConduit.WriteAppending; + style.share = FileConduit.Share.Read; + auto conduit = new FileConduit (paths[index], style); + + buffer = setConduit (conduit); + if (reset) + conduit.truncate; + } +} +