[PATCH v5 1/1] syslogd: Add a configurable option to log timestamps in UTC.

Grant Erickson via busybox <[email protected]>
Newsgroups gmane.linux.busybox
Message-ID <[email protected]>
This adds a configurable option 'FEATURE_SYSLOGD_UTC' enabling a
command line option ('-u') that directs syslogd to log timestamps in
Coordinated Universal Time (UTC) rather than in local time.
---
 sysklogd/syslogd.c | 61 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 58 insertions(+), 3 deletions(-)

diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index 2cbb22b6d1b4..40644fb97484 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -35,6 +35,15 @@
 //config:	This enables syslogd to rotate the message files
 //config:	on his own. No need to use an external rotate script.
 //config:
+//config:config FEATURE_SYSLOGD_UTC
+//config:	bool "Optionally log timestamps in UTC"
+//config:	default n
+//config:	depends on SYSLOGD
+//config:	help
+//config:	This enables a command line option ('-u') that directs
+//config:	syslogd to log timestamps in Coordinated Universal Time
+//config:	(UTC) rather than in local time.
+//config:
 //config:config FEATURE_REMOTE_LOG
 //config:	bool "Remote Log support"
 //config:	default y
@@ -147,6 +156,9 @@
 //usage:	)
 //usage:     "\n	-l N		Log only messages more urgent than prio N (1-8)"
 //usage:     "\n	-S		Smaller output"
+//usage:	IF_FEATURE_SYSLOGD_UTC(
+//usage:     "\n	-u		Log timestamps in Coordinated Universal Time (UTC)"
+//usage:	)
 //usage:     "\n	-t		Strip client-generated timestamps"
 //usage:	IF_FEATURE_SYSLOGD_DUP(
 //usage:     "\n	-D		Drop duplicates"
@@ -333,6 +345,7 @@ enum {
 	IF_FEATURE_SYSLOGD_DUP(   OPTBIT_dup        ,)	// -D
 	IF_FEATURE_SYSLOGD_CFG(   OPTBIT_cfg        ,)	// -f
 	IF_FEATURE_KMSG_SYSLOG(   OPTBIT_kmsg       ,)	// -K
+	IF_FEATURE_SYSLOGD_UTC(   OPTBIT_utc        ,)	// -u
 
 	OPT_mark        = 1 << OPTBIT_mark    ,
 	OPT_nofork      = 1 << OPTBIT_nofork  ,
@@ -348,6 +361,7 @@ enum {
 	OPT_dup         = IF_FEATURE_SYSLOGD_DUP(   (1 << OPTBIT_dup        )) + 0,
 	OPT_cfg         = IF_FEATURE_SYSLOGD_CFG(   (1 << OPTBIT_cfg        )) + 0,
 	OPT_kmsg        = IF_FEATURE_KMSG_SYSLOG(   (1 << OPTBIT_kmsg       )) + 0,
+	OPT_utc         = IF_FEATURE_SYSLOGD_UTC(   (1 << OPTBIT_utc        )) + 0,
 };
 #define OPTION_STR "m:nO:l:St" \
 	IF_FEATURE_ROTATE_LOGFILE("s:" ) \
@@ -357,7 +371,8 @@ enum {
 	IF_FEATURE_IPC_SYSLOG(    "C::") \
 	IF_FEATURE_SYSLOGD_DUP(   "D"  ) \
 	IF_FEATURE_SYSLOGD_CFG(   "f:" ) \
-	IF_FEATURE_KMSG_SYSLOG(   "K"  )
+	IF_FEATURE_KMSG_SYSLOG(   "K"  ) \
+	IF_FEATURE_SYSLOGD_UTC(   "u"  )
 #define OPTION_DECL *opt_m, *opt_l \
 	IF_FEATURE_ROTATE_LOGFILE(,*opt_s) \
 	IF_FEATURE_ROTATE_LOGFILE(,*opt_b) \
@@ -818,6 +833,25 @@ static void parse_fac_prio_20(int pri, char *res20)
 	snprintf(res20, 20, "<%d>", pri);
 }
 
+static char *timestamp_from_time(const time_t *time)
+{
+	char *timestamp = NULL;
+
+	if (time) {
+#if ENABLE_FEATURE_SYSLOGD_UTC
+		if (option_mask32 & OPT_utc)
+			timestamp = asctime(gmtime(time));
+		else
+			timestamp = asctime(localtime(time));
+#else
+		timestamp = ctime(time);
+#endif
+		timestamp += 4; /* skip day of week */
+	}
+
+	return timestamp;
+}
+
 /* len parameter is used only for "is there a timestamp?" check.
  * NB: some callers cheat and supply len==0 when they know
  * that there is no timestamp, short-circuiting the test. */
@@ -833,8 +867,29 @@ static void timestamp_and_log(int pri, char *msg, int len)
 	) {
 		if (!(option_mask32 & OPT_timestamp)) {
 			/* use message timestamp */
+#if ENABLE_FEATURE_SYSLOGD_UTC
+			if (option_mask32 & OPT_utc) {
+				struct tm parsed, local;
+				now = time(NULL);
+				localtime_r(&now, &local);
+				if (strptime(msg, "%h %e %T", &parsed) != NULL) {
+					parsed.tm_gmtoff	= local.tm_gmtoff;
+					parsed.tm_zone		= local.tm_zone;
+					parsed.tm_year		= local.tm_year;
+					parsed.tm_isdst		= local.tm_isdst;
+					now = mktime(&parsed);
+					timestamp = asctime(gmtime(&now)) + 4;
+				} else {
+					timestamp = msg;
+				}
+			} else {
+				timestamp = msg;
+				now = 0;
+			}
+#else
 			timestamp = msg;
 			now = 0;
+#endif
 		}
 		msg += 16;
 	}
@@ -844,7 +899,7 @@ static void timestamp_and_log(int pri, char *msg, int len)
 		struct timeval tv;
 		xgettimeofday(&tv);
 		now = tv.tv_sec;
-		timestamp = ctime(&now) + 4; /* skip day of week */
+		timestamp = timestamp_from_time(&now);
 		/* overwrite year by milliseconds, zero terminate */
 		sprintf(timestamp + 15, ".%03u", (unsigned)tv.tv_usec / 1000u);
 	} else {
@@ -853,7 +908,7 @@ static void timestamp_and_log(int pri, char *msg, int len)
 #else
 	if (!timestamp) {
 		time(&now);
-		timestamp = ctime(&now) + 4; /* skip day of week */
+		timestamp = timestamp_from_time(&now);
 	}
 	timestamp[15] = '\0';
 #endif
-- 
2.45.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.