diff --git a/src/core/ngx_syslog.c b/src/core/ngx_syslog.c index bad45bd16..46d641160 100644 --- a/src/core/ngx_syslog.c +++ b/src/core/ngx_syslog.c @@ -14,6 +14,11 @@ + (NGX_MAXHOSTNAMELEN - 1) + 1 /* space */ \ + 32 /* tag */ + 2 /* colon, space */ +#define NGX_SYSLOG_RFC5424_MAX_STR \ + NGX_MAX_ERROR_STR + sizeof("<255>1 1970-01-01T00:00:00.000Z ") - 1 \ + + (NGX_MAXHOSTNAMELEN - 1) + 1 /* space */ \ + + sizeof("nginx ") - 1 /* appname, space */ \ + + 32 /* pid */ + 5 /* -, space */ static char *ngx_syslog_parse_args(ngx_conf_t *cf, ngx_syslog_peer_t *peer); static ngx_int_t ngx_syslog_init_peer(ngx_syslog_peer_t *peer); @@ -215,6 +220,9 @@ ngx_syslog_parse_args(ngx_conf_t *cf, ngx_syslog_peer_t *peer) } else if (len == 10 && ngx_strncmp(p, "nohostname", 10) == 0) { peer->nohostname = 1; + } else if (len == 7 && ngx_strncmp(p, "rfc5424", 7) == 0) { + peer->is_rfc5424 = 1; + } else { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unknown syslog parameter \"%s\"", p); @@ -250,12 +258,33 @@ ngx_syslog_add_header(ngx_syslog_peer_t *peer, u_char *buf) peer->hostname, &peer->tag); } +u_char * +ngx_syslog_add_header_rfc5424(ngx_syslog_peer_t *peer, u_char *buf) +{ + ngx_uint_t pri; + + pri = peer->facility * 8 + peer->severity; + + if (peer->nohostname) { + return ngx_sprintf(buf, "<%ui>1 %V - nginx %d - - ", + pri, + &ngx_cached_syslog_rfc5424_time, + ngx_log_pid); + } + + return ngx_sprintf(buf, "<%ui>1 %V %V nginx %d - - ", + pri, + &ngx_cached_syslog_rfc5424_time, + peer->hostname, + ngx_log_pid); +} void ngx_syslog_writer(ngx_log_t *log, ngx_uint_t level, u_char *buf, size_t len) { - u_char *p, msg[NGX_SYSLOG_MAX_STR]; + int max_len; + u_char *p, msg[NGX_SYSLOG_RFC5424_MAX_STR]; ngx_uint_t head_len; ngx_syslog_peer_t *peer; @@ -268,13 +297,20 @@ ngx_syslog_writer(ngx_log_t *log, ngx_uint_t level, u_char *buf, peer->busy = 1; peer->severity = level - 1; - p = ngx_syslog_add_header(peer, msg); + if (peer->is_rfc5424) { + max_len = NGX_SYSLOG_RFC5424_MAX_STR; + p = ngx_syslog_add_header_rfc5424(peer, msg); + } else { + max_len = NGX_SYSLOG_MAX_STR; + p = ngx_syslog_add_header(peer, msg); + } + head_len = p - msg; len -= NGX_LINEFEED_SIZE; - if (len > NGX_SYSLOG_MAX_STR - head_len) { - len = NGX_SYSLOG_MAX_STR - head_len; + if (len > max_len - head_len) { + len = max_len - head_len; } p = ngx_snprintf(p, len, "%s", buf); diff --git a/src/core/ngx_syslog.h b/src/core/ngx_syslog.h index e2d54acdb..42eb69f4e 100644 --- a/src/core/ngx_syslog.h +++ b/src/core/ngx_syslog.h @@ -23,11 +23,13 @@ typedef struct { unsigned busy:1; unsigned nohostname:1; + unsigned is_rfc5424:1; } ngx_syslog_peer_t; char *ngx_syslog_process_conf(ngx_conf_t *cf, ngx_syslog_peer_t *peer); u_char *ngx_syslog_add_header(ngx_syslog_peer_t *peer, u_char *buf); +u_char *ngx_syslog_add_header_rfc5424(ngx_syslog_peer_t *peer, u_char *buf); void ngx_syslog_writer(ngx_log_t *log, ngx_uint_t level, u_char *buf, size_t len); ssize_t ngx_syslog_send(ngx_syslog_peer_t *peer, u_char *buf, size_t len); diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c index 16788c98c..1c1326efc 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.000Z")]; static char *week[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; @@ -70,6 +73,7 @@ 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.000Z") - 1; ngx_cached_time = &cached_time[0]; @@ -80,7 +84,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 +183,14 @@ 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.%03dZ", + tm.ngx_tm_year, tm.ngx_tm_mon, + tm.ngx_tm_mday, tm.ngx_tm_hour, + tm.ngx_tm_min, tm.ngx_tm_sec, + tp->msec); + ngx_memory_barrier(); ngx_cached_time = tp; @@ -187,6 +199,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); } @@ -218,10 +231,11 @@ 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; + ngx_uint_t msec; struct timeval tv; if (!ngx_trylock(&ngx_time_lock)) { @@ -231,10 +245,14 @@ ngx_time_sigsafe_update(void) ngx_gettimeofday(&tv); sec = tv.tv_sec; + msec = tv.tv_usec / 1000; + + ngx_current_msec = ngx_monotonic_time(sec, msec); tp = &cached_time[slot]; if (tp->sec == sec) { + tp->msec = msec; ngx_unlock(&ngx_time_lock); return; } @@ -264,10 +282,20 @@ 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.%03dZ", + tm.ngx_tm_year, tm.ngx_tm_mon, + tm.ngx_tm_mday, tm.ngx_tm_hour, + tm.ngx_tm_min, tm.ngx_tm_sec, + tp->msec); + + 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 diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c index f7c4bd2f5..6afc0d3ed 100644 --- a/src/http/modules/ngx_http_log_module.c +++ b/src/http/modules/ngx_http_log_module.c @@ -312,9 +312,18 @@ ngx_http_log_handler(ngx_http_request_t *r) if (log[l].syslog_peer) { /* length of syslog's PRI and HEADER message parts */ - len += sizeof("<255>Jan 01 00:00:00 ") - 1 - + ngx_cycle->hostname.len + 1 - + log[l].syslog_peer->tag.len + 2; + if (log[l].syslog_peer->is_rfc5424) { + u_char pid[32]; + ngx_sprintf(pid, "%P", ngx_pid); + len += sizeof("<255>1 1970-01-01T00:00:00.000Z ") - 1 + + ngx_cycle->hostname.len + 1 + + sizeof("nginx ") - 1 + + ngx_strlen(pid) + 5; + } else { + len += sizeof("<255>Jan 01 00:00:00 ") - 1 + + ngx_cycle->hostname.len + 1 + + log[l].syslog_peer->tag.len + 2; + } goto alloc_line; } @@ -367,7 +376,9 @@ ngx_http_log_handler(ngx_http_request_t *r) p = line; if (log[l].syslog_peer) { - p = ngx_syslog_add_header(log[l].syslog_peer, line); + p = log[l].syslog_peer->is_rfc5424 ? + ngx_syslog_add_header_rfc5424(log[l].syslog_peer, line) + : ngx_syslog_add_header(log[l].syslog_peer, line); } for (i = 0; i < log[l].format->ops->nelts; i++) { diff --git a/src/stream/ngx_stream_log_module.c b/src/stream/ngx_stream_log_module.c index 0ff7f4244..d2d9e5782 100644 --- a/src/stream/ngx_stream_log_module.c +++ b/src/stream/ngx_stream_log_module.c @@ -260,10 +260,18 @@ ngx_stream_log_handler(ngx_stream_session_t *s) if (log[l].syslog_peer) { /* length of syslog's PRI and HEADER message parts */ - len += sizeof("<255>Jan 01 00:00:00 ") - 1 - + ngx_cycle->hostname.len + 1 - + log[l].syslog_peer->tag.len + 2; - + if (log[l].syslog_peer->is_rfc5424) { + u_char pid[32]; + ngx_sprintf(pid, "%P", ngx_pid); + len += sizeof("<255>1 1970-01-01T00:00:00.000Z ") - 1 + + ngx_cycle->hostname.len + 1 + + sizeof("nginx ") - 1 + + ngx_strlen(pid) + 5; + } else { + len += sizeof("<255>Jan 01 00:00:00 ") - 1 + + ngx_cycle->hostname.len + 1 + + log[l].syslog_peer->tag.len + 2; + } goto alloc_line; } @@ -315,7 +323,9 @@ ngx_stream_log_handler(ngx_stream_session_t *s) p = line; if (log[l].syslog_peer) { - p = ngx_syslog_add_header(log[l].syslog_peer, line); + p = log[l].syslog_peer->is_rfc5424 ? + ngx_syslog_add_header_rfc5424(log[l].syslog_peer, line) + : ngx_syslog_add_header(log[l].syslog_peer, line); } for (i = 0; i < log[l].format->ops->nelts; i++) {