[PATCH] Added the $upstream_connection variable

Jason Stangroome jason at codeassassin.com
Wed Aug 31 13:38:20 UTC 2016


Hello,

I am using nginx primarily as a proxy and I am looking to improve the
visibility and control over keepalive connections to upstreams.

I have several patches I would like to submit for your consideration
but I am relatively unfamiliar with the code base so I've started
simple and I appreciate your feedback. I must say the code base has
been very approachable to work with.

To begin I am adding support for an $upstream_connection variable for
use with the log_format directive. This is essentially the same as the
$connection variable but applies to upstream connections instead of
downstream.

The intent of this variable is to help understand which requests are
being serviced by the same upstream keepalive connection and which are
using different connections.

I think I have followed the Contributing Changes page at nginx.org.
I've honoured the existing code formatting and my `hg export` output
follows my signature. I have also executed the tests from the
nginx-tests repository in a Ubuntu Trusty environment but I did not
have many nginx modules included in my build.

Regards,

Jason
--
# HG changeset patch
# User Jason Stangroome <jason at codeassassin.com>
# Date 1472649436 0
#      Wed Aug 31 13:17:16 2016 +0000
# Node ID f06c8a934e3f3ceac2ff393a391234e225cbfcf1
# Parent  c6372a40c2a731d8816160bf8f55a7a50050c2ac
Added the $upstream_connection variable

Allows the connection identifier of the upstream connection used to service a
proxied request to be logged in the access.log to understand which requests
are using which upstream keepalive connections.

diff -r c6372a40c2a7 -r f06c8a934e3f src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c Fri Aug 26 15:33:07 2016 +0300
+++ b/src/http/ngx_http_upstream.c Wed Aug 31 13:17:16 2016 +0000
@@ -161,6 +161,9 @@
 static ngx_int_t ngx_http_upstream_response_length_variable(
     ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);

+static ngx_int_t ngx_http_upstream_connection_variable(
+    ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
+
 static char *ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd,
void *dummy);
 static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
@@ -395,6 +398,10 @@
       ngx_http_upstream_response_length_variable, 1,
       NGX_HTTP_VAR_NOCACHEABLE, 0 },

+    { ngx_string("upstream_connection"), NULL,
+      ngx_http_upstream_connection_variable, 0,
+      NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
 #if (NGX_HTTP_CACHE)

     { ngx_string("upstream_cache_status"), NULL,
@@ -1804,6 +1811,7 @@

     if (u->state->connect_time == (ngx_msec_t) -1) {
         u->state->connect_time = ngx_current_msec - u->state->response_time;
+        u->state->connection_number = c->number;
     }

     if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) {
@@ -5291,6 +5299,67 @@
 }


+static ngx_int_t
+ngx_http_upstream_connection_variable(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    u_char                     *p;
+    size_t                      len;
+    ngx_uint_t                  i;
+    ngx_http_upstream_state_t  *state;
+
+    v->valid = 1;
+    v->no_cacheable = 0;
+    v->not_found = 0;
+
+    if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
+        v->not_found = 1;
+        return NGX_OK;
+    }
+
+    len = r->upstream_states->nelts * (NGX_ATOMIC_T_LEN + 2);
+
+    p = ngx_pnalloc(r->pool, len);
+    if (p == NULL) {
+        return NGX_ERROR;
+    }
+
+    v->data = p;
+
+    i = 0;
+    state = r->upstream_states->elts;
+
+    for ( ;; ) {
+
+        p = ngx_sprintf(p, "%uA", state[i].connection_number);
+
+        if (++i == r->upstream_states->nelts) {
+            break;
+        }
+
+        if (state[i].peer) {
+            *p++ = ',';
+            *p++ = ' ';
+
+        } else {
+            *p++ = ' ';
+            *p++ = ':';
+            *p++ = ' ';
+
+            if (++i == r->upstream_states->nelts) {
+                break;
+            }
+
+            continue;
+        }
+    }
+
+    v->len = p - v->data;
+
+    return NGX_OK;
+}
+
+
 ngx_int_t
 ngx_http_upstream_header_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
diff -r c6372a40c2a7 -r f06c8a934e3f src/http/ngx_http_upstream.h
--- a/src/http/ngx_http_upstream.h Fri Aug 26 15:33:07 2016 +0300
+++ b/src/http/ngx_http_upstream.h Wed Aug 31 13:17:16 2016 +0000
@@ -66,6 +66,8 @@
     off_t                            bytes_received;

     ngx_str_t                       *peer;
+
+    ngx_atomic_uint_t                connection_number;
 } ngx_http_upstream_state_t;



More information about the nginx-devel mailing list