This may actually be a bug in the JVM (Sun/Oralce 1.7.0) or the Linux
distribution TZ data files (Debian 6.0.4), but it is impacting OpenNMS.
After upgrading to 1.10 we noticed all outages were starting at 20hrs.
The time in the webUI, the time on the machine, the time returned by
Date() in java and the time returned by now() in postgresql were all
correct.
Looking deeper the times in the outages tables were all out by 20hrs.
So I decided to investigate where these times were coming from.
Java is not my native language and I have not looked at the OpenNMS
internals before, so apologies if this is wrong or slightly off somewhere:
It appears opennms uses Date() to get the current local time at the time
of an outage/event and then converts it to GMT to store in memory, but
is converted back to local time when it used (or written to the outages
table in the DB).
Looking at src/main/java/org/opennms/netmgt/EventConstants.java there is
the following two functions (erm.. methods..) that the time is passed
through (sorry pasting this in email is going to garble the formating):
1133 static final ThreadLocal<DateFormat> FORMATTER_LONG_GMT = new
ThreadLocal<DateFormat>() {
1134 protected synchronized DateFormat initialValue() {
1135 final DateFormat formatter =
DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.LONG);
1136 formatter.setLenient(true);
1137 formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
1138 return formatter;
1139 }
1140 };
1141
and
1104 static final ThreadLocal<DateFormat> FORMATTER_LONG = new
ThreadLocal<DateFormat>() {
1105 protected synchronized DateFormat initialValue() {
1106 final DateFormat formatter =
DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.LONG);
1107 formatter.setLenient(true);
1108 return formatter;
1109 }
1110 };
So, constructing a small test program like the following:
import java.util.*;
import java.text.DateFormat;
public class DateTest {
static final ThreadLocal<DateFormat> FORMATTER_LONG_GMT = new
ThreadLocal<DateFormat>() {
protected synchronized DateFormat initialValue() {
final DateFormat formatter =
DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.LONG);
formatter.setLenient(true);
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
return formatter;
}
};
static final ThreadLocal<DateFormat> FORMATTER_LONG = new
ThreadLocal<DateFormat>() {
protected synchronized DateFormat initialValue() {
final DateFormat formatter =
DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.LONG);
formatter.setLenient(true);
return formatter;
}
};
public static void main(String[] args) throws Exception {
System.out.println("Date (Local): " + new Date());
String timestr = FORMATTER_LONG_GMT.get().format(new Date());
System.out.println("Date (GMT): " + timestr);
System.out.println("Date (Local): " +
FORMATTER_LONG.get().parse(timestr));
}
}
And running it, yields some very interesting results.
It appears that in our default locale (we are in Sydney), the conversion
from GMT->Local time is not adjusting for the timezone.
Running it with LANG=C the results are as expected.
Observe:
gmollett@onms:~$ locale
LANG=en_AU.UTF-8
LANGUAGE=
LC_CTYPE="en_AU.UTF-8"
LC_NUMERIC="en_AU.UTF-8"
LC_TIME="en_AU.UTF-8"
LC_COLLATE="en_AU.UTF-8"
LC_MONETARY="en_AU.UTF-8"
LC_MESSAGES="en_AU.UTF-8"
LC_PAPER="en_AU.UTF-8"
LC_NAME="en_AU.UTF-8"
LC_ADDRESS="en_AU.UTF-8"
LC_TELEPHONE="en_AU.UTF-8"
LC_MEASUREMENT="en_AU.UTF-8"
LC_IDENTIFICATION="en_AU.UTF-8"
LC_ALL=
gmollett@onms:~$ java DateTest
Date (Local): Thu Apr 12 14:35:06 EST 2012
Date (GMT): Thursday, 12 April 2012 4:35:06 AM
Date (Local): Thu Apr 12 04:35:06 EST 2012
And:
gmollett@onms:~$ export LANG=C
gmollett@onms:~$ locale
LANG=C
LANGUAGE=
LC_CTYPE="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_PAPER="C"
LC_NAME="C"
LC_ADDRESS="C"
LC_TELEPHONE="C"
LC_MEASUREMENT="C"
LC_IDENTIFICATION="C"
LC_ALL=
gmollett@onms:~$ java DateTest
Date (Local): Thu Apr 12 14:37:35 EST 2012
Date (GMT): Thursday, April 12, 2012 4:37:35 AM GMT
Date (Local): Thu Apr 12 14:37:35 EST 2012
And sure enough, running OpenNMS with LANG=C added to the environment,
everything works normally again, and the times in the outages table are
correct.
I will leave this with you guys, please let me know if you want any more
information or if there is anything more I can do to help.
Thanks,
Garth.
------------------------------------------------------------------------------
For Developers, A Lot Can Happen In A Second.
Boundary is the first to Know...and Tell You.
Monitor Your Applications in Ultra-Fine Resolution. Try it FREE!
http://p.sf.net/sfu/Boundary-d2dvs2
_______________________________________________
Please read the OpenNMS Mailing List FAQ:
http://www.opennms.org/index.php/Mailing_List_FAQ
opennms-devel mailing list
To *unsubscribe* or change your subscription options, see the bottom of this
page:
https://lists.sourceforge.net/lists/listinfo/opennms-devel