Hi,<br><br>I would like to add to Varnish some statistics (which are not available in the VCL).<br>They will be logged by calling syslog in cnt_done after the end of each request.<br>I am just beginning the adventure of varnish and therefore I have a few questions:<br>
1) where to put the statistics variable (int, char *) so that they won't be overwritten by another thread - the struct sess, sessmem or somewhere else?<br>2) where to put initialization of variables that they will be initialized before each request - VCA_Prep?<br>
<br>When I view logs I see that Content-Lengt << clinet_out, I mean Content-Length is couple times smaller then client_out. <br>It looks like clinet_out isn't cleared at the beggining of request or another thread add something to it between sending data and saving logs. <br>
While the same time backend_in, backend_out and client_in data seems to be correct.<br>This error occurs in about 5-10% of requests and I'm not able to reproduce it on a machine.<br><br>Here's how I'm doing it now:<br>
/* cache.h */<br>struct conn_stat{<br> unsigned magic;<br>#define CONN_STAT_MAGIC 0xf6d1bf<br> char *host;<br> char *addr;<br><br> unsigned long long client_in;<br> unsigned long long client_out;<br>
<br> unsigned long long backend_in;<br> unsigned long long backend_out;<br>};<br><br>struct sess {<br> /* ... */<br> struct conn_stat conn_stat;<br> unsigned long long *wbytes; /* Where to put number of bytes written */<br>
unsigned long long *rbytes; /* Where to put number of bytes read */<br> /* ... */<br>};<br><br>/* cache_session.c: */<br>struct sessmem {<br> /* ... */<br> struct conn_stat *conn_stat;<br> /* ... */<br>
};<br>//ses_sm_alloc()<br> sm = (void*)p;<br> p += sizeof *sm;<br> sm->magic = SESSMEM_MAGIC;<br> sm->workspace = nws;<br> sm->conn_stat = p;<br> p += cl;<br> sm->http[0] = HTTP_create(p, nhttp);<br>
p += hl;<br> sm->http[1] = HTTP_create(p, nhttp);<br> p += hl;<br> sm->wsp = p;<br> p += nws;<br><br>/* cache_center.c */<br>static int<br>cnt_streamdeliver(struct sess *sp)<br>{<br> struct busyobj *bo;<br>
<br> bo = sp->stream_busyobj;<br> CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);<br><br> sp->wbytes = &sp->conn_stat.client_out;<br> *sp->wbytes = 0;<br><br> RES_StreamStart(sp);<br> sp->wrk->h_content_length = NULL;<br>
<br> if (sp->wantbody)<br> RES_StreamBody(sp);<br><br> RES_StreamEnd(sp);<br> <br> sp->wbytes = NULL;<br> /* ... */<br><br>static int<br>cnt_done(struct sess *sp)<br>{<br> double dh, dp, da;<br>
int i;<br><br> CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);<br> CHECK_OBJ_ORNULL(sp->vcl, VCL_CONF_MAGIC);<br> <br> if(sp->vcl != NULL) {<br> syslog(LOG_INFO, "%llu", sp->conn_stat->client_out);<br>
}<br><br><br>