nicko 2004/11/17 14:17:53
Modified: src/Appender RollingFileAppender.cs
Log:
Added support for rolling the current file out of the way if not appending.
Added new rolling style 'Once' which rolls the file only when the appender is
configured.
Revision Changes Path
1.11 +162 -35 logging-log4net/src/Appender/RollingFileAppender.cs
Index: RollingFileAppender.cs
===================================================================
RCS file: /home/cvs/logging-log4net/src/Appender/RollingFileAppender.cs,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- RollingFileAppender.cs 12 Nov 2004 22:33:30 -0000 1.10
+++ RollingFileAppender.cs 17 Nov 2004 22:17:52 -0000 1.11
@@ -57,6 +57,9 @@
/// rolled once the date boundary specified in the <see
cref="DatePattern"/> property
/// is crossed, but within a date boundary the file will also be rolled
/// once its size exceeds the <see cref="MaximumFileSize"/>.
+ /// When set to <see cref="RollingMode.Once"/> the log file will be
rolled when
+ /// the appender is configured. This effectively means that the log
file can be
+ /// rolled once per program execution.
/// </para>
/// <para>
/// A of few additional optional features have been added:
@@ -130,6 +133,23 @@
public enum RollingMode
{
/// <summary>
+ /// Roll files once per program execution
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// Roll files once per program execution.
+ /// Well really once each time this appender is
+ /// configured.
+ /// </para>
+ /// <para>
+ /// Setting this option also sets <c>AppendToFile</c> to
+ /// <c>false</c> on the <c>RollingFileAppender</c>,
otherwise
+ /// this appender would just be a normal file appender.
+ /// </para>
+ /// </remarks>
+ Once = 0,
+
+ /// <summary>
/// Roll files based only on the size of the file
/// </summary>
Size = 1,
@@ -376,7 +396,15 @@
/// </summary>
/// <value>The rolling style.</value>
/// <remarks>
+ /// <para>
/// The default rolling style is <see
cref="RollingMode.Composite" />.
+ /// </para>
+ /// <para>
+ /// When set to <see cref="RollingMode.Once"/> this appender's
+ /// <see cref="FileAppender.AppendToFile"/> property is set to
<c>false</c>, otherwise
+ /// the appender would append to a single file rather than
rolling
+ /// the file each time it is opened.
+ /// </para>
/// </remarks>
public RollingMode RollingStyle
{
@@ -386,6 +414,13 @@
m_rollingStyle = value;
switch (m_rollingStyle)
{
+ case RollingMode.Once:
+ m_rollDate = false;
+ m_rollSize = false;
+
+ this.AppendToFile = false;
+ break;
+
case RollingMode.Size:
m_rollDate = false;
m_rollSize = true;
@@ -491,21 +526,8 @@
{
lock(this)
{
- if (!m_staticLogFileName)
- {
- m_scheduledFilename = fileName =
fileName.Trim();
-
- if (m_rollDate)
- {
- m_scheduledFilename = fileName
= fileName + m_now.ToString(m_datePattern,
System.Globalization.DateTimeFormatInfo.InvariantInfo);
- }
+ fileName = GetNextOutputFileName(fileName);
- if (m_countDirection > 0)
- {
- m_scheduledFilename = fileName
= fileName + '.' + (++m_curSizeRollBackups);
- }
- }
-
// Calculate the current size of the file
long currentCount = 0;
if (append)
@@ -518,6 +540,26 @@
}
}
}
+ else
+ {
+ // If not Appending to an existing file
we should have rolled the file out of the
+ // way. Therefore we should not be
overwirtting an existing file.
+ // The only exception is if we are not
allowed to roll the existing file away.
+ if (m_maxSizeRollBackups != 0 &&
FileExists(fileName))
+ {
+
LogLog.Error("RollingFileAppender: INTERNAL ERROR. Append is False but
OutputFile ["+fileName+"] already exists.");
+ }
+ }
+
+ if (!m_staticLogFileName)
+ {
+ m_scheduledFilename = fileName;
+
+ if (m_countDirection > 0)
+ {
+ m_curSizeRollBackups++;
+ }
+ }
// Open the file (call the base class to do it)
base.OpenFile(fileName, append);
@@ -527,6 +569,38 @@
}
}
+ /// <summary>
+ /// Get the current output file name
+ /// </summary>
+ /// <param name="fileName">the base file name</param>
+ /// <returns>the output file name</returns>
+ /// <remarks>
+ /// The output file name is based on the base fileName
specified.
+ /// If <see cref="StaticLogFileName"/> is set then the output
+ /// file name is the same as the base file passed in. Otherwise
+ /// the output file depends on the date pattern, on the count
+ /// direction or both.
+ /// </remarks>
+ protected string GetNextOutputFileName(string fileName)
+ {
+ if (!m_staticLogFileName)
+ {
+ fileName = fileName.Trim();
+
+ if (m_rollDate)
+ {
+ fileName = fileName +
m_now.ToString(m_datePattern,
System.Globalization.DateTimeFormatInfo.InvariantInfo);
+ }
+
+ if (m_countDirection > 0)
+ {
+ fileName = fileName + '.' +
(m_curSizeRollBackups + 1);
+ }
+ }
+
+ return fileName;
+ }
+
#endregion
#region Initialize Options
@@ -538,22 +612,12 @@
{
m_curSizeRollBackups = 0;
- string sName = null;
- if (m_staticLogFileName || !m_rollDate)
- {
- sName = m_baseFileName;
- }
- else
- {
- sName = m_scheduledFilename;
- }
-
string fullPath = null;
string fileName = null;
using(SecurityContext.Impersonate(this))
{
- fullPath = System.IO.Path.GetFullPath(sName);
+ fullPath =
System.IO.Path.GetFullPath(m_baseFileName);
fileName = System.IO.Path.GetFileName(fullPath);
}
@@ -656,6 +720,32 @@
{
DetermineCurSizeRollBackups();
RollOverIfDateBoundaryCrossing();
+
+ // If file exists and we are not appending then roll it
out of the way
+ if (AppendToFile == false)
+ {
+ bool fileExists = false;
+ string fileName =
GetNextOutputFileName(m_baseFileName);
+
+ using(SecurityContext.Impersonate(this))
+ {
+ fileExists =
System.IO.File.Exists(fileName);
+ }
+
+ if (fileExists)
+ {
+ if (m_maxSizeRollBackups == 0)
+ {
+
LogLog.Debug("RollingFileAppender: Output file ["+fileName+"] already exists.
MaxSizeRollBackups is 0; cannot roll. Overwriting existing file.");
+ }
+ else
+ {
+
LogLog.Debug("RollingFileAppender: Output file ["+fileName+"] already exists.
Not appending to file. Rolling existing file out of the way.");
+
+ RollOverRenameFiles(fileName);
+ }
+ }
+ }
}
/// <summary>
@@ -698,7 +788,7 @@
}
// Only look for files in the current roll point
- if (m_rollDate)
+ if (m_rollDate && !m_staticLogFileName)
{
if (! curFileName.StartsWith(baseFile +
m_dateTime.Now.ToString(m_datePattern,
System.Globalization.DateTimeFormatInfo.InvariantInfo)))
{
@@ -865,6 +955,11 @@
SecurityContext =
SecurityContextProvider.DefaultProvider.CreateSecurityContext(this);
}
+ using(SecurityContext.Impersonate(this))
+ {
+ m_baseFileName =
ConvertToFullPath(base.File.Trim());
+ }
+
ExistingInit();
base.ActivateOptions();
@@ -1053,7 +1148,41 @@
LogLog.Debug("RollingFileAppender: maxSizeRollBackups
["+m_maxSizeRollBackups+"]");
LogLog.Debug("RollingFileAppender: curSizeRollBackups
["+m_curSizeRollBackups+"]");
LogLog.Debug("RollingFileAppender: countDirection
["+m_countDirection+"]");
+
+ RollOverRenameFiles(File);
+ // This will also close the file. This is OK since
multiple close operations are safe.
+ SafeOpenFile(m_baseFileName, false);
+ }
+
+ /// <summary>
+ /// Implements file roll.
+ /// </summary>
+ /// <param name="baseFileName">the base name to rename</param>
+ /// <remarks>
+ /// <para>
+ /// If the maximum number of size based backups is reached
+ /// (<c>curSizeRollBackups == maxSizeRollBackups</c>) then the
oldest
+ /// file is deleted -- it's index determined by the sign of
countDirection.
+ /// If <c>countDirection</c> < 0, then files
+ /// {<c>File.1</c>, ..., <c>File.curSizeRollBackups -1</c>}
+ /// are renamed to {<c>File.2</c>, ...,
+ /// <c>File.curSizeRollBackups</c>}.
+ /// </para>
+ /// <para>
+ /// If <c>maxSizeRollBackups</c> is equal to zero, then the
+ /// <c>File</c> is truncated with no backup files created.
+ /// </para>
+ /// <para>
+ /// If <c>maxSizeRollBackups</c> < 0, then <c>File</c> is
+ /// renamed if needed and no files are deleted.
+ /// </para>
+ /// <para>
+ /// This is called by <see cref="RollOverSize"/> to rename the
files.
+ /// </para>
+ /// </remarks>
+ protected void RollOverRenameFiles(string baseFileName)
+ {
// If maxBackups <= 0, then there is no file renaming
to be done.
if (m_maxSizeRollBackups != 0)
{
@@ -1062,40 +1191,38 @@
// Delete the oldest file, to keep
Windows happy.
if (m_curSizeRollBackups ==
m_maxSizeRollBackups)
{
- DeleteFile(File + '.' +
m_maxSizeRollBackups);
+ DeleteFile(baseFileName + '.' +
m_maxSizeRollBackups);
m_curSizeRollBackups--;
}
// Map {(maxBackupIndex - 1), ..., 2,
1} to {maxBackupIndex, ..., 3, 2}
for (int i = m_curSizeRollBackups; i >=
1; i--)
{
- RollFile((File + "." + i),
(File + '.' + (i + 1)));
+ RollFile((baseFileName + "." +
i), (baseFileName + '.' + (i + 1)));
}
m_curSizeRollBackups++;
// Rename fileName to fileName.1
- RollFile(File, File + ".1");
+ RollFile(baseFileName, baseFileName +
".1");
}
else
- { //countDirection > 0
+ {
+ //countDirection > 0
if (m_curSizeRollBackups >=
m_maxSizeRollBackups && m_maxSizeRollBackups > 0)
{
//delete the first and keep
counting up.
int oldestFileIndex =
m_curSizeRollBackups - m_maxSizeRollBackups + 1;
- DeleteFile(File + '.' +
oldestFileIndex);
+ DeleteFile(baseFileName + '.' +
oldestFileIndex);
}
if (m_staticLogFileName)
{
m_curSizeRollBackups++;
- RollFile(File, File + '.' +
m_curSizeRollBackups);
+ RollFile(baseFileName,
baseFileName + '.' + m_curSizeRollBackups);
}
}
}
-
- // This will also close the file. This is OK since
multiple close operations are safe.
- SafeOpenFile(m_baseFileName, false);
}
#endregion