From: des Date: Mon, 31 Jul 2006 06:36:56 +0000 (+0000) Subject: Clone varnishncsa off of varnishlog. Anders will hack on it to produce X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1913e6cccf744040a611785197d28e0e588f42ec;p=varnish Clone varnishncsa off of varnishlog. Anders will hack on it to produce NCSA-style (common / combined) logs. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@570 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/Makefile.am b/varnish-cache/bin/Makefile.am index ce96ce37..8f35401a 100644 --- a/varnish-cache/bin/Makefile.am +++ b/varnish-cache/bin/Makefile.am @@ -1,3 +1,3 @@ # $Id$ -SUBDIRS = varnishd varnishlog varnishstat varnishtester varnishtop +SUBDIRS = varnishd varnishlog varnishncsa varnishstat varnishtester varnishtop diff --git a/varnish-cache/bin/varnishncsa/Makefile.am b/varnish-cache/bin/varnishncsa/Makefile.am new file mode 100644 index 00000000..064bf885 --- /dev/null +++ b/varnish-cache/bin/varnishncsa/Makefile.am @@ -0,0 +1,13 @@ +# $Id$ + +INCLUDES = -I$(top_srcdir)/include + +bin_PROGRAMS = varnishncsa + +man_MANS = varnishncsa.1 + +varnishncsa_SOURCES = varnishncsa.c + +varnishncsa_LDADD = \ + $(top_builddir)/lib/libvarnishapi/libvarnishapi.la \ + $(top_builddir)/lib/libsbuf/libsbuf.a diff --git a/varnish-cache/bin/varnishncsa/varnishncsa.1 b/varnish-cache/bin/varnishncsa/varnishncsa.1 new file mode 100644 index 00000000..0f10ffdb --- /dev/null +++ b/varnish-cache/bin/varnishncsa/varnishncsa.1 @@ -0,0 +1,126 @@ +.\" +.\" $Id$ +.\" +.Dd July 11, 2006 +.Dt VARNISHNCSA 1 +.Os +.Sh NAME +.Nm varnishncsa +.Nd Generate NCSA common / combined logs +.Sh SYNOPSIS +.Nm +.Op Fl C +.Op Fl b +.Op Fl c +.Op Fl o +.Op Fl I Ar regex +.Op Fl X Ar regex +.Op Fl i Ar tag +.Op Fl r Ar file +.Op Fl w Ar file +.Op Fl x Ar tag +.Sh DESCRIPTION +The +.Nm +utility reads and presents +.Xr varnishd 1 +shared memory logs. +.Pp +The following options are available: +.Bl -tag -width Fl +.It Fl C +Ignore case when matching regular expressions. +.It Fl b +Include log entries which result from communication with a backend +server. +If neither +.Fl b +nor +.Fl c +is specified, +.Nm +acts as if they both were. +.It Fl c +Include log entries which result from communication with a client. +If neither +.Fl b +nor +.Fl c +is specified, +.Nm +acts as if they both were. +.It Fl o +Group log entries by request ID. +.It Fl I Ar regex +Include log entries which match the specified regular expression. +If neither +.Fl I +nor +.Fl i +is specified, all log entries are included. +.It Fl X Ar regex +Exclude log entries which match the specified regular expression. +.It Fl i Ar tag +Include log entries with the specified tag. +If neither +.Fl I +nor +.Fl i +is specified, all log entries are included. +.It Fl r Ar file +Read log entries from +.Ar file +instead of shared memory. +.It Fl w Ar file +Write log entries to +.Ar file +instead of displaying them. +.It Fl x Ar tag +Exclude log entries with the specified tag. +.El +.Sh TAGS +The following log entry tags are currently defined: +.\" keep in sync with include/shmlog_tags.h +.\" XXX add descriptions +.Bl -tag -width 16 +.It Dv Backend +.It Dv BackendClose +.It Dv BackendOpen +.It Dv BackendReuse +.It Dv BackendXID +.It Dv BldHdr +.It Dv CLI +.It Dv ClientAddr +.It Dv Debug +.It Dv Error +.It Dv ExpBan +.It Dv ExpKill +.It Dv ExpPick +.It Dv Header +.It Dv Hit +.It Dv HttpError +.It Dv Length +.It Dv LostHeader +.It Dv Protocol +.It Dv Request +.It Dv Response +.It Dv SessionClose +.It Dv SessionOpen +.It Dv SessionReuse +.It Dv Status +.It Dv URL +.It Dv VCL_call +.It Dv VCL_return +.It Dv VCL_trace +.It Dv WorkThread +.It Dv XID +.El +.Sh SEE ALSO +.Xr varnishd 1 , +.Xr varnishstat 1 +.Sh HISTORY +The +.Nm +utility was developed by +.An Poul-Henning Kamp Aq phk@freebsd.dk +in cooperation with Verdens Gang AS and Linpro AS. diff --git a/varnish-cache/bin/varnishncsa/varnishncsa.c b/varnish-cache/bin/varnishncsa/varnishncsa.c new file mode 100644 index 00000000..7e5b3982 --- /dev/null +++ b/varnish-cache/bin/varnishncsa/varnishncsa.c @@ -0,0 +1,295 @@ +/* + * $Id$ + * + * Log tailer for Varnish + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "shmlog.h" +#include "varnishapi.h" + + +static char * +vis_it(unsigned char *p) +{ + static char visbuf[255*4 + 3 + 1]; + + strcpy(visbuf, " ["); + strvisx(visbuf + 2, p + 4, p[1], + VIS_OCTAL | VIS_TAB | VIS_NL); + strcat(visbuf, "]"); + return (visbuf); +} + +/* Ordering-----------------------------------------------------------*/ + +static struct sbuf *ob[65536]; +static int hc[65536]; +static int xrf[65536]; + +static void +clean_order(void) +{ + unsigned u; + + for (u = 0; u < 65536; u++) { + if (ob[u] == NULL) + continue; + sbuf_finish(ob[u]); + if (sbuf_len(ob[u])) + printf("%s\n", sbuf_data(ob[u])); + sbuf_clear(ob[u]); + } +} + +static void +order(unsigned char *p, int h_opt) +{ + unsigned u, v; + + u = (p[2] << 8) | p[3]; + if (ob[u] == NULL) { + ob[u] = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND); + assert(ob[u] != NULL); + } + v = 0; + switch (p[0]) { + case SLT_VCL_call: + sbuf_printf(ob[u], "%02x %3d %4d %-12s", + p[0], p[1], u, VSL_tags[p[0]]); + if (p[1] > 0) { + sbuf_cat(ob[u], " <"); + sbuf_bcat(ob[u], p + 4, p[1]); + } + if (h_opt && p[1] == 3 && !memcmp(p + 4, "hit", 3)) + hc[u]++; + break; + case SLT_VCL_trace: + if (p[1] > 0) { + sbuf_cat(ob[u], " "); + sbuf_bcat(ob[u], p + 4, p[1]); + } + break; + case SLT_VCL_return: + if (p[1] > 0) { + sbuf_cat(ob[u], " "); + sbuf_bcat(ob[u], p + 4, p[1]); + sbuf_cat(ob[u], ">\n"); + } + if (h_opt && p[1] == 7 && !memcmp(p + 4, "deliver", 7)) + hc[u]++; + if (h_opt && p[1] == 6 && !memcmp(p + 4, "insert", 6)) { + if (hc[xrf[u]] == 1) { + hc[u] += 2; + hc[xrf[u]] = 4; + } + } + break; + case SLT_Debug: + if (p[1] == 0) + break; + if (!h_opt) + ; + else if (p[1] > 4 && !memcmp(p + 4, "TTD:", 4)) + break; + sbuf_printf(ob[u], "%02x %3d %4d %-12s", + p[0], p[1], u, VSL_tags[p[0]]); + if (p[1] > 0) + sbuf_cat(ob[u], vis_it(p)); + sbuf_cat(ob[u], "\n"); + break; + case SLT_HttpError: + if (!h_opt) + v = 1; + else if (p[1] == 16 && !memcmp(p + 4, "Received nothing", 16)) + ; + else if (p[1] == 17 && !memcmp(p + 4, "Received errno 54", 17)) + ; + else + v = 1; + break; + case SLT_SessionClose: + if (!h_opt) + v = 1; + else if (p[1] == 10 && !memcmp(p + 4, "no request", 10)) + ; + else if (p[1] == 7 && !memcmp(p + 4, "timeout", 7)) + ; + else + v = 1; + break; + case SLT_Request: + if (h_opt && p[1] == 3 && !memcmp(p + 4, "GET", 3)) + hc[u]++; + if (h_opt && p[1] == 4 && !memcmp(p + 4, "HEAD", 4)) + hc[u]++; + v = 1; + break; + case SLT_Backend: + xrf[u] = atoi(p + 4); + v = 1; + break; + case SLT_Status: + if (h_opt && p[1] == 3 && !memcmp(p + 4, "200", 3)) + hc[u]++; + v = 1; + break; + default: + v = 1; + break; + } + if (v) { + sbuf_printf(ob[u], "%02x %3d %4d %-12s", + p[0], p[1], u, VSL_tags[p[0]]); + if (p[1] > 0) { + sbuf_cat(ob[u], " <"); + sbuf_bcat(ob[u], p + 4, p[1]); + sbuf_cat(ob[u], ">"); + } + sbuf_cat(ob[u], "\n"); + } + if (u == 0) { + sbuf_finish(ob[u]); + printf("%s", sbuf_data(ob[u])); + sbuf_clear(ob[u]); + return; + } + switch (p[0]) { + case SLT_SessionClose: + case SLT_SessionReuse: + case SLT_BackendClose: + case SLT_BackendReuse: + sbuf_finish(ob[u]); + if ((hc[u] != 4 || h_opt == 0) && sbuf_len(ob[u]) > 1) + printf("%s\n", sbuf_data(ob[u])); + sbuf_clear(ob[u]); + hc[u] = 0; + xrf[u] = 0; + break; + default: + break; + } +} + + + +/*--------------------------------------------------------------------*/ + +static void +Usage(void) +{ + fprintf(stderr, "Usage: varnishncsa [-o] [-w file] [-r file]\n"); + exit(2); +} + +int +main(int argc, char **argv) +{ + int i, c; + unsigned u, v; + unsigned char *p; + int o_flag = 0; + char *w_opt = NULL; + FILE *wfile = NULL; + int h_opt = 0; + struct VSL_data *vd; + + vd = VSL_New(); + + while ((c = getopt(argc, argv, VSL_ARGS "how:")) != -1) { + i = VSL_Arg(vd, c, optarg); + if (i < 0) + exit (1); + if (i > 0) + continue; + switch (c) { + case 'h': + h_opt = 1; + break; + case 'o': + o_flag = 1; + break; + case 'w': + w_opt = optarg; + break; + default: + Usage(); + } + } + + if (VSL_OpenLog(vd)) + exit (1); + + if (o_flag && w_opt != NULL) + Usage(); + + if (w_opt != NULL) { + wfile = fopen(w_opt, "w"); + if (wfile == NULL) { + perror(w_opt); + exit (1); + } + } + u = 0; + v = 0; + + while (1) { + i = VSL_NextLog(vd, &p); + if (i < 0) + break; + if (i == 0) { + if (w_opt == NULL) { + if (o_flag && ++v == 100) + clean_order(); + fflush(stdout); + } else if (++v == 100) { + fflush(wfile); + printf("\nFlushed\n"); + } + usleep(50000); + continue; + } + v = 0; + if (wfile != NULL) { + i = fwrite(p, 4 + p[1], 1, wfile); + if (i != 1) + perror(w_opt); + u++; + if (!(u % 1000)) { + printf("%u\r", u); + fflush(stdout); + } + continue; + } + if (o_flag) { + order(p, h_opt); + continue; + } + u = (p[2] << 8) | p[3]; + printf("%02x %3d %4d %-12s", + p[0], p[1], u, VSL_tags[p[0]]); + + if (p[1] > 0) { + if (p[0] != SLT_Debug) { + printf(" <"); + fwrite(p + 4, p[1], 1, stdout); + printf(">"); + } else { + fputs(vis_it(p), stdout); + } + + } + printf("\n"); + } + if (o_flag) + clean_order(); + return (0); +} diff --git a/varnish-cache/configure.ac b/varnish-cache/configure.ac index 1be4245f..6e64a3a4 100644 --- a/varnish-cache/configure.ac +++ b/varnish-cache/configure.ac @@ -69,6 +69,7 @@ AC_CONFIG_FILES([ bin/Makefile bin/varnishd/Makefile bin/varnishlog/Makefile + bin/varnishncsa/Makefile bin/varnishstat/Makefile bin/varnishtester/Makefile bin/varnishtop/Makefile