logging-log4j-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Curt Arnold <carn...@apache.org>
Subject Re: Timestamps and time zones
Date Mon, 20 Oct 2008 20:41:25 GMT

On Oct 20, 2008, at 1:39 PM, Peter Steele wrote:

>> If you are changing from 8:00 AM PDT to 8:00 AM EDT, you are not just
>> changing the time zone, but you are also changing the time.
>
> Yes, that's correct, both the time zone and time are being set in one
> operation.
>
>> Are you changing the timezone using a operating system utility
>> (control panel etc) or by using a call to TimeZone.setDefault()?
>
> We are using TimeZone.setDefault(). The user sets the time and time  
> zone
> in our
> GUI and hits an Apply button to invoke the change.
>
>> Different JVM's may have different approaches to how a change in the
>> operating system timezone becomes visible in the JDK.  If the JDK  
>> only
>
>> checks the default timezone at start up, there is nothing log4j can
>> do.  Knowing the vendor and version of the OS and JVM in use and the
>> exact method of making the timezone change would be helpful to
>> understand your observed behavior.  It does appear that you are  
>> seeing
>
>> an immediate effect from changing the time, but the timezone is not
>> immediately updated in the app by the manner you are making the  
>> change.
>
> We are using JDK 1.5 on FreeBSD 7.0. The code we execute does take
> immediate effect
> on the system itself as far as the local time is concerned, e.g., the
> date command
> shows the same date/time/time zone as the user sets in the GUI. The
> logger timestamps
> however still show the time in the original time zone.
>
>> I'd suggest using the EnhancedPatternLayout in the extras companion
>> and output the time in a fixed timezone.  Something like:
>>
>> %d{yyyy-MM-dd HH:mm:ss}{UTC}Z - %c - %m%n
>>
>> You could also output the time in local time for convenience, but
>> you'd always have the time in a known timezone.
>
> I will check this out but I'm not sure if it will solve the problem.
> Ideally, when we
> change the time from say 8:00 PDT to 8:00 EDT, we'd like the log
> timestamps to also
> show 8:00, but what we get is 5:00, at least until we restart the
> application. We could
> add the explicit time zone but will it just end up showing 5:00 EDT
> instead of 8:00 EDT?
> Is there a log4j function we could call to force it to resync with the
> current local time,
> similar to what it must be doing when an application starts?
>
>


When the PatternLayout is created during configuration, an instance of  
java.text.SimpleDateFormat (or a log4j-provided DateFormat if you  
specify %d{ISO8601} or similar) and this format is used for the  
lifetime of PatternLayout.  java.text.SimpleDateFormat apparently  
caches the default timezone at the time of creation (at least in your  
JDK's implementation) and does not monitor any subsequent changes.

Date formatting can be a time consuming part of logging.  log4j 1.2  
has a decent amount code (problematic code though) to cache the  
results of previous format requests for potential reuse.  The caching  
and design is much cleaner in the EnhancedPatternLayout in the extras  
companion.  The following patch to the extras companion should allow  
an %d pattern in an EnhancedPatternLayout without a explicit timezone  
to follow changes to the default timezone without an undue performance  
hit.  The timezone should be updated at most once a second, since  
CachedDateFormat should handle the more frequent calls.   I've run the  
standard unit tests against it and it didn't break anything, but I  
haven't attempted to test it while changing the system timezone.

I'd appreciate your feedback.  If the works for you, we could consider  
this for the next release of the extras companion.


Index: src/main/java/org/apache/log4j/pattern/DatePatternConverter.java
===================================================================
--- src/main/java/org/apache/log4j/pattern/DatePatternConverter.java	 
(revision 702979)
+++ src/main/java/org/apache/log4j/pattern/DatePatternConverter.java	 
(working copy)
@@ -21,6 +21,9 @@
  import org.apache.log4j.spi.LoggingEvent;

  import java.text.SimpleDateFormat;
+import java.text.DateFormat;
+import java.text.FieldPosition;
+import java.text.ParsePosition;
  import java.util.Date;
  import java.util.TimeZone;

@@ -63,6 +66,41 @@
     */
    private final CachedDateFormat df;

+    /**
+     * This class wraps a DateFormat and forces the time zone to the
+     *   default time zone before each format and parse request.
+     */
+  private class DefaultZoneDateFormat extends DateFormat {
+        /**
+         * Wrapped instance of DateFormat.
+         */
+    private final DateFormat dateFormat;
+
+        /**
+         * Construct new instance.
+         * @param format format, may not be null.
+         */
+    public DefaultZoneDateFormat(final DateFormat format) {
+        dateFormat = format;
+    }
+
+        /**
+         * @{inheritDoc}
+         */
+    public StringBuffer format(Date date, StringBuffer toAppendTo,  
FieldPosition fieldPosition) {
+        dateFormat.setTimeZone(TimeZone.getDefault());
+        return dateFormat.format(date, toAppendTo, fieldPosition);
+    }
+
+        /**
+         * @{inheritDoc}
+         */
+    public Date parse(String source, ParsePosition pos) {
+        dateFormat.setTimeZone(TimeZone.getDefault());
+        return dateFormat.parse(source, pos);
+    }
+  }
+
    /**
     * Private constructor.
     * @param options options, may be null.
@@ -95,7 +133,7 @@
      }

      int maximumCacheValidity = 1000;
-    SimpleDateFormat simpleFormat = null;
+    DateFormat simpleFormat = null;

      try {
        simpleFormat = new SimpleDateFormat(pattern);
@@ -113,6 +151,8 @@
      if ((options != null) && (options.length > 1)) {
        TimeZone tz = TimeZone.getTimeZone((String) options[1]);
        simpleFormat.setTimeZone(tz);
+    } else {
+      simpleFormat = new DefaultZoneDateFormat(simpleFormat);
      }

      df = new CachedDateFormat(simpleFormat, maximumCacheValidity);



  as it is and there is a fair bit of logic (much better in the  
EnhancedPatternLayout in extras than in log4j) to cache previous  
formatted results and reuse them

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org


Mime
View raw message