Add $unixtime to http variables

This is a patch to add $unixtime to the http variables.

It simply contains the output of time(NULL)

It could be useful to measure the time between the send
of a request to an upstream module and the time the application
server process it.

Example:

uwsgi_param UWSGI_TIME $unixtime;

Then in your app:

if int(time.time()) - int(env[‘UWSGI_TIME’]):
print “*** SYSTEM IS RESPONDING SLOWLY ***”

I do not know if it is better to name it $time instead of $unixtime…

— src/http/ngx_http_variables.c 2010-06-23 17:31:33.000000000 +0200
+++ …/nginx-ok/src/http/ngx_http_variables.c 2010-09-20
19:24:57.000000000 +0200
@@ -93,6 +93,9 @@
static ngx_int_t ngx_http_variable_pid(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);

+static ngx_int_t ngx_http_variable_unixtime(ngx_http_request_t *r,

  • ngx_http_variable_value_t *v, uintptr_t data);

/*

  • TODO:
  • Apache CGI: AUTH_TYPE, PATH_INFO (null), PATH_TRANSLATED
    

@@ -254,6 +257,9 @@
{ ngx_string(“pid”), NULL, ngx_http_variable_pid,
0, 0, 0 },

  • { ngx_string(“unixtime”), NULL, ngx_http_variable_unixtime,
  •  0, 0, 0 },
    
  • { ngx_null_string, NULL, NULL, 0, 0, 0 }
    };

@@ -1640,6 +1646,26 @@

static ngx_int_t
+ngx_http_variable_unixtime(ngx_http_request_t *r,

  • ngx_http_variable_value_t *v, uintptr_t data)
    +{
  • u_char *p;
  • p = ngx_pnalloc(r->pool, NGX_INT64_LEN);
  • if (p == NULL) {
  •    return NGX_ERROR;
    
  • }
  • v->len = ngx_sprintf(p, “%T”, time(NULL)) - p;
  • v->valid = 1;
  • v->no_cacheable = 0;
  • v->not_found = 0;
  • v->data = p;
  • return NGX_OK;
    +}

+static ngx_int_t
ngx_http_variable_pid(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{


Roberto De Ioris
http://unbit.it

uwsgi_param UWSGI_TIME $unixtime;

Then in your app:

if int(time.time()) - int(env[‘UWSGI_TIME’]):
print “*** SYSTEM IS RESPONDING SLOWLY ***”

I do not know if it is better to name it $time instead of $unixtime…

Sorry, i think for this purpose it is betetr to use
r->start_sec instead of time(NULL).

What do you think about it ?


Roberto De Ioris
http://unbit.it

On Mon, Sep 20, 2010 at 10:43 PM, Roberto De Ioris [email protected]
wrote:

Sorry, i think for this purpose it is betetr to use
r->start_sec instead of time(NULL).

What do you think about it ?
When I made the same patch nearly 2 years ago, I used
ngx_cached_time->sec.


Boris D…

On Tue, Sep 21, 2010 at 09:00, Roberto De Ioris [email protected]
wrote:

I would like to have (with the most possible accuracy) the time
when the request starts. (this will allow to reliably calculate
overload problems)

ngx_cached_time try to update every main loop.

ngx_cached_time->sec can be different (oh yes we are talking about
milliseconds, but why not maintaining accuracy :slight_smile: )

but as unixtime you mean unix timestamp?

I would like to have (with the most possible accuracy) the time
when the request starts. (this will allow to reliably calculate
overload problems)

ngx_cached_time->sec can be different (oh yes we are talking about
milliseconds, but why not maintaining accuracy :slight_smile: )

This is the relevant nginx code:

tp = ngx_timeofday();
r->start_sec = tp->sec;
r->start_msec = tp->msec;

#define ngx_timeofday() (ngx_time_t *) ngx_cached_time


Roberto De Ioris
http://unbit.it

Hello!

On Mon, Sep 20, 2010 at 07:32:44PM +0200, Roberto De Ioris wrote:

uwsgi_param UWSGI_TIME $unixtime;

Then in your app:

if int(time.time()) - int(env[‘UWSGI_TIME’]):
print “*** SYSTEM IS RESPONDING SLOWLY ***”

This won’t work as you expect since request to upstream is created
once and used when sending request to multiple upstream servers
(due to proxy_next_upstream/fastcgi_next_upstream/…). Logging
$upstream_response_time would be better idea.

I do not know if it is better to name it $time instead of $unixtime…

If you just need current system time as a variable - I would
recommend moving $msec from log module to generic variables
instead. Or, probably, duplicating it - as log variable will be
more efficient during logging than generic one.

  • ngx_http_variable_value_t *v, uintptr_t data);
  • u_char *p;
  • p = ngx_pnalloc(r->pool, NGX_INT64_LEN);

NGX_TIME_T_LEN should be here.

  • if (p == NULL) {
  •    return NGX_ERROR;
    
  • }
  • v->len = ngx_sprintf(p, “%T”, time(NULL)) - p;

As you were already said - don’t use time(). Use ngx_getimeofday()
instead.

  • v->valid = 1;
  • v->no_cacheable = 0;

If you want to print current time - you may want to mark this
variable as non-cacheable (here and in definition via
NGX_HTTP_VAR_NOCACHEABLE flag).

  • v->not_found = 0;
  • v->data = p;
  • return NGX_OK;
    +}

+static ngx_int_t
ngx_http_variable_pid(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{

Maxim D.

This won’t work as you expect since request to upstream is created
once and used when sending request to multiple upstream servers
(due to proxy_next_upstream/fastcgi_next_upstream/…). Logging
$upstream_response_time would be better idea.

Thanks Maxim, this works perfectly for logging slow-accept() (caused by
full
backlog queue or insufficient processes) as the counter starts before
nginx connection to upstream.

Bye

Roberto De Ioris
http://unbit.it