?? fileappender.cs
字號(hào):
{
m_fileName = ConvertToFullPath(m_fileName.Trim());
}
if (m_fileName != null)
{
SafeOpenFile(m_fileName, m_appendToFile);
}
else
{
LogLog.Warn("FileAppender: File option not set for appender ["+Name+"].");
LogLog.Warn("FileAppender: Are you using FileAppender instead of ConsoleAppender?");
}
}
#endregion Override implementation of AppenderSkeleton
#region Override implementation of TextWriterAppender
/// <summary>
/// Closes any previously opened file and calls the parent's <see cref="TextWriterAppender.Reset"/>.
/// </summary>
/// <remarks>
/// <para>
/// Resets the filename and the file stream.
/// </para>
/// </remarks>
override protected void Reset()
{
base.Reset();
m_fileName = null;
}
/// <summary>
/// Called to initialize the file writer
/// </summary>
/// <remarks>
/// <para>
/// Will be called for each logged message until the file is
/// successfully opened.
/// </para>
/// </remarks>
override protected void PrepareWriter()
{
SafeOpenFile(m_fileName, m_appendToFile);
}
/// <summary>
/// This method is called by the <see cref="AppenderSkeleton.DoAppend(LoggingEvent)"/>
/// method.
/// </summary>
/// <param name="loggingEvent">The event to log.</param>
/// <remarks>
/// <para>
/// Writes a log statement to the output stream if the output stream exists
/// and is writable.
/// </para>
/// <para>
/// The format of the output will depend on the appender's layout.
/// </para>
/// </remarks>
override protected void Append(LoggingEvent loggingEvent)
{
if (m_stream.AcquireLock())
{
try
{
base.Append(loggingEvent);
}
finally
{
m_stream.ReleaseLock();
}
}
}
/// <summary>
/// This method is called by the <see cref="AppenderSkeleton.DoAppend(LoggingEvent[])"/>
/// method.
/// </summary>
/// <param name="loggingEvents">The array of events to log.</param>
/// <remarks>
/// <para>
/// Acquires the output file locks once before writing all the events to
/// the stream.
/// </para>
/// </remarks>
override protected void Append(LoggingEvent[] loggingEvents)
{
if (m_stream.AcquireLock())
{
try
{
base.Append(loggingEvents);
}
finally
{
m_stream.ReleaseLock();
}
}
}
/// <summary>
/// Writes a footer as produced by the embedded layout's <see cref="ILayout.Footer"/> property.
/// </summary>
/// <remarks>
/// <para>
/// Writes a footer as produced by the embedded layout's <see cref="ILayout.Footer"/> property.
/// </para>
/// </remarks>
protected override void WriteFooter()
{
if (m_stream!=null)
{
//WriteFooter can be called even before a file is opened
m_stream.AcquireLock();
try
{
base.WriteFooter();
}
finally
{
m_stream.ReleaseLock();
}
}
}
/// <summary>
/// Writes a header produced by the embedded layout's <see cref="ILayout.Header"/> property.
/// </summary>
/// <remarks>
/// <para>
/// Writes a header produced by the embedded layout's <see cref="ILayout.Header"/> property.
/// </para>
/// </remarks>
protected override void WriteHeader()
{
if (m_stream!=null)
{
if (m_stream.AcquireLock())
{
try
{
base.WriteHeader();
}
finally
{
m_stream.ReleaseLock();
}
}
}
}
/// <summary>
/// Closes the underlying <see cref="TextWriter"/>.
/// </summary>
/// <remarks>
/// <para>
/// Closes the underlying <see cref="TextWriter"/>.
/// </para>
/// </remarks>
protected override void CloseWriter()
{
if (m_stream!=null)
{
m_stream.AcquireLock();
try
{
base.CloseWriter();
}
finally
{
m_stream.ReleaseLock();
}
}
}
#endregion Override implementation of TextWriterAppender
#region Public Instance Methods
/// <summary>
/// Closes the previously opened file.
/// </summary>
/// <remarks>
/// <para>
/// Writes the <see cref="ILayout.Footer"/> to the file and then
/// closes the file.
/// </para>
/// </remarks>
protected void CloseFile()
{
WriteFooterAndCloseWriter();
}
#endregion Public Instance Methods
#region Protected Instance Methods
/// <summary>
/// Sets and <i>opens</i> the file where the log output will go. The specified file must be writable.
/// </summary>
/// <param name="fileName">The path to the log file. Must be a fully qualified path.</param>
/// <param name="append">If true will append to fileName. Otherwise will truncate fileName</param>
/// <remarks>
/// <para>
/// Calls <see cref="OpenFile"/> but guarantees not to throw an exception.
/// Errors are passed to the <see cref="TextWriterAppender.ErrorHandler"/>.
/// </para>
/// </remarks>
virtual protected void SafeOpenFile(string fileName, bool append)
{
try
OpenFile(fileName, append);
}
catch(Exception e)
{
ErrorHandler.Error("OpenFile("+fileName+","+append+") call failed.", e, ErrorCode.FileOpenFailure);
}
}
/// <summary>
/// Sets and <i>opens</i> the file where the log output will go. The specified file must be writable.
/// </summary>
/// <param name="fileName">The path to the log file. Must be a fully qualified path.</param>
/// <param name="append">If true will append to fileName. Otherwise will truncate fileName</param>
/// <remarks>
/// <para>
/// If there was already an opened file, then the previous file
/// is closed first.
/// </para>
/// <para>
/// This method will ensure that the directory structure
/// for the <paramref name="fileName"/> specified exists.
/// </para>
/// </remarks>
virtual protected void OpenFile(string fileName, bool append)
{
if (LogLog.IsErrorEnabled)
{
// Internal check that the fileName passed in is a rooted path
bool isPathRooted = false;
using(SecurityContext.Impersonate(this))
{
isPathRooted = Path.IsPathRooted(fileName);
}
if (!isPathRooted)
{
LogLog.Error("FileAppender: INTERNAL ERROR. OpenFile("+fileName+"): File name is not fully qualified.");
}
}
lock(this)
{
Reset();
LogLog.Debug("FileAppender: Opening file for writing ["+fileName+"] append ["+append+"]");
// Save these for later, allowing retries if file open fails
m_fileName = fileName;
m_appendToFile = append;
LockingModel.CurrentAppender=this;
LockingModel.OpenFile(fileName,append,m_encoding);
m_stream=new LockingStream(LockingModel);
if (m_stream != null)
{
m_stream.AcquireLock();
try
{
SetQWForFiles(new StreamWriter(m_stream, m_encoding));
}
finally
{
m_stream.ReleaseLock();
}
}
WriteHeader();
}
}
/// <summary>
/// Sets the quiet writer used for file output
/// </summary>
/// <param name="fileStream">the file stream that has been opened for writing</param>
/// <remarks>
/// <para>
/// This implementation of <see cref="SetQWForFiles(Stream)"/> creates a <see cref="StreamWriter"/>
/// over the <paramref name="fileStream"/> and passes it to the
/// <see cref="SetQWForFiles(TextWriter)"/> method.
/// </para>
/// <para>
/// This method can be overridden by sub classes that want to wrap the
/// <see cref="Stream"/> in some way, for example to encrypt the output
/// data using a <c>System.Security.Cryptography.CryptoStream</c>.
/// </para>
/// </remarks>
virtual protected void SetQWForFiles(Stream fileStream)
{
SetQWForFiles(new StreamWriter(fileStream, m_encoding));
}
/// <summary>
/// Sets the quiet writer being used.
/// </summary>
/// <param name="writer">the writer over the file stream that has been opened for writing</param>
/// <remarks>
/// <para>
/// This method can be overridden by sub classes that want to
/// wrap the <see cref="TextWriter"/> in some way.
/// </para>
/// </remarks>
virtual protected void SetQWForFiles(TextWriter writer)
{
QuietWriter = new QuietTextWriter(writer, ErrorHandler);
}
#endregion Protected Instance Methods
#region Protected Static Methods
/// <summary>
/// Convert a path into a fully qualified path.
/// </summary>
/// <param name="path">The path to convert.</param>
/// <returns>The fully qualified path.</returns>
/// <remarks>
/// <para>
/// Converts the path specified to a fully
/// qualified path. If the path is relative it is
/// taken as relative from the application base
/// directory.
/// </para>
/// </remarks>
protected static string ConvertToFullPath(string path)
{
return SystemInfo.ConvertToFullPath(path);
}
#endregion Protected Static Methods
#region Private Instance Fields
/// <summary>
/// Flag to indicate if we should append to the file
/// or overwrite the file. The default is to append.
/// </summary>
private bool m_appendToFile = true;
/// <summary>
/// The name of the log file.
/// </summary>
private string m_fileName = null;
/// <summary>
/// The encoding to use for the file stream.
/// </summary>
private Encoding m_encoding = Encoding.Default;
/// <summary>
/// The security context to use for privileged calls
/// </summary>
private SecurityContext m_securityContext;
/// <summary>
/// The stream to log to. Has added locking semantics
/// </summary>
private FileAppender.LockingStream m_stream = null;
/// <summary>
/// The locking model to use
/// </summary>
private FileAppender.LockingModelBase m_lockingModel = new FileAppender.ExclusiveLock();
#endregion Private Instance Fields
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -