From d04b1bce6966cb5855ee86ac1a9294a2db08f9d2 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 8 May 2012 11:03:10 +0200 Subject: [PATCH] MEDIUM: http: improve error capture reports A number of important information were missing from the error captures, so let's improve them. Now we also log source port, session flags, transaction flags, message flags, pending output bytes, expected buffer wrapping position, total bytes transferred, message chunk length, and message body length. As such, the output format has slightly evolved and the source address moved to the third line : [08/May/2012:11:14:36.341] frontend echo (#1): invalid request backend echo (#1), server (#-1), event #1 src 127.0.0.1:40616, session #4, session flags 0x00000000 HTTP msg state 26, msg flags 0x00000000, tx flags 0x00000000 HTTP chunk len 0 bytes, HTTP body len 0 bytes buffer flags 0x00909002, out 0 bytes, total 28 bytes pending 28 bytes, wrapping at 8030, error at position 7: 00000 GET / /?t=20000 HTTP/1.1\r\n 00026 \r\n [08/May/2012:11:13:13.426] backend echo (#1) : invalid response frontend echo (#1), server local (#1), event #0 src 127.0.0.1:40615, session #1, session flags 0x0000044e HTTP msg state 32, msg flags 0x0000000e, tx flags 0x08200000 HTTP chunk len 0 bytes, HTTP body len 20 bytes buffer flags 0x00008002, out 81 bytes, total 92 bytes pending 11 bytes, wrapping at 7949, error at position 9: 00000 Foo: bar\r\r\n --- include/types/proxy.h | 10 ++++++++- src/dumpstats.c | 48 +++++++++++++++++++++++++++---------------- src/proto_http.c | 10 ++++++++- 3 files changed, 48 insertions(+), 20 deletions(-) diff --git a/include/types/proxy.h b/include/types/proxy.h index 4766e130d..26af50154 100644 --- a/include/types/proxy.h +++ b/include/types/proxy.h @@ -177,7 +177,15 @@ struct error_snapshot { unsigned int sid; /* ID of the faulty session */ unsigned int ev_id; /* event number (counter incremented for each capture) */ unsigned int state; /* message state before the error (when saved) */ - unsigned int flags; /* buffer flags */ + unsigned int b_flags; /* buffer flags */ + unsigned int s_flags; /* session flags */ + unsigned int t_flags; /* transaction flags */ + unsigned int m_flags; /* message flags */ + unsigned int b_out; /* pending output bytes */ + unsigned int b_wrap; /* position where the buffer is expected to wrap */ + unsigned long long b_tot; /* total bytes transferred via this buffer */ + unsigned long long m_clen; /* chunk len for this message */ + unsigned long long m_blen; /* body len for this message */ struct server *srv; /* server associated with the error (or NULL) */ struct proxy *oe; /* other end = frontend or backend involved */ struct sockaddr_storage src; /* client's address */ diff --git a/src/dumpstats.c b/src/dumpstats.c index 465844f84..ae19db796 100644 --- a/src/dumpstats.c +++ b/src/dumpstats.c @@ -3925,43 +3925,55 @@ static int stats_dump_errors_to_buffer(struct stream_interface *si) char pn[INET6_ADDRSTRLEN]; struct tm tm; + int port; get_localtime(es->when.tv_sec, &tm); chunk_printf(&msg, " \n[%02d/%s/%04d:%02d:%02d:%02d.%03d]", tm.tm_mday, monthname[tm.tm_mon], tm.tm_year+1900, tm.tm_hour, tm.tm_min, tm.tm_sec, (int)(es->when.tv_usec/1000)); - addr_to_str(&es->src, pn, sizeof(pn)); + switch (addr_to_str(&es->src, pn, sizeof(pn))) { + case AF_INET: + case AF_INET6: + port = get_host_port(&es->src); + break; + default: + port = 0; + } + switch (si->applet.ctx.errors.buf) { case 0: chunk_printf(&msg, " frontend %s (#%d): invalid request\n" - " src %s, session #%d, backend %s (#%d), server %s (#%d)\n" - " HTTP internal state %d, buffer flags 0x%08x, event #%u\n" - " request length %d bytes, error at position %d:\n \n", + " backend %s (#%d)", si->applet.ctx.errors.px->id, si->applet.ctx.errors.px->uuid, - pn, es->sid, (es->oe->cap & PR_CAP_BE) ? es->oe->id : "", - (es->oe->cap & PR_CAP_BE) ? es->oe->uuid : -1, - es->srv ? es->srv->id : "", - es->srv ? es->srv->puid : -1, - es->state, es->flags, es->ev_id, - es->len, es->pos); + (es->oe->cap & PR_CAP_BE) ? es->oe->id : "", + (es->oe->cap & PR_CAP_BE) ? es->oe->uuid : -1); break; case 1: chunk_printf(&msg, " backend %s (#%d) : invalid response\n" - " src %s, session #%d, frontend %s (#%d), server %s (#%d)\n" - " HTTP internal state %d, buffer flags 0x%08x, event #%u\n" - " response length %d bytes, error at position %d:\n \n", + " frontend %s (#%d)", si->applet.ctx.errors.px->id, si->applet.ctx.errors.px->uuid, - pn, es->sid, es->oe->id, es->oe->uuid, - es->srv ? es->srv->id : "", - es->srv ? es->srv->puid : -1, - es->state, es->flags, es->ev_id, - es->len, es->pos); + es->oe->id, es->oe->uuid); break; } + chunk_printf(&msg, + ", server %s (#%d), event #%u\n" + " src %s:%d, session #%d, session flags 0x%08x\n" + " HTTP msg state %d, msg flags 0x%08x, tx flags 0x%08x\n" + " HTTP chunk len %lld bytes, HTTP body len %lld bytes\n" + " buffer flags 0x%08x, out %d bytes, total %lld bytes\n" + " pending %d bytes, wrapping at %d, error at position %d:\n \n", + es->srv ? es->srv->id : "", es->srv ? es->srv->puid : -1, + es->ev_id, + pn, port, es->sid, es->s_flags, + es->state, es->m_flags, es->t_flags, + es->m_clen, es->m_blen, + es->b_flags, es->b_out, es->b_tot, + es->len, es->b_wrap, es->pos); + if (bi_putchk(si->ib, &msg) == -1) { /* Socket buffer full. Let's try again later from the same point */ return 0; diff --git a/src/proto_http.c b/src/proto_http.c index aec711cb7..5f169152d 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -7235,8 +7235,16 @@ void http_capture_bad_message(struct error_snapshot *es, struct session *s, es->oe = other_end; es->src = s->req->prod->addr.from; es->state = state; - es->flags = buf->flags; es->ev_id = error_snapshot_id++; + es->b_flags = buf->flags; + es->s_flags = s->flags; + es->t_flags = s->txn.flags; + es->m_flags = msg->flags; + es->b_out = buf->o; + es->b_wrap = buf->data + buf->size - buf->p; + es->b_tot = buf->total; + es->m_clen = msg->chunk_len; + es->m_blen = msg->body_len; } /* Return in and the pointer and length of occurrence of