r4663 - in trunk/varnish-cache: . bin bin/varnishsizes

kristian at varnish-cache.org kristian at varnish-cache.org
Thu Apr 15 14:01:56 CEST 2010


Author: kristian
Date: 2010-04-15 14:01:56 +0200 (Thu, 15 Apr 2010)
New Revision: 4663

Added:
   trunk/varnish-cache/bin/varnishsizes/
   trunk/varnish-cache/bin/varnishsizes/Makefile.am
   trunk/varnish-cache/bin/varnishsizes/varnishsizes.1
   trunk/varnish-cache/bin/varnishsizes/varnishsizes.c
Modified:
   trunk/varnish-cache/bin/Makefile.am
   trunk/varnish-cache/configure.ac
Log:
Add varnishsizes, which is varnishhist for the Length-header

Though it works fine, varnishhist and *sizes should probably be merged
together at some point.


Modified: trunk/varnish-cache/bin/Makefile.am
===================================================================
--- trunk/varnish-cache/bin/Makefile.am	2010-04-15 07:33:44 UTC (rev 4662)
+++ trunk/varnish-cache/bin/Makefile.am	2010-04-15 12:01:56 UTC (rev 4663)
@@ -3,5 +3,5 @@
 SUBDIRS = varnishadm varnishd varnishlog varnishncsa varnishreplay varnishtest
 
 if HAVE_CURSES
-SUBDIRS += varnishhist varnishstat varnishtop
+SUBDIRS += varnishhist varnishstat varnishtop varnishsizes
 endif

Added: trunk/varnish-cache/bin/varnishsizes/Makefile.am
===================================================================
--- trunk/varnish-cache/bin/varnishsizes/Makefile.am	                        (rev 0)
+++ trunk/varnish-cache/bin/varnishsizes/Makefile.am	2010-04-15 12:01:56 UTC (rev 4663)
@@ -0,0 +1,16 @@
+# $Id$
+
+INCLUDES = -I$(top_srcdir)/include
+
+bin_PROGRAMS = varnishsizes
+
+dist_man_MANS = varnishsizes.1
+
+varnishsizes_SOURCES = varnishsizes.c
+
+varnishsizes_LDADD = \
+	$(top_builddir)/lib/libvarnish/libvarnish.la \
+	$(top_builddir)/lib/libvarnishcompat/libvarnishcompat.la \
+	$(top_builddir)/lib/libvarnishapi/libvarnishapi.la \
+	-lm \
+	${CURSES_LIBS} ${PTHREAD_LIBS}

Added: trunk/varnish-cache/bin/varnishsizes/varnishsizes.1
===================================================================
--- trunk/varnish-cache/bin/varnishsizes/varnishsizes.1	                        (rev 0)
+++ trunk/varnish-cache/bin/varnishsizes/varnishsizes.1	2010-04-15 12:01:56 UTC (rev 4663)
@@ -0,0 +1,151 @@
+.\"-
+.\" Copyright (c) 2006 Verdens Gang AS
+.\" Copyright (c) 2006-2009 Linpro AS
+.\" All rights reserved.
+.\"
+.\" Author: Dag-Erling Smørgrav <des at des.no>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $Id$
+.\"
+.Dd June 28, 2007
+.Dt VARNISHSIZES 1
+.Os
+.Sh NAME
+.Nm varnishsizes
+.Nd Varnish request histogram
+.Sh SYNOPSIS
+.Nm
+.Op Fl b
+.Op Fl C
+.Op Fl c
+.Op Fl d
+.Op Fl I Ar regex
+.Op Fl i Ar tag
+.Op Fl n Ar varnish_name
+.Op Fl r Ar file
+.Op Fl V
+.Op Fl w Ar delay
+.Op Fl X Ar regex
+.Op Fl x Ar tag
+.Sh DESCRIPTION
+The
+.Nm
+utility reads
+.Xr varnishd 1
+shared memory logs and presents a continuously updated histogram
+showing the distribution of the last
+.Va N
+requests by their processing.
+The value of
+.Va N
+and the vertical scale are displayed in the top left corner.
+The horizontal scale is logarithmic.
+Hits are marked with a pipe character ("|"), and misses are marked
+with a hash character ("#").
+.Pp
+The following options are available:
+.Bl -tag -width Fl
+.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
+Ignore case when matching regular expressions.
+.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 d
+Process old log entries on startup.
+Normally,
+.Nm
+will only process entries which are written to the log after it
+starts.
+.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 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 n
+Specifies the name of the
+.Nm varnishd
+instance to get logs from.
+If
+.Fl n
+is not specified, the host name is used.
+.It Fl r Ar file
+Read log entries from
+.Ar file
+instead of shared memory.
+.It Fl V
+Display the version number and exit.
+.It Fl w Ar delay
+Wait at least
+.Ar delay
+seconds between each update.
+The default is 1.
+.Ar file
+instead of displaying them.
+The file will be overwritten unless the
+.Fl a
+option was specified.
+.It Fl X Ar regex
+Exclude log entries which match the specified regular expression.
+.It Fl x Ar tag
+Exclude log entries with the specified tag.
+.El
+.Sh SEE ALSO
+.Xr varnishd 1 ,
+.Xr varnishlog 1 ,
+.Xr varnishncsa 1 ,
+.Xr varnishstat 1 ,
+.Xr varnishtop 1
+.Sh SIZESORY
+The
+.Nm
+utility was developed by
+.An Poul-Henning Kamp Aq phk at phk.freebsd.dk
+in cooperation with Verdens Gang AS and Linpro AS.
+This manual page was written by
+.An Dag-Erling Sm\(/orgrav Aq des at des.no .

Added: trunk/varnish-cache/bin/varnishsizes/varnishsizes.c
===================================================================
--- trunk/varnish-cache/bin/varnishsizes/varnishsizes.c	                        (rev 0)
+++ trunk/varnish-cache/bin/varnishsizes/varnishsizes.c	2010-04-15 12:01:56 UTC (rev 4663)
@@ -0,0 +1,353 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2009 Linpro AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ * Author: Dag-Erling Smørgrav <des at des.no>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Log tailer for Varnish
+ */
+
+#include "config.h"
+
+#include "svnid.h"
+SVNID("$Id$")
+
+#include <sys/types.h>
+#include <curses.h>
+#include <errno.h>
+#include <limits.h>
+#include <math.h>
+#include <pthread.h>
+#include <regex.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "libvarnish.h"
+#include "shmlog.h"
+#include "varnishapi.h"
+
+#define HIST_N 2000 /* how far back we remember */
+#define HIST_LOW 1 /* low end of log range */
+#define HIST_HIGH 8 /* high end of log range */
+#define HIST_RANGE (HIST_HIGH - HIST_LOW)
+#define HIST_RES 100 /* bucket resolution */
+#define HIST_BUCKETS (HIST_RANGE * HIST_RES)
+
+static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
+
+static int delay = 1;
+static unsigned rr_hist[HIST_N];
+static unsigned nhist;
+static unsigned next_hist;
+static unsigned bucket_miss[HIST_BUCKETS];
+static unsigned bucket_hit[HIST_BUCKETS];
+static unsigned char hh[FD_SETSIZE];
+
+static double log_ten;
+
+static int scales[] = {
+	1,
+	2,
+	3,
+	4,
+	5,
+	10,
+	15,
+	20,
+	25,
+	50,
+	100,
+	250,
+	500,
+	1000,
+	2500,
+	5000,
+	10000,
+	25000,
+	50000,
+	100000,
+	INT_MAX
+};
+
+static void
+update(void)
+{
+	int w = COLS / HIST_RANGE;
+	int n = w * HIST_RANGE;
+	unsigned bm[n], bh[n];
+	unsigned max;
+	int i, j, scale;
+
+	erase();
+
+	/* Draw horizontal axis */
+	w = COLS / HIST_RANGE;
+	n = w * HIST_RANGE;
+	for (i = 0; i < n; ++i)
+		mvaddch(LINES - 2, i, '-');
+	for (i = 0, j = HIST_LOW; i < HIST_RANGE; ++i, ++j) {
+		mvaddch(LINES - 2, w * i, '+');
+		mvprintw(LINES - 1, w * i, "|1e%d", j);
+	}
+
+	mvprintw(0, 0, "%*s", COLS - 1, VSL_Name());
+
+	/* count our flock */
+	for (i = 0; i < n; ++i)
+		bm[i] = bh[i] = 0;
+	for (i = 0, max = 1; i < HIST_BUCKETS; ++i) {
+		j = i * n / HIST_BUCKETS;
+		bm[j] += bucket_miss[i];
+		bh[j] += bucket_hit[i];
+		if (bm[j] + bh[j] > max)
+			max = bm[j] + bh[j];
+	}
+
+	/* scale */
+	for (i = 0; max / scales[i] > LINES - 3; ++i)
+		/* nothing */ ;
+	scale = scales[i];
+
+	mvprintw(0, 0, "1:%d, n = %d", scale, nhist);
+
+	/* show them */
+	for (i = 0; i < n; ++i) {
+		for (j = 0; j < bm[i] / scale; ++j)
+			mvaddch(LINES - 3 - j, i, '#');
+		for (; j < (bm[i] + bh[i]) / scale; ++j)
+			mvaddch(LINES - 3 - j, i, '|');
+	}
+
+	refresh();
+}
+
+static int
+h_hist(void *priv, enum shmlogtag tag, unsigned fd, unsigned len,
+    unsigned spec, const char *ptr)
+{
+	double b;
+	int i, j, tmp;
+
+	(void)priv;
+	(void)len;
+	(void)spec;
+
+	if (fd >= FD_SETSIZE)
+		/* oops */
+		return (0);
+
+	if (tag == SLT_Hit) {
+		hh[fd] = 1;
+		return (0);
+	}
+	if (tag != SLT_Length)
+		return (0);
+
+	/* determine processing time */
+	i = sscanf(ptr, "%d", &tmp);
+	assert(i == 1);
+
+	/* Typically 304s and tend to throw the scaling off */
+	if (tmp == 0)
+		return 0;
+
+	b = tmp;
+	/* select bucket */
+	i = HIST_RES * (log(b) / log_ten);
+	if (i < HIST_LOW * HIST_RES)
+		i = HIST_LOW * HIST_RES;
+	if (i >= HIST_HIGH * HIST_RES)
+		i = HIST_HIGH * HIST_RES - 1;
+	i -= HIST_LOW * HIST_RES;
+	assert(i >= 0);
+	assert(i < HIST_BUCKETS);
+
+	pthread_mutex_lock(&mtx);
+
+	/* phase out old data */
+	if (nhist == HIST_N) {
+		j = rr_hist[next_hist];
+		if (j < 0)  {
+			assert(bucket_miss[-j] > 0);
+			bucket_miss[-j]--;
+		} else {
+			assert(bucket_hit[j] > 0);
+			bucket_hit[j]--;
+		}
+	} else {
+		++nhist;
+	}
+
+	/* phase in new data */
+	if (hh[fd] || i == 0) {
+		bucket_hit[i]++;
+		rr_hist[next_hist] = i;
+	} else {
+		bucket_miss[i]++;
+		rr_hist[next_hist] = -i;
+	}
+	if (++next_hist == HIST_N) {
+		next_hist = 0;
+	}
+	hh[fd] = 0;
+
+	pthread_mutex_unlock(&mtx);
+
+	return (0);
+}
+
+static void *
+accumulate_thread(void *arg)
+{
+	struct VSL_data *vd = arg;
+	int i;
+
+	for (;;) {
+		i = VSL_Dispatch(vd, h_hist, NULL);
+		if (i < 0)
+			break;
+		if (i == 0)
+			usleep(50000);
+	}
+	return (arg);
+}
+
+static void
+do_curses(struct VSL_data *vd)
+{
+	pthread_t thr;
+	int ch;
+
+	if (pthread_create(&thr, NULL, accumulate_thread, vd) != 0) {
+		fprintf(stderr, "pthread_create(): %s\n", strerror(errno));
+		exit(1);
+	}
+
+	initscr();
+	raw();
+	noecho();
+	nonl();
+	intrflush(stdscr, FALSE);
+	curs_set(0);
+	erase();
+	for (;;) {
+		pthread_mutex_lock(&mtx);
+		update();
+		pthread_mutex_unlock(&mtx);
+
+		timeout(delay * 1000);
+		switch ((ch = getch())) {
+		case ERR:
+			break;
+#ifdef KEY_RESIZE
+		case KEY_RESIZE:
+			erase();
+			break;
+#endif
+		case '\014': /* Ctrl-L */
+		case '\024': /* Ctrl-T */
+			redrawwin(stdscr);
+			refresh();
+			break;
+		case '\003': /* Ctrl-C */
+			raise(SIGINT);
+			break;
+		case '\032': /* Ctrl-Z */
+			endwin();
+			raise(SIGTSTP);
+			break;
+		case '\021': /* Ctrl-Q */
+		case 'Q':
+		case 'q':
+			endwin();
+			return;
+		case '0':
+		case '1':
+		case '2':
+		case '3':
+		case '4':
+		case '5':
+		case '6':
+		case '7':
+		case '8':
+		case '9':
+			delay = 1 << (ch - '0');
+			break;
+		default:
+			beep();
+			break;
+		}
+	}
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+usage(void)
+{
+	fprintf(stderr, "usage: varnishsizes "
+	    "%s [-n varnish_name] [-V] [-w delay]\n", VSL_USAGE);
+	exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+	int o;
+	struct VSL_data *vd;
+	const char *n_arg = NULL;
+
+	vd = VSL_New();
+
+	while ((o = getopt(argc, argv, VSL_ARGS "n:Vw:")) != -1) {
+		switch (o) {
+		case 'n':
+			n_arg = optarg;
+			break;
+		case 'V':
+			varnish_version("varnishsizes");
+			exit(0);
+		case 'w':
+			delay = atoi(optarg);
+			break;
+		default:
+			if (VSL_Arg(vd, o, optarg) > 0)
+				break;
+			usage();
+		}
+	}
+
+	if (VSL_OpenLog(vd, n_arg))
+		exit(1);
+
+	log_ten = log(10.0);
+
+	do_curses(vd);
+	exit(0);
+}

Modified: trunk/varnish-cache/configure.ac
===================================================================
--- trunk/varnish-cache/configure.ac	2010-04-15 07:33:44 UTC (rev 4662)
+++ trunk/varnish-cache/configure.ac	2010-04-15 12:01:56 UTC (rev 4663)
@@ -449,6 +449,7 @@
     bin/varnishncsa/Makefile
     bin/varnishreplay/Makefile
     bin/varnishstat/Makefile
+    bin/varnishsizes/Makefile
     bin/varnishtest/Makefile
     bin/varnishtop/Makefile
     doc/Makefile




More information about the varnish-commit mailing list