Index | Thread | Search

From:
Stuart Henderson <stu@spacehopper.org>
Subject:
Re: syslogd: ISO8601 timestamp format in UTC by default
To:
Rafael Sadowski <rafael@sizeofvoid.org>
Cc:
tech@openbsd.org, Alexander Bluhm <bluhm@openbsd.org>
Date:
Mon, 2 Nov 2026 14:32:57 +0000

Download raw body.

Thread
newsyslog already unconditionally writes to the start of logs in this
format, so I think it does make sense to change syslogd's default.

as far as programs that parse logs go, I know sshguard and pflogsumm
handle the -Z format... but there are likely to be a bunch of user-
written scripts that won't. at least until we have more information
about how bad that's going to be, I think it might be safer to flip
the default, but give a way to move back, at least for a release or
so...


On 2026/11/02 15:21, Rafael Sadowski wrote:
> As some people have shown an interest in this (see httpd: add timestamps
> to fastcgi error log), here is an initial version for switching syslogd
> to ISO8601 timestamps by default.
> 
> Personally, I would welcome it. So far, I have only tested it locally. I
> have NO larger syslogd server up and running.
> 
> Rafael
> 
> diff --git a/usr.sbin/syslogd/parsemsg.c b/usr.sbin/syslogd/parsemsg.c
> index a28ac9752c5..a2e0d345bb0 100644
> --- a/usr.sbin/syslogd/parsemsg.c
> +++ b/usr.sbin/syslogd/parsemsg.c
> @@ -27,7 +27,7 @@
>  #include "parsemsg.h"
>  #include "syslogd.h"
>  
> -size_t parsemsg_timestamp_bsd(const char *, char *);
> +size_t parsemsg_timestamp_bsd(const char *);
>  size_t parsemsg_timestamp_v1(const char *, char *);
>  size_t parsemsg_prog(const char *, char *);
>  
> @@ -41,7 +41,8 @@ parsemsg(const char *msgstr, struct msg *msg)
>  	if (msg->m_pri &~ (LOG_FACMASK|LOG_PRIMASK))
>  		msg->m_pri = -1;
>  
> -	if ((n = parsemsg_timestamp_bsd(msgstr, msg->m_timestamp)) == 0)
> +	msg->m_timestamp[0] = '\0';
> +	if ((n = parsemsg_timestamp_bsd(msgstr)) == 0)
>  		n = parsemsg_timestamp_v1(msgstr, msg->m_timestamp);
>  	msgstr += n;
>  
> @@ -83,21 +84,18 @@ parsemsg_priority(const char *msg, int *pri)
>  }
>  
>  size_t
> -parsemsg_timestamp_bsd(const char *msg, char *timestamp)
> +parsemsg_timestamp_bsd(const char *msg)
>  {
>  	size_t i;
>  
> -	timestamp[0] = '\0';
>  	for (i = 0; i < 16; i++) {
>  		if (msg[i] == '\0')
>  			return 0;
>  	}
>  
> -	if (msg[3] == ' ' && msg[6] == ' ' && msg[9] == ':' && msg[12] == ':' &&
> -	    msg[15] == ' ') {
> -		/* BSD syslog TIMESTAMP, RFC 3164 */
> -		if (!ZuluTime)
> -			strlcpy(timestamp, msg, 16);
> +	if (msg[3] == ' ' && msg[6] == ' ' && msg[9] == ':' &&
> +	    msg[12] == ':' && msg[15] == ' ') {
> +		/* BSD syslog TIMESTAMP, RFC 3164, ignored */
>  		return 16;
>  	}
>  
> diff --git a/usr.sbin/syslogd/syslogd.8 b/usr.sbin/syslogd/syslogd.8
> index 038be0574f3..fb7fd8b2232 100644
> --- a/usr.sbin/syslogd/syslogd.8
> +++ b/usr.sbin/syslogd/syslogd.8
> @@ -177,9 +177,8 @@ attacks over the network, including attackers remotely filling logs.
>  Do not perform remote server certificate and hostname validation
>  when sending messages.
>  .It Fl Z
> -Generate timestamps in ISO format.
> -This includes the year and the timezone, and all logging is done
> -in UTC.
> +This option is ignored and only accepted for backward compatibility.
> +Timestamps are always generated in ISO 8601 format in UTC.
>  .El
>  .Pp
>  The options
> diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c
> index af76ec2e181..eefcee99feb 100644
> --- a/usr.sbin/syslogd/syslogd.c
> +++ b/usr.sbin/syslogd/syslogd.c
> @@ -229,7 +229,6 @@ int	MarkSeq = 0;		/* mark sequence number */
>  int	Repeat = 0;		/* 0 msg repeated, 1 in files only, 2 never */
>  int	SecureMode = 1;		/* when true, speak only unix domain socks */
>  int	NoDNS = 0;		/* when true, refrain from doing DNS lookups */
> -int	ZuluTime = 0;		/* display date and time in UTC ISO format */
>  int	IncludeHostname = 0;	/* include RFC 3164 hostnames when forwarding */
>  int	Family = PF_UNSPEC;	/* protocol family, may disable IPv4 or IPv6 */
>  
> @@ -484,8 +483,7 @@ main(int argc, char *argv[])
>  		case 'V':		/* do not verify certificates */
>  			NoVerify = 1;
>  			break;
> -		case 'Z':		/* time stamps in UTC ISO format */
> -			ZuluTime = 1;
> +		case 'Z':		/* OBSOLETE, UTC ISO is the default */
>  			break;
>  		default:
>  			usage();
> @@ -1771,21 +1769,17 @@ struct timeval	now;
>  void
>  current_time(char *timestamp)
>  {
> -	(void)gettimeofday(&now, NULL);
> -
> -	if (ZuluTime) {
> -		struct tm *tm;
> -		size_t l;
> +	struct tm *tm;
> +	size_t l;
>  
> -		tm = gmtime(&now.tv_sec);
> -		l = strftime(timestamp, 33, "%FT%T", tm);
> -		/*
> -		 * Use only millisecond precision as some time has
> -		 * passed since syslog(3) was called.
> -		 */
> -		snprintf(timestamp + l, 33 - l, ".%03ldZ", now.tv_usec / 1000);
> -	} else
> -		strlcpy(timestamp, ctime(&now.tv_sec) + 4, 16);
> +	(void)gettimeofday(&now, NULL);
> +	tm = gmtime(&now.tv_sec);
> +	l = strftime(timestamp, 33, "%FT%T", tm);
> +	/*
> +	 * Use only millisecond precision as some time has
> +	 * passed since syslog(3) was called.
> +	 */
> +	snprintf(timestamp + l, 33 - l, ".%03ldZ", now.tv_usec / 1000);
>  }
>  
>  /*
> diff --git a/usr.sbin/syslogd/syslogd.h b/usr.sbin/syslogd/syslogd.h
> index b7c630da299..b9bf7e41e86 100644
> --- a/usr.sbin/syslogd/syslogd.h
> +++ b/usr.sbin/syslogd/syslogd.h
> @@ -23,8 +23,6 @@
>  
>  #include <stdarg.h>
>  
> -extern int	ZuluTime;
> -
>  /* Privilege separation */
>  void  priv_init(int, int, int, int, char **);
>  __dead void priv_exec(const char *, int, int, int, char **);
>