⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileappender.cs

📁 精通SQL Server2005项目开发
💻 CS
📖 第 1 页 / 共 3 页
字号:
			{
				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
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -