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

📄 rollingfileappender.cs

📁 精通SQL Server2005项目开发
💻 CS
📖 第 1 页 / 共 4 页
字号:
		/// Does the work of bumping the 'current' file counter higher
		/// to the highest count when an incremental file name is seen.
		/// The highest count is either the first file (when count direction
		/// is greater than 0) or the last file (when count direction less than 0).
		/// In either case, we want to know the highest count that is present.
		/// </summary>
		/// <param name="baseFile"></param>
		/// <param name="curFileName"></param>
		private void InitializeFromOneFile(string baseFile, string curFileName)
		{
			if (! curFileName.StartsWith(baseFile) )
			{
				// This is not a log file, so ignore
				return;
			}
			if (curFileName.Equals(baseFile)) 
			{
				// Base log file is not an incremented logfile (.1 or .2, etc)
				return;
			}
	
			int index = curFileName.LastIndexOf(".");
			if (-1 == index) 
			{
				// This is not an incremented logfile (.1 or .2)
				return;
			}
	
			if (m_staticLogFileName) 
			{
				int endLength = curFileName.Length - index;
				if (baseFile.Length + endLength != curFileName.Length) 
				{
					// file is probably scheduledFilename + .x so I don't care
					return;
				}
			}
	
			// Only look for files in the current roll point
			if (m_rollDate && !m_staticLogFileName)
			{
				if (! curFileName.StartsWith(baseFile + m_dateTime.Now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo)))
				{
					LogLog.Debug("RollingFileAppender: Ignoring file ["+curFileName+"] because it is from a different date period");
					return;
				}
			}

			try 
			{
				// Bump the counter up to the highest count seen so far
				int backup;
				if (SystemInfo.TryParse(curFileName.Substring(index + 1), out backup))
				{
					if (backup > m_curSizeRollBackups)
					{
						if (0 == m_maxSizeRollBackups)
						{
							// Stay at zero when zero backups are desired
						}
						else if (-1 == m_maxSizeRollBackups)
						{
							// Infinite backups, so go as high as the highest value
							m_curSizeRollBackups = backup;
						}
						else
						{
							// Backups limited to a finite number
							if (m_countDirection >= 0) 
							{
								// Go with the highest file when counting up
								m_curSizeRollBackups = backup;
							} 
							else
							{
								// Clip to the limit when counting down
								if (backup <= m_maxSizeRollBackups)
								{
									m_curSizeRollBackups = backup;
								}
							}
						}
						LogLog.Debug("RollingFileAppender: File name ["+curFileName+"] moves current count to ["+m_curSizeRollBackups+"]");
					}
				}
			} 
			catch(FormatException) 
			{
				//this happens when file.log -> file.log.yyyy-mm-dd which is normal
				//when staticLogFileName == false
				LogLog.Debug("RollingFileAppender: Encountered a backup file not ending in .x ["+curFileName+"]");
			}
		}

		/// <summary>
		/// Takes a list of files and a base file name, and looks for 
		/// 'incremented' versions of the base file.  Bumps the max
		/// count up to the highest count seen.
		/// </summary>
		/// <param name="baseFile"></param>
		/// <param name="arrayFiles"></param>
		private void InitializeRollBackups(string baseFile, ArrayList arrayFiles)
		{
			if (null != arrayFiles)
			{
				string baseFileLower = baseFile.ToLower(System.Globalization.CultureInfo.InvariantCulture);

				foreach(string curFileName in arrayFiles)
				{
					InitializeFromOneFile(baseFileLower, curFileName.ToLower(System.Globalization.CultureInfo.InvariantCulture));
				}
			}
		}

		/// <summary>
		/// Calculates the RollPoint for the datePattern supplied.
		/// </summary>
		/// <param name="datePattern">the date pattern to calculate the check period for</param>
		/// <returns>The RollPoint that is most accurate for the date pattern supplied</returns>
		/// <remarks>
		/// Essentially the date pattern is examined to determine what the
		/// most suitable roll point is. The roll point chosen is the roll point
		/// with the smallest period that can be detected using the date pattern
		/// supplied. i.e. if the date pattern only outputs the year, month, day 
		/// and hour then the smallest roll point that can be detected would be
		/// and hourly roll point as minutes could not be detected.
		/// </remarks>
		private RollPoint ComputeCheckPeriod(string datePattern) 
		{
			// s_date1970 is 1970-01-01 00:00:00 this is UniversalSortableDateTimePattern 
			// (based on ISO 8601) using universal time. This date is used for reference
			// purposes to calculate the resolution of the date pattern.

			// Get string representation of base line date
			string r0 = s_date1970.ToString(datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo);

			// Check each type of rolling mode starting with the smallest increment.
			for(int i = (int)RollPoint.TopOfMinute; i <= (int)RollPoint.TopOfMonth; i++) 
			{
				// Get string representation of next pattern
				string r1 = NextCheckDate(s_date1970, (RollPoint)i).ToString(datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo);

				LogLog.Debug("RollingFileAppender: Type = ["+i+"], r0 = ["+r0+"], r1 = ["+r1+"]");

				// Check if the string representations are different
				if (r0 != null && r1 != null && !r0.Equals(r1)) 
				{
					// Found highest precision roll point
					return (RollPoint)i;
				}
			}

			return RollPoint.InvalidRollPoint; // Deliberately head for trouble...
		}

		/// <summary>
		/// Initialize the appender based on the options set
		/// </summary>
		/// <remarks>
		/// <para>
		/// This is part of the <see cref="IOptionHandler"/> delayed object
		/// activation scheme. The <see cref="ActivateOptions"/> method must 
		/// be called on this object after the configuration properties have
		/// been set. Until <see cref="ActivateOptions"/> is called this
		/// object is in an undefined state and must not be used. 
		/// </para>
		/// <para>
		/// If any of the configuration properties are modified then 
		/// <see cref="ActivateOptions"/> must be called again.
		/// </para>
		/// <para>
		/// Sets initial conditions including date/time roll over information, first check,
		/// scheduledFilename, and calls <see cref="ExistingInit"/> to initialize
		/// the current number of backups.
		/// </para>
		/// </remarks>
		override public void ActivateOptions() 
		{
			if (m_rollDate && m_datePattern != null) 
			{
				m_now = m_dateTime.Now;
				m_rollPoint = ComputeCheckPeriod(m_datePattern);

				if (m_rollPoint == RollPoint.InvalidRollPoint)
				{
					throw new ArgumentException("Invalid RollPoint, unable to parse ["+m_datePattern+"]");
				}

				// next line added as this removes the name check in rollOver
				m_nextCheck = NextCheckDate(m_now, m_rollPoint);
			} 
			else 
			{
				if (m_rollDate)
				{
					ErrorHandler.Error("Either DatePattern or rollingStyle options are not set for ["+Name+"].");
				}
			}

			if (SecurityContext == null)
			{
				SecurityContext = SecurityContextProvider.DefaultProvider.CreateSecurityContext(this);
			}

			using(SecurityContext.Impersonate(this))
			{
				// Must convert the FileAppender's m_filePath to an absolute path before we
				// call ExistingInit(). This will be done by the base.ActivateOptions() but
				// we need to duplicate that functionality here first.
				base.File = ConvertToFullPath(base.File.Trim());

				// Store fully qualified base file name
				m_baseFileName = base.File;
			}

			if (m_rollDate && File != null && m_scheduledFilename == null)
			{
				m_scheduledFilename = File + m_now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo);
			}

			ExistingInit();
	
			base.ActivateOptions();
		}

		#endregion
  
		#region Roll File

		/// <summary>
		/// Rollover the file(s) to date/time tagged file(s).
		/// </summary>
		/// <param name="fileIsOpen">set to true if the file to be rolled is currently open</param>
		/// <remarks>
		/// <para>
		/// Rollover the file(s) to date/time tagged file(s).
		/// Resets curSizeRollBackups. 
		/// If fileIsOpen is set then the new file is opened (through SafeOpenFile).
		/// </para>
		/// </remarks>
		protected void RollOverTime(bool fileIsOpen) 
		{
			if (m_staticLogFileName) 
			{
				// Compute filename, but only if datePattern is specified
				if (m_datePattern == null) 
				{
					ErrorHandler.Error("Missing DatePattern option in rollOver().");
					return;
				}
	  
				//is the new file name equivalent to the 'current' one
				//something has gone wrong if we hit this -- we should only
				//roll over if the new file will be different from the old
				string dateFormat = m_now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo);
				if (m_scheduledFilename.Equals(File + dateFormat)) 
				{
					ErrorHandler.Error("Compare " + m_scheduledFilename + " : " + File + dateFormat);
					return;
				}
	  
				if (fileIsOpen)
				{
					// close current file, and rename it to datedFilename
					this.CloseFile();
				}
	  
				//we may have to roll over a large number of backups here
				for (int i = 1; i <= m_curSizeRollBackups; i++) 
				{
					string from = File + '.' + i;
					string to = m_scheduledFilename + '.' + i;
					RollFile(from, to);
				}
	  
				RollFile(File, m_scheduledFilename);
			}
	
			//We've cleared out the old date and are ready for the new
			m_curSizeRollBackups = 0; 
	
			//new scheduled name
			m_scheduledFilename = File + m_now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo);

			if (fileIsOpen)
			{
				// This will also close the file. This is OK since multiple close operations are safe.
				SafeOpenFile(m_baseFileName, false);
			}
		}
  
		/// <summary>
		/// Renames file <paramref name="fromFile"/> to file <paramref name="toFile"/>.
		/// </summary>
		/// <param name="fromFile">Name of existing file to roll.</param>
		/// <param name="toFile">New name for file.</param>
		/// <remarks>
		/// <para>
		/// Renames file <paramref name="fromFile"/> to file <paramref name="toFile"/>. It
		/// also checks for existence of target file and deletes if it does.
		/// </para>
		/// </remarks>
		protected void RollFile(string fromFile, string toFile) 
		{
			if (FileExists(fromFile))
			{
				// Delete the toFile if it exists
				DeleteFile(toFile);

				// We may not have permission to move the file, or the file may be locked
				try
				{
					LogLog.Debug("RollingFileAppender: Moving [" + fromFile + "] -> [" + toFile + "]");
					using(SecurityContext.Impersonate(this))
					{
						System.IO.File.Move(fromFile, toFile);
					}
				}
				catch(Exception moveEx)
				{
					ErrorHandler.Error("Exception while rolling file [" + fromFile + "] -> [" + toFile + "]", moveEx, ErrorCode.GenericFailure);
				}
			}
			else
			{
				LogLog.Warn("RollingFileAppender: Cannot RollFile [" + fromFile + "] -> [" + toFile + "]. Source does not exist");
			}
		}

		/// <summary>
		/// Test if a file exists at a specified path
		/// </summary>
		/// <param name="path">the path to the file</param>
		/// <returns>true if the file exists</returns>
		/// <remarks>
		/// <para>
		/// Test if a file exists at a specified path
		/// </para>
		/// </remarks>
		protected bool FileExists(string path)
		{
			using(SecurityContext.Impersonate(this))
			{
				return System.IO.File.Exists(path);
			}
		}
  
		/// <summary>
		/// Deletes the specified file if it exists.
		/// </summary>
		/// <param name="fileName">The file to delete.</param>
		/// <remarks>
		/// <para>
		/// Delete a file if is exists.
		/// The file is first moved to a new filename then deleted.
		/// This allows the file to be removed even when it cannot
		/// be deleted, but it still can be moved.
		/// </para>
		/// </remarks>
		protected void DeleteFile(string fileName) 
		{
			if (FileExists(fileName)) 
			{
				// We may not have permission to delete the file, or the file may be locked

				string fileToDelete = fileName;

				// Try to move the file to temp name.
				// If the file is locked we may still be able to move it
				string tempFileName = fileName + "." + Environment.TickCount + ".DeletePending";
				try
				{
					using(SecurityContext.Impersonate(this))
					{
						System.IO.File.Move(fileName, tempFileName);
					}
					fileToDelete = tempFileName;
				}
				catch(Exception moveEx)
				{
					LogLog.Debug("RollingFileAppender: Exception while moving file to be deleted [" + fileName + "] -> [" + tempFileName + "]", moveEx);
				}

				// Try to delete the file (either the original or the moved file)
				try
				{
					using(SecurityContext.Impersonate(this))

⌨️ 快捷键说明

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