We are encountering this issue sporadically when our application (a Windows
Service) is restarted.
I attached the methods I needed to change to correct the problem below (all
from FileAppender.cs).
I have a somewhat outdated code base, so it my require some minor changes to
include it.
We are also encountering another, similar problem when the file rolls over
(RollingFileAppender).
In short, we have some monitoring tools that periodically scan the log file for
errors. If one of them happens to be scanning the file at the exact instant
that it rolls over, the rename fails, but the re-open succeeds and the file is
truncated (since the scanning tool opens it with AllowReadWrite).
This causes us to lose an entire log file, which is unacceptable.
I am considering catching the specific exception which is thrown when the file
has been opened by another process and retrying until the lock clears. I think
delaying the rollover until next time something is logged would be a better
solution, but I don't see convenient way to do that.
Any thoughts?
Dave
/// <summary>
/// Closes any previously opened file and calls the parent's <see
cref="TextWriterAppender.Reset"/>.
/// </summary>
override protected void Reset()
{
base.Reset();
}
/// <summary>
/// This method determines if there is a sense in attempting to append.
/// </summary>
/// <remarks>
/// <para>
/// Checks if we should force the file to be open, and if so, tries
/// to open it is it isn't open
/// </para>
/// </remarks>
/// <returns><c>false</c> if any of the preconditions fail.</returns>
override protected bool PreAppendCheck()
{
if (m_qtw == null || m_qtw.Closed)
{
try
{
OpenFile(m_fileName, m_appendToFile);
}
catch(Exception e)
{
ErrorHandler.Error("OpenFile("+m_fileName+","+m_appendToFile+") call failed.",
e, ErrorCodes.FileOpenFailure);
}
}
return base.PreAppendCheck();
}
/// <summary>
/// Activate the options on the file appender. This will
/// case the file to be opened.
/// </summary>
override public void ActivateOptions()
{
base.ActivateOptions();
if (m_fileName != null)
{
try
{
OpenFile(m_fileName, m_appendToFile);
}
catch(Exception e)
{
ErrorHandler.Error("OpenFile("+m_fileName+","+m_appendToFile+") call failed.",
e, ErrorCodes.FileOpenFailure);
}
}
else
{
LogLog.Warn("FileAppender: File option not set for appender
["+Name+"].");
LogLog.Warn("FileAppender: Are you using FileAppender instead
of ConsoleAppender?");
}
}