[PATCH] Added the $upstream_connection variable

Alexey Ivanov savetherbtz at gmail.com
Mon Sep 12 09:52:34 UTC 2016


+1 to that.

Connection reuse to an upstream is a very important metric for Edge->DC communication.
In our production since we have nginx on both sides we are are gathering that metric from the other side of the other side of a connection. I assume not everybody have that luxury, therefore that stat would be useful.

> On Aug 31, 2016, at 6:38 AM, Jason Stangroome <jason at codeassassin.com> wrote:
> 
> 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;
> 
> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 842 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20160912/6f6fb219/attachment.bin>


More information about the nginx-devel mailing list