You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by bo...@apache.org on 2016/11/06 10:06:47 UTC

svn commit: r1768300 - in /logging/log4net/trunk: src/Core/ src/Layout/ src/Layout/Pattern/ src/Util/ tests/src/Core/ tests/src/Layout/

Author: bodewig
Date: Sun Nov  6 10:06:47 2016
New Revision: 1768300

URL: http://svn.apache.org/viewvc?rev=1768300&view=rev
Log:
use UTC time internally, patch by JocularJoe, closes #36

Modified:
    logging/log4net/trunk/src/Core/LoggingEvent.cs
    logging/log4net/trunk/src/Core/TimeEvaluator.cs
    logging/log4net/trunk/src/Layout/Pattern/RelativeTimePatternConverter.cs
    logging/log4net/trunk/src/Layout/Pattern/UtcDatePatternConverter.cs
    logging/log4net/trunk/src/Layout/RawUtcTimeStampLayout.cs
    logging/log4net/trunk/src/Layout/XmlLayoutSchemaLog4j.cs
    logging/log4net/trunk/src/Util/LogLog.cs
    logging/log4net/trunk/src/Util/OnlyOnceErrorHandler.cs
    logging/log4net/trunk/src/Util/SystemInfo.cs
    logging/log4net/trunk/tests/src/Core/FixingTest.cs
    logging/log4net/trunk/tests/src/Layout/XmlLayoutTest.cs

Modified: logging/log4net/trunk/src/Core/LoggingEvent.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Core/LoggingEvent.cs?rev=1768300&r1=1768299&r2=1768300&view=diff
==============================================================================
--- logging/log4net/trunk/src/Core/LoggingEvent.cs (original)
+++ logging/log4net/trunk/src/Core/LoggingEvent.cs Sun Nov  6 10:06:47 2016
@@ -88,16 +88,49 @@ namespace log4net.Core
 		public string ThreadName;
 
 		/// <summary>
-		/// The time the event was logged
+		/// Gets or sets the local time the event was logged
 		/// </summary>
 		/// <remarks>
-		/// <para>
-		/// The TimeStamp is stored in the local time zone for this computer.
+        /// <para>
+        /// Prefer using the <see cref="TimeStampUtc"/> setter, since local time can be ambiguous.
 		/// </para>
 		/// </remarks>
-		public DateTime TimeStamp;
+        [Obsolete("Prefer using TimeStampUtc, since local time can be ambiguous in time zones with daylight savings time.")]
+        public DateTime TimeStamp;
+
+        /// <summary>
+        /// Gets or sets the UTC time the event was logged
+        /// </summary>
+        /// <remarks>
+        /// <para>
+        /// The TimeStamp is stored in the UTC time zone.
+        /// </para>
+        /// </remarks>
+#pragma warning disable 618 // Suppress warnings that TimeStamp field is obsolete
+        public DateTime TimeStampUtc
+        {
+            get
+            {
+                if (TimeStamp != default(DateTime) && 
+                    _timeStampUtc == default(DateTime))
+                {
+                    // TimeStamp field has been set explicitly but TimeStampUtc hasn't
+                    // => use TimeStamp
+                    return TimeStamp.ToUniversalTime();
+                }
+                return _timeStampUtc;
+            }
+            set
+            {
+                _timeStampUtc = value;
+                // For backwards compatibility
+                TimeStamp = _timeStampUtc.ToLocalTime();
+            }
+        }
+        private DateTime _timeStampUtc;
+#pragma warning restore 618
 
-		/// <summary>
+        /// <summary>
 		/// Location information for the caller.
 		/// </summary>
 		/// <remarks>
@@ -334,7 +367,7 @@ namespace log4net.Core
 			m_data.Level = level;
 
 			// Store the event creation time
-			m_data.TimeStamp = DateTime.Now;
+			m_data.TimeStampUtc = DateTime.UtcNow;
 		}
 
 		/// <summary>
@@ -454,7 +487,7 @@ namespace log4net.Core
 
 			m_data.Message = info.GetString("Message");
 			m_data.ThreadName = info.GetString("ThreadName");
-			m_data.TimeStamp = info.GetDateTime("TimeStamp");
+			m_data.TimeStampUtc = info.GetDateTime("TimeStamp").ToUniversalTime();
 			m_data.LocationInfo = (LocationInfo) info.GetValue("LocationInfo", typeof(LocationInfo));
 			m_data.UserName = info.GetString("UserName");
 			m_data.ExceptionString = info.GetString("ExceptionString");
@@ -481,7 +514,7 @@ namespace log4net.Core
 		/// </value>
 		/// <remarks>
 		/// <para>
-		/// The TimeStamp is stored in the local time zone for this computer.
+		/// The TimeStamp is stored internally in UTC and converted to the local time zone for this computer.
 		/// </para>
 		/// <para>
 		/// Tries to get the start time for the current process.
@@ -496,7 +529,30 @@ namespace log4net.Core
 		/// </remarks>
 		public static DateTime StartTime
 		{
-			get { return SystemInfo.ProcessStartTime; }
+			get { return SystemInfo.ProcessStartTimeUtc.ToLocalTime(); }
+		}
+
+        /// <summary>
+        /// Gets the UTC time when the current process started.
+        /// </summary>
+        /// <value>
+        /// This is the UTC time when this process started.
+        /// </value>
+        /// <remarks>
+        /// <para>
+        /// Tries to get the start time for the current process.
+        /// Failing that it returns the time of the first call to
+        /// this property.
+        /// </para>
+        /// <para>
+        /// Note that AppDomains may be loaded and unloaded within the
+        /// same process without the process terminating and therefore
+        /// without the process start time being reset.
+        /// </para>
+        /// </remarks>
+        public static DateTime StartTimeUtc
+        {
+            get { return SystemInfo.ProcessStartTimeUtc; }
 		}
 
 		/// <summary>
@@ -523,12 +579,23 @@ namespace log4net.Core
 		/// </value>
 		/// <remarks>
 		/// <para>
-		/// The TimeStamp is stored in the local time zone for this computer.
+		/// The TimeStamp is stored in UTC and converted to the local time zone for this computer.
 		/// </para>
 		/// </remarks>
 		public DateTime TimeStamp
 		{
-			get { return m_data.TimeStamp; }
+			get { return m_data.TimeStampUtc.ToLocalTime(); }
+		}
+
+        /// <summary>
+        /// Gets UTC the time of the logging event.
+        /// </summary>
+        /// <value>
+        /// The UTC time of the logging event.
+        /// </value>
+        public DateTime TimeStampUtc
+        {
+            get { return m_data.TimeStampUtc; }
 		}
 
 		/// <summary>
@@ -1038,8 +1105,13 @@ namespace log4net.Core
 			info.AddValue("Level", m_data.Level);
 			info.AddValue("Message", m_data.Message);
 			info.AddValue("ThreadName", m_data.ThreadName);
+            // TODO: consider serializing UTC rather than local time.  Not implemented here because it
+            // would give an unexpected result if client and server have different versions of this class.
+            // info.AddValue("TimeStamp", m_data.TimeStampUtc);
+#pragma warning disable 618
 			info.AddValue("TimeStamp", m_data.TimeStamp);
-			info.AddValue("LocationInfo", m_data.LocationInfo);
+#pragma warning restore 618
+            info.AddValue("LocationInfo", m_data.LocationInfo);
 			info.AddValue("UserName", m_data.UserName);
 			info.AddValue("ExceptionString", m_data.ExceptionString);
 			info.AddValue("Properties", m_data.Properties);

Modified: logging/log4net/trunk/src/Core/TimeEvaluator.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Core/TimeEvaluator.cs?rev=1768300&r1=1768299&r2=1768300&view=diff
==============================================================================
--- logging/log4net/trunk/src/Core/TimeEvaluator.cs (original)
+++ logging/log4net/trunk/src/Core/TimeEvaluator.cs Sun Nov  6 10:06:47 2016
@@ -39,9 +39,9 @@ namespace log4net.Core
         private int m_interval;
 
         /// <summary>
-        /// The time of last check. This gets updated when the object is created and when the evaluator triggers.
+        /// The UTC time of last check. This gets updated when the object is created and when the evaluator triggers.
         /// </summary>
-        private DateTime m_lasttime;
+        private DateTime m_lastTimeUtc;
 
         /// <summary>
         /// The default time threshold for triggering in seconds. Zero means it won't trigger at all.
@@ -84,7 +84,7 @@ namespace log4net.Core
         public TimeEvaluator(int interval)
         {
             m_interval = interval;
-            m_lasttime = DateTime.Now;
+            m_lastTimeUtc = DateTime.UtcNow;
         }
 
         /// <summary>
@@ -131,11 +131,11 @@ namespace log4net.Core
 
             lock (this) // avoid triggering multiple times
             {
-                TimeSpan passed = DateTime.Now.Subtract(m_lasttime);
+                TimeSpan passed = DateTime.UtcNow.Subtract(m_lastTimeUtc);
 
                 if (passed.TotalSeconds > m_interval)
                 {
-                    m_lasttime = DateTime.Now;
+                    m_lastTimeUtc = DateTime.UtcNow;
                     return true;
                 }
                 else

Modified: logging/log4net/trunk/src/Layout/Pattern/RelativeTimePatternConverter.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Layout/Pattern/RelativeTimePatternConverter.cs?rev=1768300&r1=1768299&r2=1768300&view=diff
==============================================================================
--- logging/log4net/trunk/src/Layout/Pattern/RelativeTimePatternConverter.cs (original)
+++ logging/log4net/trunk/src/Layout/Pattern/RelativeTimePatternConverter.cs Sun Nov  6 10:06:47 2016
@@ -50,7 +50,7 @@ namespace log4net.Layout.Pattern
 		/// </remarks>
 		override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
 		{
-			writer.Write( TimeDifferenceInMillis(LoggingEvent.StartTime, loggingEvent.TimeStamp).ToString(System.Globalization.NumberFormatInfo.InvariantInfo) );
+			writer.Write( TimeDifferenceInMillis(LoggingEvent.StartTimeUtc, loggingEvent.TimeStampUtc).ToString(System.Globalization.NumberFormatInfo.InvariantInfo) );
 		}
 
 		/// <summary>

Modified: logging/log4net/trunk/src/Layout/Pattern/UtcDatePatternConverter.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Layout/Pattern/UtcDatePatternConverter.cs?rev=1768300&r1=1768299&r2=1768300&view=diff
==============================================================================
--- logging/log4net/trunk/src/Layout/Pattern/UtcDatePatternConverter.cs (original)
+++ logging/log4net/trunk/src/Layout/Pattern/UtcDatePatternConverter.cs Sun Nov  6 10:06:47 2016
@@ -67,7 +67,7 @@ namespace log4net.Layout.Pattern
 		{
 			try 
 			{
-				m_dateFormatter.FormatDate(loggingEvent.TimeStamp.ToUniversalTime(), writer);
+				m_dateFormatter.FormatDate(loggingEvent.TimeStampUtc, writer);
 			}
 			catch (Exception ex) 
 			{

Modified: logging/log4net/trunk/src/Layout/RawUtcTimeStampLayout.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Layout/RawUtcTimeStampLayout.cs?rev=1768300&r1=1768299&r2=1768300&view=diff
==============================================================================
--- logging/log4net/trunk/src/Layout/RawUtcTimeStampLayout.cs (original)
+++ logging/log4net/trunk/src/Layout/RawUtcTimeStampLayout.cs Sun Nov  6 10:06:47 2016
@@ -66,7 +66,7 @@ namespace log4net.Layout
 		/// </remarks>
 		public virtual object Format(LoggingEvent loggingEvent)
 		{
-			return loggingEvent.TimeStamp.ToUniversalTime();
+			return loggingEvent.TimeStampUtc;
 		}
 
 		#endregion

Modified: logging/log4net/trunk/src/Layout/XmlLayoutSchemaLog4j.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Layout/XmlLayoutSchemaLog4j.cs?rev=1768300&r1=1768299&r2=1768300&view=diff
==============================================================================
--- logging/log4net/trunk/src/Layout/XmlLayoutSchemaLog4j.cs (original)
+++ logging/log4net/trunk/src/Layout/XmlLayoutSchemaLog4j.cs Sun Nov  6 10:06:47 2016
@@ -180,7 +180,7 @@ method="run" file="Generator.java" line=
 			// We must convert the TimeStamp to UTC before performing any mathematical
 			// operations. This allows use to take into account discontinuities
 			// caused by daylight savings time transitions.
-			TimeSpan timeSince1970 = loggingEvent.TimeStamp.ToUniversalTime() - s_date1970;
+			TimeSpan timeSince1970 = loggingEvent.TimeStampUtc - s_date1970;
 
 			writer.WriteAttributeString("timestamp", XmlConvert.ToString((long)timeSince1970.TotalMilliseconds));
 			writer.WriteAttributeString("level", loggingEvent.Level.DisplayName);

Modified: logging/log4net/trunk/src/Util/LogLog.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Util/LogLog.cs?rev=1768300&r1=1768299&r2=1768300&view=diff
==============================================================================
--- logging/log4net/trunk/src/Util/LogLog.cs (original)
+++ logging/log4net/trunk/src/Util/LogLog.cs Sun Nov  6 10:06:47 2016
@@ -58,7 +58,7 @@ namespace log4net.Util
         public static event LogReceivedEventHandler LogReceived;
 
         private readonly Type source;
-        private readonly DateTime timeStamp;
+        private readonly DateTime timeStampUtc;
         private readonly string prefix;
         private readonly string message;
         private readonly Exception exception;
@@ -76,7 +76,15 @@ namespace log4net.Util
         /// </summary>
 	    public DateTime TimeStamp
 	    {
-            get { return timeStamp; }
+            get { return timeStampUtc.ToLocalTime(); }
+	    }
+
+        /// <summary>
+        /// The UTC DateTime stamp of when the internal message was received.
+        /// </summary>
+        public DateTime TimeStampUtc
+        {
+            get { return timeStampUtc; }
 	    }
 
         /// <summary>
@@ -132,7 +140,7 @@ namespace log4net.Util
         /// <param name="exception"></param>
 	    public LogLog(Type source, string prefix, string message, Exception exception)
 	    {
-            timeStamp = DateTime.Now;
+            timeStampUtc = DateTime.UtcNow;
 	        
             this.source = source;
 	        this.prefix = prefix;

Modified: logging/log4net/trunk/src/Util/OnlyOnceErrorHandler.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Util/OnlyOnceErrorHandler.cs?rev=1768300&r1=1768299&r2=1768300&view=diff
==============================================================================
--- logging/log4net/trunk/src/Util/OnlyOnceErrorHandler.cs (original)
+++ logging/log4net/trunk/src/Util/OnlyOnceErrorHandler.cs Sun Nov  6 10:06:47 2016
@@ -81,7 +81,7 @@ namespace log4net.Util
 		/// </summary>
 		public void Reset()
 		{
-			m_enabledDate = DateTime.MinValue;
+			m_enabledDateUtc = DateTime.MinValue;
 			m_errorCode = ErrorCode.GenericFailure;
 			m_exception = null;
 			m_message = null;
@@ -121,7 +121,7 @@ namespace log4net.Util
         /// </para>
         /// </remarks>
         public virtual void FirstError(string message, Exception e, ErrorCode errorCode) {
-            m_enabledDate = DateTime.Now;
+            m_enabledDateUtc = DateTime.UtcNow;
             m_errorCode = errorCode;
             m_exception = e;
             m_message = message;
@@ -182,13 +182,25 @@ namespace log4net.Util
 		}
 
 		/// <summary>
-		/// The date the first error that trigged this error handler occured.
+		/// The date the first error that trigged this error handler occurred, or <see cref="DateTime.MinValue"/> if it has not been triggered.
 		/// </summary>
 		public DateTime EnabledDate
 		{
-			get { return m_enabledDate; }
+			get 
+            {
+                if (m_enabledDateUtc == DateTime.MinValue) return DateTime.MinValue;
+                return m_enabledDateUtc.ToLocalTime(); 
+            }
 		}
 
+        /// <summary>
+        /// The UTC date the first error that trigged this error handler occured, or <see cref="DateTime.MinValue"/> if it has not been triggered.
+        /// </summary>
+        public DateTime EnabledDateUtc
+        {
+            get { return m_enabledDateUtc; }
+        }
+
 		/// <summary>
 		/// The message from the first error that trigged this error handler.
 		/// </summary>
@@ -224,9 +236,9 @@ namespace log4net.Util
 		#region Private Instance Fields
 
 		/// <summary>
-		/// The date the error was recorded.
+		/// The UTC date the error was recorded.
 		/// </summary>
-		private DateTime m_enabledDate;
+		private DateTime m_enabledDateUtc;
 
 		/// <summary>
 		/// Flag to indicate if it is the first error

Modified: logging/log4net/trunk/src/Util/SystemInfo.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/src/Util/SystemInfo.cs?rev=1768300&r1=1768299&r2=1768300&view=diff
==============================================================================
--- logging/log4net/trunk/src/Util/SystemInfo.cs (original)
+++ logging/log4net/trunk/src/Util/SystemInfo.cs Sun Nov  6 10:06:47 2016
@@ -394,9 +394,35 @@ namespace log4net.Util
 		/// will be set per AppDomain.
 		/// </para>
 		/// </remarks>
+        [Obsolete("Use ProcessStartTimeUtc and convert to local time if needed.")]
 		public static DateTime ProcessStartTime
 		{
-			get { return s_processStartTime; }
+			get { return s_processStartTimeUtc.ToLocalTime(); }
+		}
+
+        /// <summary>
+        /// Get the UTC start time for the current process.
+        /// </summary>
+        /// <remarks>
+        /// <para>
+        /// This is the UTC time at which the log4net library was loaded into the
+        /// AppDomain. Due to reports of a hang in the call to <c>System.Diagnostics.Process.StartTime</c>
+        /// this is not the start time for the current process.
+        /// </para>
+        /// <para>
+        /// The log4net library should be loaded by an application early during its
+        /// startup, therefore this start time should be a good approximation for
+        /// the actual start time.
+        /// </para>
+        /// <para>
+        /// Note that AppDomains may be loaded and unloaded within the
+        /// same process without the process terminating, however this start time
+        /// will be set per AppDomain.
+        /// </para>
+        /// </remarks>
+        public static DateTime ProcessStartTimeUtc
+        {
+            get { return s_processStartTimeUtc; }
 		}
 
 		/// <summary>
@@ -1174,7 +1200,7 @@ namespace log4net.Util
 		/// <summary>
 		/// Start time for the current process.
 		/// </summary>
-		private static DateTime s_processStartTime = DateTime.Now;
+		private static DateTime s_processStartTimeUtc = DateTime.UtcNow;
 
 		#endregion
 

Modified: logging/log4net/trunk/tests/src/Core/FixingTest.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/tests/src/Core/FixingTest.cs?rev=1768300&r1=1768299&r2=1768300&view=diff
==============================================================================
--- logging/log4net/trunk/tests/src/Core/FixingTest.cs (original)
+++ logging/log4net/trunk/tests/src/Core/FixingTest.cs Sun Nov  6 10:06:47 2016
@@ -131,7 +131,7 @@ namespace log4net.Tests.Core
 			loggingEventData.Domain = "ReallySimpleApp";
 			loggingEventData.LocationInfo = new LocationInfo(typeof(FixingTest).Name, "Main", "Class1.cs", "29"); //Completely arbitary
 			loggingEventData.ThreadName = Thread.CurrentThread.Name;
-			loggingEventData.TimeStamp = DateTime.Today;
+			loggingEventData.TimeStampUtc = DateTime.UtcNow.Date;
 			loggingEventData.ExceptionString = "Exception occured here";
 			loggingEventData.UserName = "TestUser";
 			return loggingEventData;
@@ -149,7 +149,8 @@ namespace log4net.Tests.Core
 			Assert.AreEqual("log4net.Tests.Core.FixingTest", loggingEventData.LoggerName, "LoggerName is incorrect");
 			Assert.AreEqual(LogManager.GetRepository(TEST_REPOSITORY), loggingEvent.Repository, "Repository is incorrect");
 			Assert.AreEqual(Thread.CurrentThread.Name, loggingEventData.ThreadName, "ThreadName is incorrect");
-			Assert.IsNotNull(loggingEventData.TimeStamp, "TimeStamp is incorrect");
+            // This test is redundant as loggingEventData.TimeStamp is a value type and cannot be null
+            // Assert.IsNotNull(loggingEventData.TimeStampUtc, "TimeStamp is incorrect");
 			Assert.AreEqual("TestUser", loggingEventData.UserName, "UserName is incorrect");
 			Assert.AreEqual("Logging event works", loggingEvent.RenderedMessage, "Message is incorrect");
 		}

Modified: logging/log4net/trunk/tests/src/Layout/XmlLayoutTest.cs
URL: http://svn.apache.org/viewvc/logging/log4net/trunk/tests/src/Layout/XmlLayoutTest.cs?rev=1768300&r1=1768299&r2=1768300&view=diff
==============================================================================
--- logging/log4net/trunk/tests/src/Layout/XmlLayoutTest.cs (original)
+++ logging/log4net/trunk/tests/src/Layout/XmlLayoutTest.cs Sun Nov  6 10:06:47 2016
@@ -73,7 +73,7 @@ namespace log4net.Tests.Layout
 			ed.LoggerName = "TestLogger";
 			ed.Message = "Test message";
 			ed.ThreadName = "TestThread";
-			ed.TimeStamp = DateTime.Today;
+			ed.TimeStampUtc = DateTime.Today.ToUniversalTime();
 			ed.UserName = "TestRunner";
 			ed.Properties = new PropertiesDictionary();