[PATCH v3] syslogd: Add a configurable option to log timestamps in UTC.

Grant Erickson gerickson at nuovations.com
Wed Apr 2 03:16:31 UTC 2025


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.

Signed-off-by: Grant Erickson <gerickson at nuovations.com>
---
sysklogd/syslogd.c | 61 +++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 58 insertions(+), 3 deletions(-)

diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index 7558051f0e7f..73c681827d86 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 "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

-------------- next part --------------
A non-text attachment was scrubbed...
Name: v3-0001-syslogd-Add-a-configurable-option-to-log-timestam.patch
Type: application/octet-stream
Size: 5027 bytes
Desc: not available
URL: <http://lists.busybox.net/pipermail/busybox/attachments/20250401/6426824b/attachment.obj>


More information about the busybox mailing list