TZ DST offset problem in 1.6.8 syslog-ng using $TZOFFSET or $ISODATE....
Hi, I've seen the "ISODATE offset?" thread, and I seem to be seeing the exact same thing: https://lists.balabit.hu/pipermail/syslog-ng/2004-November/006633.html The problem appears only during Daylight Savings Time ("summer time"), not during standard/non-DST/"Winter" time. We just entered non-DST time this weekend (and hence the bug "stopped"). During DST the TZ offset does not include the offset due to DST. So TZ is off-by-one during DST. About this section #if HAVE_GLOBAL_TIMEZONE length = snprintf(dest, left - 1, "%c%02ld%02ld", timezone > 0 ? '-' : '+', (timezone < 0 ? -timezone : timezone) / 3600, (timezone % 3600) / 60); #else Bazsi writes in the thread:
Thanks. Either the value in timezone is not set properly, or it does not contain the daylight-saving offset, or my code has an error.
I'll check (I've checked DST before, and timezone should reflect it, so it _might_ be a problem in libc) I'll see what I can do.
Has there been any progress on this? After typing up this report I notice the 1.9.6 NEWS and see: "Fixes in local timezone detection, it should properly detect DSTs on Linux, Solaris and probably BSDs". Is this the same bug? Any chance of this fix being back-ported into a 1.6 maintenance release to show up automagically in debian? (There are no TZ environment variables set on this machine. Also what should it be set to? Following GNUs docs doesn't help. See below.) ************ environment *************
cat /etc/timezone Europe/Copenhagen ls -l /etc/localtime lrwxrwxrwx 1 root root 37 2005-10-25 07:13 /etc/localtime -> /usr/share/zoneinfo/Europe/Copenhagen syslog-ng 1.6.8-1 set | grep -i TZ (no output - se below under "Tried setting TZ env") # I'm using 1.6.8-1 on debian (==newest in testing+unstable), # and the poster in the thread from Nov 2004 was using 1.6.4-1. dpkg-query -W 'syslog-ng' dpkg-query -W libc6 libc6 2.3.5-6
************ syslog-ng.conf snippet ************* destination d_template { file("/tmp/syslog-template.log" template("\"DATE'$ISODATE'TZOFFSET'$TZOFFSET'FULLDATE'$FULLDATE'MSG'$MSG\n") template_escape(yes)); }; log { source(s_all); destination(d_template); }; ************ non-DST example - works ************ # date, perl and syslog-ng all agree with the truth that # we're +0100 during "wintertime" - non-DST.
date --rfc-2822 Mon, 31 Oct 2005 00:00:06 +0100 perl -le 'use POSIX; print strftime ("%a, %d %b %Y %H:%M:%S %z", localtime);' Mon, 31 Oct 2005 00:00:08 +0100 logger 'A message' sudo tail /tmp/syslog-template.log | grep 'A message' "DATE'2005-10-31T00:00:11+0100'TZOFFSET'+0100'FULLDATE'2005 Oct 31 00:00:11'MSG'pvm: A message
************ DST example - fails ************ # Date and perl agree with the truth that # we're +0200 during "summertime" - dst.
date --rfc-2822 Tue, 25 Oct 2005 00:14:13 +0200 perl -le 'use POSIX; print strftime ("%a, %d %b %Y %H:%M:%S %z", localtime);' Tue, 25 Oct 2005 00:14:15 +0200 # syslog-ng seems to think we're +0100 logger 'A message' sudo tail /tmp/syslog-template.log | grep 'A message' "DATE'2005-10-25T00:14:17+0100'TZOFFSET'+0100'FULLDATE'2005 Oct 25 00:14:17'MSG'pvm: A message
*********** Tried setting TZ env **************** I tried setting the TZ environment variable as pr. http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html And notice that perl (or rather the POSIX implementation of strftime()) adheres to it:
TZ=:/usr/share/zoneinfo/Asia/Tokyo perl -le 'use POSIX; print strftime ("%a, %d %b %Y %H:%M:%S %z", localtime);' Tue, 25 Oct 2005 07:03:32 +0900 TZ=:/usr/share/zoneinfo/Europe/Copenhagen perl -le 'use POSIX; print strftime ("%a, %d %b %Y %H:%M:%S %z", localtime);' Tue, 25 Oct 2005 00:03:39 +0200
Using Asia/Tokyo or Europe/Copenhagen does affect syslog-ng, but it still has a offset-by-one error during DST! # Not my real timezone # export TZ=:/usr/share/zoneinfo/Asia/Tokyo # /etc/init.d/syslog-ng restart # logger 'A message' # tail /tmp/syslog-template.log | grep 'A message' "DATE'2005-10-25T07:06:14+0900'TZOFFSET'+0900'FULLDATE'2005 Oct 25 07:06:14'MSG'pvm: A message # My real timezone - should be +0200 on oct 25 in # Copenhagen as strftime also knows. # # export TZ=:/usr/share/zoneinfo/Europe/Copenhagen # /etc/init.d/syslog-ng restart # logger 'A message' # tail /tmp/syslog-template.log | grep 'A message' "DATE'2005-10-25T00:06:57+0100'TZOFFSET'+0100'FULLDATE'2005 Oct 25 00:06:57'MSG'pvm: A message -- Peter Valdemar Mørch http://www.morch.com
Hi, Can you check if this patch fixes the problem? I've just commited it to CVS, so it should be available in tomorrow's snapshot. Index: syslog-ng/configure.in diff -u syslog-ng/configure.in:1.72.4.25 syslog-ng/configure.in:1.72.4.26 --- syslog-ng/configure.in:1.72.4.25 Thu Jun 30 11:20:10 2005 +++ syslog-ng/configure.in Wed Nov 2 20:35:47 2005 @@ -1,4 +1,4 @@ -dnl $Id: configure.in,v 1.72.4.25 2005/06/30 09:20:10 bazsi Exp $ +dnl $Id: configure.in,v 1.72.4.26 2005/11/02 19:35:47 bazsi Exp $ dnl Process this file with autoconf to produce a configure script. AC_INIT(src/affile.c) AC_PREREQ(2.50) @@ -136,6 +136,7 @@ AC_DEFINE(HAVE_MODERN_UTMP, 1, [new style UTMP is defined on the system]) fi + dnl Seek a type for UINT32 AC_CHECK_SIZEOF(short, 2) AC_CHECK_SIZEOF(int, 4) @@ -185,7 +186,7 @@ AC_CHECK_LIB(socket, socket) AC_CHECK_LIB(nsl, gethostbyname) AC_CHECK_FUNCS(select snprintf vsnprintf strerror inet_aton strncpy getutent) -AC_CHECK_FUNCS(getopt_long strcasecmp strptime) +AC_CHECK_FUNCS(getopt_long strcasecmp strptime strftime) old_LIBS=$LIBS @@ -218,6 +219,34 @@ LIBS=$old_LIBS LIBWRAP_LIBS=$blb_cv_c_lwrap +AC_CACHE_CHECK([for %z format string in strftime], + blb_cv_c_strftime_percent_z, +[AC_TRY_RUN([ +#include <time.h> +#include <string.h> + +int main(void) +{ + struct tm tm; + char buf[32]; + + memset(&tm, 0, sizeof(tm)); + strftime(buf, sizeof(buf), "%z", &tm); + + if (strlen(buf) == 5) + return 0; + return 1; +} +], +blb_cv_c_strftime_percent_z=yes, +blb_cv_c_strftime_percent_z=no, +blb_cv_c_strftime_percent_z=no)]) + +if test "x$blb_cv_c_strftime_percent_z" = "xyes"; then + AC_DEFINE(HAVE_STRFTIME_PERCENT_Z, 1, [strftime has a %z format argument]) +fi + + if test "x$ac_cv_func_snprintf" = "xno" -o \ "x$ac_cv_func_vsnprintf" = "xno"; then AC_LIBOBJ(snprintf) Index: syslog-ng/src/macros.c diff -u syslog-ng/src/macros.c:1.4.4.6 syslog-ng/src/macros.c:1.4.4.7 --- syslog-ng/src/macros.c:1.4.4.6 Thu Aug 5 13:35:12 2004 +++ syslog-ng/src/macros.c Wed Nov 2 20:35:47 2005 @@ -19,7 +19,7 @@ * * Inspired by nsyslog, originally written by Darren Reed. * - * $Id: macros.c,v 1.4.4.6 2004/08/05 11:35:12 bazsi Exp $ + * $Id: macros.c,v 1.4.4.7 2005/11/02 19:35:47 bazsi Exp $ * ***************************************************************************/ @@ -109,17 +109,33 @@ } static size_t -format_tzofs(char *dest, size_t left, struct tm *tm) +format_tzofs(char *dest, size_t left, time_t unixtime, struct tm *tm) { size_t length; -#if HAVE_GLOBAL_TIMEZONE - length = snprintf(dest, left - 1, "%c%02ld%02ld", - timezone > 0 ? '-' : '+', - (timezone < 0 ? -timezone : timezone) / 3600, - (timezone % 3600) / 60); -#else +#if HAVE_STRFTIME_PERCENT_Z length = strftime(dest, left -1, "%z", tm); +#else + struct tm ltm, *gtm; + long tzoff; + + ltm = *localtime(&unixtime); + gtm = gmtime(&unixtime); + + tzoff = (ltm.tm_hour - gtm->tm_hour) * 3600; + tzoff += (ltm.tm_min - gtm->tm_min) * 60; + tzoff += ltm.tm_sec - gtm->tm_sec; + + /* normalize within +/- 12 hours */ + if (tzoff < -12*3600) + tzoff += 24*3600; + else if (tzoff > 12*3600) + tzoff -= 24*3600; + + length = snprintf(dest, left - 1, "%c%02ld%02ld", + tzoff < 0 ? '-' : '+', + (tzoff < 0 ? -tzoff : tzoff) / 3600, + (tzoff % 3600) / 60); #endif return length; } @@ -340,7 +356,7 @@ case M_ISODATE_RECVD: case M_ISODATE_STAMP: length = strftime(*dest, *left - 1, "%Y-%m-%dT%H:%M:%S", tm); - length = length + format_tzofs((*dest) + length, *left - length - 1, tm); + length = length + format_tzofs((*dest) + length, *left - length - 1, unixtime, tm); break; case M_FULLDATE: case M_FULLDATE_RECVD: @@ -355,7 +371,7 @@ case M_TZOFFSET: case M_TZOFFSET_RECVD: case M_TZOFFSET_STAMP: - length = format_tzofs(*dest, *left - 1, tm); + length = format_tzofs(*dest, *left - 1, unixtime, tm); break; case M_TZ: case M_TZ_RECVD: On Mon, 2005-10-31 at 14:37 +0100, Peter Valdemar Mørch wrote:
Hi,
-- Bazsi
Balazs Scheidler bazsi-at-balabit.hu |Lists| wrote:
Can you check if this patch fixes the problem? I've just commited it to CVS, so it should be available in tomorrow's snapshot.
Yup, that did the trick. Hope it shows up automagically in Debian soon, but I know that is out of your hands! :-D Now at least *I* have a working .deb package. Thanks! Peter
participants (3)
-
Balazs Scheidler
-
Peter Valdemar Morch
-
Peter Valdemar Mørch