You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4net-dev@logging.apache.org by rg...@apache.org on 2008/10/25 04:00:07 UTC

svn commit: r707809 - /logging/log4net/trunk/src/Appender/RollingFileAppender.cs

Author: rgrabowski
Date: Fri Oct 24 19:00:07 2008
New Revision: 707809

URL: http://svn.apache.org/viewvc?rev=707809&view=rev
Log:
Fix for LOG4NET-64. Allow file extension to be preserved when rolling file.

Modified:
    logging/log4net/trunk/src/Appender/RollingFileAppender.cs

Modified: logging/log4net/trunk/src/Appender/RollingFileAppender.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Appender/RollingFileAppender.cs?rev=707809&r1=707808&r2=707809&view=diff
==============================================================================
--- logging/log4net/trunk/src/Appender/RollingFileAppender.cs (original)
+++ logging/log4net/trunk/src/Appender/RollingFileAppender.cs Fri Oct 24 19:00:07 2008
@@ -452,7 +452,27 @@
 				}
 			}
 		}
-  
+
+        /// <summary>
+        /// Gets or sets a value indicating whether to preserve the file name extension when rolling.
+        /// </summary>
+        /// <value>
+        /// <c>true</c> if the file name extension should be preserved.
+        /// </value>
+        /// <remarks>
+        /// <para>
+        /// By default file.log is rolled to file.log.yyyy-MM-dd or file.log.curSizeRollBackup.
+        /// However, under Windows the new file name will loose any program associations as the
+        /// extension is changed. Optionally file.log can be renamed to file.yyyy-MM-dd.log or
+        /// file.curSizeRollBackup.log to maintain any program associations.
+        /// </para>
+        /// </remarks>
+        public bool PreserveLogFileNameExtension
+        {
+            get { return m_preserveLogFileNameExtension; }
+            set { m_preserveLogFileNameExtension = value; }
+        }
+
 		/// <summary>
 		/// Gets or sets a value indicating whether to always log to
 		/// the same file.
@@ -650,12 +670,12 @@
 
 				if (m_rollDate)
 				{
-					fileName = fileName + m_now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo);
+                    fileName = CombinePath(fileName, m_now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo));
 				}
 
 				if (m_countDirection >= 0) 
 				{
-					fileName = fileName + '.' + m_curSizeRollBackups;
+                    fileName = CombinePath(fileName, "." + m_curSizeRollBackups);
 				}
 			}
 
@@ -694,9 +714,16 @@
 		/// </summary>
 		/// <param name="baseFileName"></param>
 		/// <returns></returns>
-		private static string GetWildcardPatternForFile(string baseFileName)
+		private string GetWildcardPatternForFile(string baseFileName)
 		{
-			return baseFileName + '*';
+            if (m_preserveLogFileNameExtension)
+            {
+                return Path.GetFileNameWithoutExtension(baseFileName) + ".*" + Path.GetExtension(baseFileName);
+            }
+            else
+            {
+                return baseFileName + '*';
+            }
 		}
 
 		/// <summary>
@@ -727,7 +754,7 @@
 						for (int i = 0; i < files.Length; i++) 
 						{
 							string curFileName = Path.GetFileName(files[i]);
-							if (curFileName.StartsWith(baseFileName))
+							if (curFileName.StartsWith(Path.GetFileNameWithoutExtension(baseFileName)))
 							{
 								alFiles.Add(curFileName);
 							}
@@ -822,7 +849,7 @@
 		/// <param name="curFileName"></param>
 		private void InitializeFromOneFile(string baseFile, string curFileName)
 		{
-			if (! curFileName.StartsWith(baseFile) )
+            if (curFileName.StartsWith(Path.GetFileNameWithoutExtension(baseFile)) == false)
 			{
 				// This is not a log file, so ignore
 				return;
@@ -833,13 +860,7 @@
 				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;
@@ -849,64 +870,97 @@
 					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)))
+				if (! curFileName.StartsWith(CombinePath(baseFile, m_dateTime.Now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo))))
 				{
 					LogLog.Debug(declaringType, "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(declaringType, "File name ["+curFileName+"] moves current count to ["+m_curSizeRollBackups+"]");
-					}
-				}
+                int backup = GetBackUpIndex(curFileName);
+                
+                // caution: we might get a false positive when certain
+                // date patterns such as yyyyMMdd are used...those are
+                // valid number but aren't the kind of back up index
+                // we're looking for
+                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(declaringType, "File name [" + curFileName + "] moves current count to [" + m_curSizeRollBackups + "]");
+                }
 			} 
 			catch(FormatException) 
 			{
-				//this happens when file.log -> file.log.yyyy-mm-dd which is normal
+				//this happens when file.log -> file.log.yyyy-MM-dd which is normal
 				//when staticLogFileName == false
 				LogLog.Debug(declaringType, "Encountered a backup file not ending in .x ["+curFileName+"]");
 			}
 		}
 
-		/// <summary>
+        /// <summary>
+        /// Attempts to extract a number from the end of the file name that indicates
+        /// the number of the times the file has been rolled over.
+        /// </summary>
+        /// <remarks>
+        /// Certain date pattern extensions like yyyyMMdd will be parsed as valid backup indexes.
+        /// </remarks>
+        /// <param name="curFileName"></param>
+        /// <returns></returns>
+	    private int GetBackUpIndex(string curFileName)
+	    {
+            int backUpIndex = -1;
+            string fileName = curFileName;
+
+            if (m_preserveLogFileNameExtension)
+            {
+                fileName = Path.GetFileNameWithoutExtension(fileName);
+            }
+            
+            int index = fileName.LastIndexOf(".");
+            if (index > 0)
+            {
+                // if the "yyyy-MM-dd" component of file.log.yyyy-MM-dd is passed to TryParse
+                // it will gracefully fail and return backUpIndex will be 0
+                SystemInfo.TryParse(fileName.Substring(index + 1), out backUpIndex);
+            }
+
+            return backUpIndex;
+	    }
+
+	    /// <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.
@@ -1034,7 +1088,7 @@
 
 			if (m_rollDate && File != null && m_scheduledFilename == null)
 			{
-				m_scheduledFilename = File + m_now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo);
+                m_scheduledFilename = CombinePath(File, m_now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo));
 			}
 
 			ExistingInit();
@@ -1046,6 +1100,25 @@
   
 		#region Roll File
 
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="path1"></param>
+        /// <param name="path2">.1, .2, .3, etc.</param>
+        /// <returns></returns>
+        private string CombinePath(string path1, string path2)
+        {
+            string extension = Path.GetExtension(path1);
+            if (m_preserveLogFileNameExtension && extension.Length > 0)
+            {
+                return Path.Combine(Path.GetDirectoryName(path1), Path.GetFileNameWithoutExtension(path1) + path2 + extension);
+            }
+            else
+            {
+                return path1 + path2;
+            }
+        }
+
 		/// <summary>
 		/// Rollover the file(s) to date/time tagged file(s).
 		/// </summary>
@@ -1072,9 +1145,9 @@
 				//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)) 
+                if (m_scheduledFilename.Equals(CombinePath(File, dateFormat))) 
 				{
-					ErrorHandler.Error("Compare " + m_scheduledFilename + " : " + File + dateFormat);
+                    ErrorHandler.Error("Compare " + m_scheduledFilename + " : " + CombinePath(File, dateFormat));
 					return;
 				}
 	  
@@ -1087,8 +1160,8 @@
 				//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;
+                    string from = CombinePath(File, "." + i);
+                    string to = CombinePath(m_scheduledFilename, "." + i);
 					RollFile(from, to);
 				}
 	  
@@ -1099,7 +1172,7 @@
 			m_curSizeRollBackups = 0; 
 	
 			//new scheduled name
-			m_scheduledFilename = File + m_now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo);
+            m_scheduledFilename = CombinePath(File, m_now.ToString(m_datePattern, System.Globalization.DateTimeFormatInfo.InvariantInfo));
 
 			if (fileIsOpen)
 			{
@@ -1308,20 +1381,20 @@
 					// Delete the oldest file, to keep Windows happy.
 					if (m_curSizeRollBackups == m_maxSizeRollBackups) 
 					{
-						DeleteFile(baseFileName + '.' + m_maxSizeRollBackups);
+                        DeleteFile(CombinePath(baseFileName, "." + m_maxSizeRollBackups));
 						m_curSizeRollBackups--;
 					}
 	
 					// Map {(maxBackupIndex - 1), ..., 2, 1} to {maxBackupIndex, ..., 3, 2}
 					for (int i = m_curSizeRollBackups; i >= 1; i--) 
 					{
-						RollFile((baseFileName + "." + i), (baseFileName + '.' + (i + 1)));
+                        RollFile((CombinePath(baseFileName, "." + i)), (CombinePath(baseFileName, "." + (i + 1))));
 					}
 	
 					m_curSizeRollBackups++;
 
 					// Rename fileName to fileName.1
-					RollFile(baseFileName, baseFileName + ".1");
+                    RollFile(baseFileName, CombinePath(baseFileName, ".1"));
 				} 
 				else 
 				{
@@ -1351,13 +1424,13 @@
 						}
 
 						// Delete the archive file
-						DeleteFile(archiveFileBaseName + '.' + oldestFileIndex);
+                        DeleteFile(CombinePath(archiveFileBaseName, "." + oldestFileIndex));
 					}
 	
 					if (m_staticLogFileName) 
 					{
 						m_curSizeRollBackups++;
-						RollFile(baseFileName, baseFileName + '.' + m_curSizeRollBackups);
+                        RollFile(baseFileName, CombinePath(baseFileName, "." + m_curSizeRollBackups));
 					}
 				}
 			}
@@ -1528,6 +1601,12 @@
 		/// </summary>
 		private bool m_staticLogFileName = true;
   
+   		/// <summary>
+		/// Value indicating whether to preserve the file name extension when rolling.
+		/// </summary>
+		private bool m_preserveLogFileNameExtension = false;
+
+
 		/// <summary>
 		/// FileName provided in configuration.  Used for rolling properly
 		/// </summary>