[PATCH 1 of 2] Core: connect() error log message made more verbose
Maxim Dounin
mdounin at mdounin.ru
Thu Feb 9 08:11:57 UTC 2023
Hello!
On Wed, Feb 08, 2023 at 06:54:06PM +0300, Safar Safarly via nginx-devel wrote:
> # HG changeset patch
> # User Safar Safarly <hafl at me.com>
> # Date 1675779866 -10800
> # Tue Feb 07 17:24:26 2023 +0300
> # Node ID 55553146bd984be7e9e3bbfa851c282feda82d93
> # Parent cffaf3f2eec8fd33605c2a37814f5ffc30371989
> Core: connect() error log message made more verbose
>
> There was a major problem in logs: we could not identify to which servers
> connect() has failed. Previously log produced:
>
> ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
> "connect() failed");
>
> And now we'll have an address or unix socket in log:
>
> ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
> "connect() to %V failed", &peer->server.name);
>
> Message format has chosen to be exact as it is used in ngx_event_connect.c:242
> with similar error logging:
>
> ngx_log_error(level, c->log, err, "connect() to %V failed",
> pc->name);
>
> So everywhere connect() could fail we'd get a uniform and verbose error message
> in log.
Thanks for the patch.
Indeed, it might be non-trivial to find out what goes wrong when
no context is provided in error messages, and logging to syslog
fails to provide any.
Please see comments below.
>
> diff -r cffaf3f2eec8 -r 55553146bd98 src/core/ngx_resolver.c
> --- a/src/core/ngx_resolver.c Thu Feb 02 23:38:48 2023 +0300
> +++ b/src/core/ngx_resolver.c Tue Feb 07 17:24:26 2023 +0300
> @@ -4512,7 +4512,7 @@
>
> if (rc == -1) {
> ngx_log_error(NGX_LOG_CRIT, &rec->log, ngx_socket_errno,
> - "connect() failed");
> + "connect() to %V failed", &rec->server);
Resolver already provides details about the particular server it
connects to, for example:
2023/02/08 19:39:53 [crit] 23077#100129: connect() failed (2: No such file or directory) while resolving, resolver: unix:/resolver.socket
See ngx_resolver_log_error() for more information.
>
> goto failed;
> }
> diff -r cffaf3f2eec8 -r 55553146bd98 src/core/ngx_syslog.c
> --- a/src/core/ngx_syslog.c Thu Feb 02 23:38:48 2023 +0300
> +++ b/src/core/ngx_syslog.c Tue Feb 07 17:24:26 2023 +0300
> @@ -337,7 +337,7 @@
>
> if (connect(fd, peer->server.sockaddr, peer->server.socklen) == -1) {
> ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
> - "connect() failed");
> + "connect() to %V failed", &peer->server.name);
> goto failed;
> }
For syslog logging, I tend to think that this isn't really enough.
For example, consider send() errors which also might happen when
logging to syslog. Right now these are logged as:
2023/02/09 07:29:11 [alert] 23230#100162: send() failed (49: Can't assign requested address)
2023/02/09 07:29:11 [alert] 23230#100162: send() failed (49: Can't assign requested address)
Clearly no better than connect() errors:
2023/02/09 07:29:11 [alert] 23230#100162: connect() failed (2: No such file or directory)
A better fix would be to provide a log handler, similarly to
ngx_resolver_log_error() mentioned above. With a simple log
handler the above messages will instead look like:
2023/02/09 07:48:11 [alert] 23699#100145: send() failed (49: Can't assign requested address) while logging to syslog, server: 127.0.0.2:514
2023/02/09 07:48:11 [alert] 23699#100145: send() failed (49: Can't assign requested address) while logging to syslog, server: 127.0.0.2:514
2023/02/09 07:48:11 [alert] 23699#100145: connect() failed (2: No such file or directory) while logging to syslog, server: unix:/log.socket
Patch:
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1675929813 -10800
# Thu Feb 09 11:03:33 2023 +0300
# Node ID 6b662855bf77c678a3954939aefe3fd4b4af4c70
# Parent cffaf3f2eec8fd33605c2a37814f5ffc30371989
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.
diff --git a/src/core/ngx_syslog.c b/src/core/ngx_syslog.c
--- 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[] = {
@@ -66,6 +67,8 @@ ngx_syslog_process_conf(ngx_conf_t *cf,
ngx_str_set(&peer->tag, "nginx");
}
+ peer->logp = &cf->cycle->new_log;
+
peer->conn.fd = (ngx_socket_t) -1;
peer->conn.read = &ngx_syslog_dummy_event;
@@ -286,15 +289,19 @@ 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;
}
}
- /* log syslog socket events with valid log */
- peer->conn.log = ngx_cycle->log;
-
if (ngx_send) {
n = ngx_send(&peer->conn, buf, len);
@@ -324,24 +331,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, ngx_cycle->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, ngx_cycle->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, ngx_cycle->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;
/* UDP sockets are always ready to write */
peer->conn.write->ready = 1;
@@ -351,7 +359,7 @@ ngx_syslog_init_peer(ngx_syslog_peer_t *
failed:
if (ngx_close_socket(fd) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno,
+ ngx_log_error(NGX_LOG_ALERT, &peer->log, ngx_socket_errno,
ngx_close_socket_n " failed");
}
@@ -372,7 +380,30 @@ ngx_syslog_cleanup(void *data)
}
if (ngx_close_socket(peer->conn.fd) == -1) {
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->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;
+}
diff --git a/src/core/ngx_syslog.h b/src/core/ngx_syslog.h
--- a/src/core/ngx_syslog.h
+++ b/src/core/ngx_syslog.h
@@ -9,14 +9,18 @@
typedef struct {
- ngx_uint_t facility;
- ngx_uint_t severity;
- ngx_str_t tag;
+ ngx_uint_t facility;
+ ngx_uint_t severity;
+ ngx_str_t tag;
- ngx_addr_t server;
- ngx_connection_t conn;
- unsigned busy:1;
- unsigned nohostname:1;
+ ngx_addr_t server;
+ ngx_connection_t conn;
+
+ ngx_log_t log;
+ ngx_log_t *logp;
+
+ unsigned busy:1;
+ unsigned nohostname:1;
} ngx_syslog_peer_t;
--
Maxim Dounin
http://mdounin.ru/
More information about the nginx-devel
mailing list