From 13cc07acb867b652c50b6e71484acdffedd79dff Mon Sep 17 00:00:00 2001 From: Vadim Zhestikov Date: Wed, 25 Mar 2026 10:25:43 -0700 Subject: [PATCH] Core: add RFC 5424 syslog message format. When the "rfc=rfc5424" syslog parameter is used, format syslog messages according to RFC 5424 instead of RFC 3164. The RFC 5424 HEADER contains VERSION (always "1"), an ISO 8601 TIMESTAMP with millisecond precision and UTC offset (e.g. "2003-10-11T22:14:15.003+05:30"), HOSTNAME, APP-NAME, PROCID (nginx process PID), and nil values for MSGID and STRUCTURED-DATA. Add cached_syslog_rfc5424_time to ngx_times.c populated alongside the existing cached_syslog_time in both ngx_time_update() and ngx_time_sigsafe_update(). The signal-safe path has no millisecond counter available and emits ".000" for the sub-second field. Expand NGX_SYSLOG_MAX_STR to accommodate the larger RFC 5424 header. --- src/core/ngx_syslog.c | 31 +++++++++++++++++++++++++++---- src/core/ngx_times.c | 30 ++++++++++++++++++++++++++++-- src/core/ngx_times.h | 1 + 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/core/ngx_syslog.c b/src/core/ngx_syslog.c index cb197bb5d..122589c01 100644 --- a/src/core/ngx_syslog.c +++ b/src/core/ngx_syslog.c @@ -10,9 +10,11 @@ #define NGX_SYSLOG_MAX_STR \ - NGX_MAX_ERROR_STR + sizeof("<255>Jan 01 00:00:00 ") - 1 \ + NGX_MAX_ERROR_STR + sizeof("<255>1 ") - 1 \ + + sizeof("1970-09-28T12:00:00.000+06:00") - 1 + 1 /* space */ \ + (NGX_MAXHOSTNAMELEN - 1) + 1 /* space */ \ - + 32 /* tag */ + 2 /* colon, space */ + + 48 /* APP-NAME/TAG */ + 1 /* space */ \ + + NGX_INT64_LEN /* PROCID */ + sizeof(" - - ") - 1 static char *ngx_syslog_parse_args(ngx_conf_t *cf, ngx_syslog_peer_t *peer); @@ -40,6 +42,8 @@ static ngx_event_t ngx_syslog_dummy_event; char * ngx_syslog_process_conf(ngx_conf_t *cf, ngx_syslog_peer_t *peer) { + u_char ch; + ngx_uint_t j; ngx_pool_cleanup_t *cln; peer->facility = NGX_CONF_UNSET_UINT; @@ -50,8 +54,6 @@ ngx_syslog_process_conf(ngx_conf_t *cf, ngx_syslog_peer_t *peer) } if (peer->tag.data != NULL) { - ngx_uint_t j; - u_char ch; if (peer->rfc5424) { @@ -304,6 +306,27 @@ ngx_syslog_add_header(ngx_syslog_peer_t *peer, u_char *buf) pri = peer->facility * 8 + peer->severity; + if (peer->rfc5424) { + + /* + * RFC 5424 HEADER: VERSION SP TIMESTAMP SP HOSTNAME SP + * APP-NAME SP PROCID SP MSGID SP STRUCTURED-DATA SP + * + * PROCID is set to the nginx process PID. MSGID and + * STRUCTURED-DATA are set to the nil value "-". + */ + + if (peer->nohostname) { + return ngx_sprintf(buf, "<%ui>1 %V - %V %P - - ", + pri, &ngx_cached_syslog_rfc5424_time, + &peer->tag, ngx_pid); + } + + return ngx_sprintf(buf, "<%ui>1 %V %V %V %P - - ", + pri, &ngx_cached_syslog_rfc5424_time, + peer->hostname, &peer->tag, ngx_pid); + } + if (peer->nohostname) { return ngx_sprintf(buf, "<%ui>%V %V: ", pri, &ngx_cached_syslog_time, &peer->tag); diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c index b0057d2ab..585674cbf 100644 --- a/src/core/ngx_times.c +++ b/src/core/ngx_times.c @@ -33,6 +33,7 @@ volatile ngx_str_t ngx_cached_http_time; volatile ngx_str_t ngx_cached_http_log_time; volatile ngx_str_t ngx_cached_http_log_iso8601; volatile ngx_str_t ngx_cached_syslog_time; +volatile ngx_str_t ngx_cached_syslog_rfc5424_time; #if !(NGX_WIN32) @@ -56,6 +57,8 @@ static u_char cached_http_log_iso8601[NGX_TIME_SLOTS] [sizeof("1970-09-28T12:00:00+06:00")]; static u_char cached_syslog_time[NGX_TIME_SLOTS] [sizeof("Sep 28 12:00:00")]; +static u_char cached_syslog_rfc5424_time[NGX_TIME_SLOTS] + [sizeof("1970-09-28T12:00:00.000+06:00")]; static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; @@ -70,6 +73,8 @@ ngx_time_init(void) ngx_cached_http_log_time.len = sizeof("28/Sep/1970:12:00:00 +0600") - 1; ngx_cached_http_log_iso8601.len = sizeof("1970-09-28T12:00:00+06:00") - 1; ngx_cached_syslog_time.len = sizeof("Sep 28 12:00:00") - 1; + ngx_cached_syslog_rfc5424_time.len = + sizeof("1970-09-28T12:00:00.000+06:00") - 1; ngx_cached_time = &cached_time[0]; @@ -80,7 +85,7 @@ ngx_time_init(void) void ngx_time_update(void) { - u_char *p0, *p1, *p2, *p3, *p4; + u_char *p0, *p1, *p2, *p3, *p4, *p5; ngx_tm_t tm, gmt; time_t sec; ngx_uint_t msec; @@ -179,6 +184,15 @@ ngx_time_update(void) months[tm.ngx_tm_mon - 1], tm.ngx_tm_mday, tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec); + p5 = &cached_syslog_rfc5424_time[slot][0]; + + (void) ngx_sprintf(p5, "%4d-%02d-%02dT%02d:%02d:%02d.%03ui%c%02i:%02i", + tm.ngx_tm_year, tm.ngx_tm_mon, + tm.ngx_tm_mday, tm.ngx_tm_hour, + tm.ngx_tm_min, tm.ngx_tm_sec, msec, + tp->gmtoff < 0 ? '-' : '+', + ngx_abs(tp->gmtoff / 60), ngx_abs(tp->gmtoff % 60)); + ngx_memory_barrier(); ngx_cached_time = tp; @@ -187,6 +201,7 @@ ngx_time_update(void) ngx_cached_http_log_time.data = p2; ngx_cached_http_log_iso8601.data = p3; ngx_cached_syslog_time.data = p4; + ngx_cached_syslog_rfc5424_time.data = p5; ngx_unlock(&ngx_time_lock); } @@ -214,7 +229,7 @@ ngx_monotonic_time(time_t sec, ngx_uint_t msec) void ngx_time_sigsafe_update(void) { - u_char *p, *p2; + u_char *p, *p2, *p3; ngx_tm_t tm; time_t sec; ngx_time_t *tp; @@ -260,10 +275,21 @@ ngx_time_sigsafe_update(void) months[tm.ngx_tm_mon - 1], tm.ngx_tm_mday, tm.ngx_tm_hour, tm.ngx_tm_min, tm.ngx_tm_sec); + p3 = &cached_syslog_rfc5424_time[slot][0]; + + (void) ngx_sprintf(p3, "%4d-%02d-%02dT%02d:%02d:%02d.000%c%02i:%02i", + tm.ngx_tm_year, tm.ngx_tm_mon, + tm.ngx_tm_mday, tm.ngx_tm_hour, + tm.ngx_tm_min, tm.ngx_tm_sec, + cached_gmtoff < 0 ? '-' : '+', + ngx_abs(cached_gmtoff / 60), + ngx_abs(cached_gmtoff % 60)); + ngx_memory_barrier(); ngx_cached_err_log_time.data = p; ngx_cached_syslog_time.data = p2; + ngx_cached_syslog_rfc5424_time.data = p3; ngx_unlock(&ngx_time_lock); } diff --git a/src/core/ngx_times.h b/src/core/ngx_times.h index 49e0a8c48..4d6142fe9 100644 --- a/src/core/ngx_times.h +++ b/src/core/ngx_times.h @@ -41,6 +41,7 @@ extern volatile ngx_str_t ngx_cached_http_time; extern volatile ngx_str_t ngx_cached_http_log_time; extern volatile ngx_str_t ngx_cached_http_log_iso8601; extern volatile ngx_str_t ngx_cached_syslog_time; +extern volatile ngx_str_t ngx_cached_syslog_rfc5424_time; /* * milliseconds elapsed since some unspecified point in the past