[4.0] 6dfcd17 Pipe byte accounting
Martin Blix Grydeland
martin at varnish-software.com
Tue Apr 1 15:09:55 CEST 2014
commit 6dfcd17ba234e18314d5f9d739c93aca215a4160
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date: Sun Mar 30 01:52:17 2014 +0100
Pipe byte accounting
Add VSC counters for pipe traffic. Traffic is split between header
bytes, and input and output piped bytes.
Log SLT_PipeAcct records showing per pipe session byte counts.
diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 2e41e24..c58a1fc 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -699,6 +699,7 @@ struct req {
#define RES_ESI (1<<4)
#define RES_ESI_CHILD (1<<5)
#define RES_GUNZIP (1<<6)
+#define RES_PIPE (1<<7)
/* Deliver pipeline */
#define N_VDPS 5
@@ -1088,6 +1089,7 @@ const char *reqbody_status_2str(enum req_body_state_e e);
const char *sess_close_2str(enum sess_close sc, int want_desc);
/* cache_pipe.c */
+void Pipe_Init(void);
void PipeRequest(struct req *req, struct busyobj *bo);
/* cache_pool.c */
diff --git a/bin/varnishd/cache/cache_main.c b/bin/varnishd/cache/cache_main.c
index a5674c0..c6a2599 100644
--- a/bin/varnishd/cache/cache_main.c
+++ b/bin/varnishd/cache/cache_main.c
@@ -219,6 +219,7 @@ child_main(void)
VBP_Init();
WRK_Init();
Pool_Init();
+ Pipe_Init();
EXP_Init();
HSH_Init(heritage.hash);
diff --git a/bin/varnishd/cache/cache_pipe.c b/bin/varnishd/cache/cache_pipe.c
index 7d77096..05b8d0a 100644
--- a/bin/varnishd/cache/cache_pipe.c
+++ b/bin/varnishd/cache/cache_pipe.c
@@ -40,8 +40,17 @@
#include "vtcp.h"
#include "vtim.h"
+static struct lock pipestat_mtx;
+
+struct acct_pipe {
+ ssize_t req;
+ ssize_t bereq;
+ ssize_t in;
+ ssize_t out;
+};
+
static int
-rdf(int fd0, int fd1)
+rdf(int fd0, int fd1, ssize_t *pcnt)
{
int i, j;
char buf[BUFSIZ], *p;
@@ -53,12 +62,30 @@ rdf(int fd0, int fd1)
j = write(fd1, p, i);
if (j <= 0)
return (1);
+ *pcnt += j;
if (i != j)
(void)usleep(100000); /* XXX hack */
}
return (0);
}
+static void
+pipecharge(struct req *req, const struct acct_pipe *a)
+{
+
+ VSLb(req->vsl, SLT_PipeAcct, "%ju %ju %ju %ju",
+ (uintmax_t)a->req,
+ (uintmax_t)a->bereq,
+ (uintmax_t)a->in,
+ (uintmax_t)a->out);
+
+ Lck_Lock(&pipestat_mtx);
+ VSC_C_main->s_pipe_hdrbytes += a->req;
+ VSC_C_main->s_pipe_in += a->in;
+ VSC_C_main->s_pipe_out += a->out;
+ Lck_Unlock(&pipestat_mtx);
+}
+
void
PipeRequest(struct req *req, struct busyobj *bo)
{
@@ -66,7 +93,8 @@ PipeRequest(struct req *req, struct busyobj *bo)
struct worker *wrk;
struct pollfd fds[2];
int i;
- ssize_t txcnt;
+ struct acct_pipe acct;
+ ssize_t hdrbytes;
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
CHECK_OBJ_NOTNULL(req->sp, SESS_MAGIC);
@@ -74,24 +102,38 @@ PipeRequest(struct req *req, struct busyobj *bo)
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+ req->res_mode = RES_PIPE;
+
+ memset(&acct, 0, sizeof acct);
+ acct.req = req->acct.req_hdrbytes;
+ req->acct.req_hdrbytes = 0;
+
vc = VDI_GetFd(bo);
- if (vc == NULL)
+ if (vc == NULL) {
+ pipecharge(req, &acct);
+ SES_Close(req->sp, SC_OVERLOAD);
return;
+ }
bo->vbc = vc; /* For panic dumping */
(void)VTCP_blocking(vc->fd);
WRW_Reserve(wrk, &vc->fd, bo->vsl, req->t_req);
- (void)HTTP1_Write(wrk, bo->bereq, 0);
+ hdrbytes = HTTP1_Write(wrk, bo->bereq, 0);
if (req->htc->pipeline.b != NULL)
(void)WRW_Write(wrk, req->htc->pipeline.b,
Tlen(req->htc->pipeline));
- i = WRW_FlushRelease(wrk, &txcnt);
+ i = WRW_FlushRelease(wrk, &acct.bereq);
+ if (acct.bereq > hdrbytes) {
+ acct.in = acct.bereq - hdrbytes;
+ acct.bereq = hdrbytes;
+ }
VSLb_ts_req(req, "Pipe", W_TIM_real(wrk));
if (i) {
+ pipecharge(req, &acct);
SES_Close(req->sp, SC_TX_PIPE);
VDI_CloseFd(&vc);
return;
@@ -113,7 +155,7 @@ PipeRequest(struct req *req, struct busyobj *bo)
i = poll(fds, 2, (int)(cache_param->pipe_timeout * 1e3));
if (i < 1)
break;
- if (fds[0].revents && rdf(vc->fd, req->sp->fd)) {
+ if (fds[0].revents && rdf(vc->fd, req->sp->fd, &acct.out)) {
if (fds[1].fd == -1)
break;
(void)shutdown(vc->fd, SHUT_RD);
@@ -121,7 +163,7 @@ PipeRequest(struct req *req, struct busyobj *bo)
fds[0].events = 0;
fds[0].fd = -1;
}
- if (fds[1].revents && rdf(req->sp->fd, vc->fd)) {
+ if (fds[1].revents && rdf(req->sp->fd, vc->fd, &acct.in)) {
if (fds[0].fd == -1)
break;
(void)shutdown(req->sp->fd, SHUT_RD);
@@ -131,7 +173,17 @@ PipeRequest(struct req *req, struct busyobj *bo)
}
}
VSLb_ts_req(req, "PipeSess", W_TIM_real(wrk));
+ pipecharge(req, &acct);
SES_Close(req->sp, SC_TX_PIPE);
VDI_CloseFd(&vc);
bo->vbc = NULL;
}
+
+/*--------------------------------------------------------------------*/
+
+void
+Pipe_Init(void)
+{
+
+ Lck_New(&pipestat_mtx, lck_pipestat);
+}
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index 2236553..1e9ecd5 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -896,7 +896,6 @@ CNT_Request(struct worker *wrk, struct req *req)
CHECK_OBJ_ORNULL(wrk->nobjhead, OBJHEAD_MAGIC);
}
if (nxt == REQ_FSM_DONE) {
- /* XXX: Workaround for pipe */
AN(req->vsl->wid);
if (req->res_mode & (RES_ESI|RES_ESI_CHILD))
VSLb(req->vsl, SLT_ESI_BodyBytes, "%ju",
@@ -923,13 +922,15 @@ CNT_AcctLogCharge(struct dstat *ds, struct req *req)
a = &req->acct;
- VSLb(req->vsl, SLT_ReqAcct, "%ju %ju %ju %ju %ju %ju",
- (uintmax_t)a->req_hdrbytes,
- (uintmax_t)a->req_bodybytes,
- (uintmax_t)(a->req_hdrbytes + a->req_bodybytes),
- (uintmax_t)a->resp_hdrbytes,
- (uintmax_t)a->resp_bodybytes,
- (uintmax_t)(a->resp_hdrbytes + a->resp_bodybytes));
+ if (!(req->res_mode & RES_PIPE)) {
+ VSLb(req->vsl, SLT_ReqAcct, "%ju %ju %ju %ju %ju %ju",
+ (uintmax_t)a->req_hdrbytes,
+ (uintmax_t)a->req_bodybytes,
+ (uintmax_t)(a->req_hdrbytes + a->req_bodybytes),
+ (uintmax_t)a->resp_hdrbytes,
+ (uintmax_t)a->resp_bodybytes,
+ (uintmax_t)(a->resp_hdrbytes + a->resp_bodybytes));
+ }
#define ACCT(foo) \
ds->s_##foo += a->foo; \
diff --git a/bin/varnishtest/tests/l00004.vtc b/bin/varnishtest/tests/l00004.vtc
new file mode 100644
index 0000000..3b07e36
--- /dev/null
+++ b/bin/varnishtest/tests/l00004.vtc
@@ -0,0 +1,63 @@
+varnishtest "Test request byte counters on pipe"
+
+server s1 {
+ rxreq
+ expect req.url == "/"
+ expect req.http.test == "yes"
+ txresp -body "fdsa"
+} -start
+
+varnish v1 -vcl+backend {
+ sub vcl_recv {
+ return (pipe);
+ }
+
+ sub vcl_pipe {
+ set bereq.http.test = "yes";
+ unset bereq.http.x-forwarded-for;
+ unset bereq.http.x-varnish;
+ unset bereq.http.connection;
+ }
+} -start
+
+# req:
+# POST / HTTP/1.1\r\n 17 bytes
+# Content-Length: 4\r\n 19 bytes
+# \r\n 2 bytes
+# Total: 38 bytes
+
+# bereq:
+# POST / HTTP/1.1\r\n 17 bytes
+# Content-Length: 4\r\n 19 bytes
+# test: yes\r\n 11 bytes
+# \r\n 2 bytes
+# Total: 49 bytes
+
+# reqbody
+# asdf 4 bytes
+
+# resp:
+# HTTP/1.1 200 Ok\r\n 17 bytes
+# Content-Length: 4\r\n 19 bytes
+# \r\n 2 bytes
+# fdsa 4 bytes
+# Total: 42 bytes
+
+logexpect l1 -v v1 -g request {
+ expect 0 1001 Begin "^req .* rxreq"
+ expect * = PipeAcct "^38 49 4 42$"
+ expect 0 = End
+} -start
+
+client c1 {
+ txreq -req "POST" -url "/" -hdr "Content-Length: 4"
+ send "asdf"
+ rxresp
+ expect resp.status == 200
+} -run
+
+logexpect l1 -wait
+
+varnish v1 -expect s_pipe_hdrbytes == 38
+varnish v1 -expect s_pipe_in == 4
+varnish v1 -expect s_pipe_out == 42
diff --git a/include/tbl/locks.h b/include/tbl/locks.h
index 8329bab..1a01782 100644
--- a/include/tbl/locks.h
+++ b/include/tbl/locks.h
@@ -53,4 +53,5 @@ LOCK(nbusyobj)
LOCK(busyobj)
LOCK(mempool)
LOCK(vxid)
+LOCK(pipestat)
/*lint -restore */
diff --git a/include/tbl/vsc_f_main.h b/include/tbl/vsc_f_main.h
index 859a2eb..4040b0d 100644
--- a/include/tbl/vsc_f_main.h
+++ b/include/tbl/vsc_f_main.h
@@ -400,6 +400,20 @@ VSC_F(s_resp_bodybytes, uint64_t, 1, 'a', info,
"Reponse body bytes",
"Total response body bytes transmitted"
)
+VSC_F(s_pipe_hdrbytes, uint64_t, 0, 'a', info,
+ "Pipe request header bytes",
+ "Total request bytes received for piped sessions"
+)
+VSC_F(s_pipe_in, uint64_t, 0, 'a', info,
+ "Piped bytes from client",
+ "Total number of bytes forwarded from clients in"
+ " pipe sessions"
+)
+VSC_F(s_pipe_out, uint64_t, 0, 'a', info,
+ "Piped bytes to client",
+ "Total number of bytes forwarded to clients in"
+ " pipe sessions"
+)
VSC_F(sess_closed, uint64_t, 1, 'a', info,
"Session Closed",
diff --git a/include/tbl/vsl_tags.h b/include/tbl/vsl_tags.h
index 0213a61..99894cc 100644
--- a/include/tbl/vsl_tags.h
+++ b/include/tbl/vsl_tags.h
@@ -500,4 +500,16 @@ SLTM(ESI_BodyBytes, 0, "ESI body fragment byte counter",
"\n"
)
+SLTM(PipeAcct, 0, "Pipe byte counts",
+ "Contains byte counters for pipe sessions.\n\n"
+ "The format is::\n\n"
+ "\t%d %d %d %d\n"
+ "\t| | | |\n"
+ "\t| | | +------- Piped bytes to client\n"
+ "\t| | +---------- Piped bytes from client\n"
+ "\t| +------------- Backend request headers\n"
+ "\t+---------------- Client request headers\n"
+ "\n"
+)
+
#undef NODEF_NOTICE
More information about the varnish-commit
mailing list