changeset 9057:8771d35d55d0

Syslog: introduced error log handler. This ensures that errors which happen during logging to syslog are logged with proper context, such as "while logging to syslog" and the server name. Prodded by Safar Safarly.
author Maxim Dounin <mdounin@mdounin.ru>
date Fri, 10 Mar 2023 07:43:50 +0300
parents 29adacffdefa
children a5e6e8510634
files src/core/ngx_syslog.c src/core/ngx_syslog.h
diffstat 2 files changed, 41 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/ngx_syslog.c
+++ b/src/core/ngx_syslog.c
@@ -18,6 +18,7 @@
 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);
 static void ngx_syslog_cleanup(void *data);
+static u_char *ngx_syslog_log_error(ngx_log_t *log, u_char *buf, size_t len);
 
 
 static char  *facilities[] = {
@@ -67,7 +68,7 @@ ngx_syslog_process_conf(ngx_conf_t *cf, 
     }
 
     peer->hostname = &cf->cycle->hostname;
-    peer->log = &cf->cycle->new_log;
+    peer->logp = &cf->cycle->new_log;
 
     peer->conn.fd = (ngx_socket_t) -1;
 
@@ -289,6 +290,13 @@ ngx_syslog_send(ngx_syslog_peer_t *peer,
 {
     ssize_t  n;
 
+    if (peer->log.handler == NULL) {
+        peer->log = *peer->logp;
+        peer->log.handler = ngx_syslog_log_error;
+        peer->log.data = peer;
+        peer->log.action = "logging to syslog";
+    }
+
     if (peer->conn.fd == (ngx_socket_t) -1) {
         if (ngx_syslog_init_peer(peer) != NGX_OK) {
             return NGX_ERROR;
@@ -306,7 +314,7 @@ ngx_syslog_send(ngx_syslog_peer_t *peer,
     if (n == NGX_ERROR) {
 
         if (ngx_close_socket(peer->conn.fd) == -1) {
-            ngx_log_error(NGX_LOG_ALERT, peer->log, ngx_socket_errno,
+            ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno,
                           ngx_close_socket_n " failed");
         }
 
@@ -324,25 +332,25 @@ ngx_syslog_init_peer(ngx_syslog_peer_t *
 
     fd = ngx_socket(peer->server.sockaddr->sa_family, SOCK_DGRAM, 0);
     if (fd == (ngx_socket_t) -1) {
-        ngx_log_error(NGX_LOG_ALERT, peer->log, ngx_socket_errno,
+        ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno,
                       ngx_socket_n " failed");
         return NGX_ERROR;
     }
 
     if (ngx_nonblocking(fd) == -1) {
-        ngx_log_error(NGX_LOG_ALERT, peer->log, ngx_socket_errno,
+        ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno,
                       ngx_nonblocking_n " failed");
         goto failed;
     }
 
     if (connect(fd, peer->server.sockaddr, peer->server.socklen) == -1) {
-        ngx_log_error(NGX_LOG_ALERT, peer->log, ngx_socket_errno,
+        ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno,
                       "connect() failed");
         goto failed;
     }
 
     peer->conn.fd = fd;
-    peer->conn.log = peer->log;
+    peer->conn.log = &peer->log;
 
     /* UDP sockets are always ready to write */
     peer->conn.write->ready = 1;
@@ -352,7 +360,7 @@ ngx_syslog_init_peer(ngx_syslog_peer_t *
 failed:
 
     if (ngx_close_socket(fd) == -1) {
-        ngx_log_error(NGX_LOG_ALERT, peer->log, ngx_socket_errno,
+        ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno,
                       ngx_close_socket_n " failed");
     }
 
@@ -373,7 +381,30 @@ ngx_syslog_cleanup(void *data)
     }
 
     if (ngx_close_socket(peer->conn.fd) == -1) {
-        ngx_log_error(NGX_LOG_ALERT, peer->log, ngx_socket_errno,
+        ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno,
                       ngx_close_socket_n " failed");
     }
 }
+
+
+static u_char *
+ngx_syslog_log_error(ngx_log_t *log, u_char *buf, size_t len)
+{
+    u_char             *p;
+    ngx_syslog_peer_t  *peer;
+
+    p = buf;
+
+    if (log->action) {
+        p = ngx_snprintf(buf, len, " while %s", log->action);
+        len -= p - buf;
+    }
+
+    peer = log->data;
+
+    if (peer) {
+        p = ngx_snprintf(p, len, ", server: %V", &peer->server.name);
+    }
+
+    return p;
+}
--- a/src/core/ngx_syslog.h
+++ b/src/core/ngx_syslog.h
@@ -18,7 +18,8 @@ typedef struct {
     ngx_addr_t         server;
     ngx_connection_t   conn;
 
-    ngx_log_t         *log;
+    ngx_log_t          log;
+    ngx_log_t         *logp;
 
     unsigned           busy:1;
     unsigned           nohostname:1;