r4911 - in trunk/varnish-cache: bin/varnishstat bin/varnishtest include lib/libvarnishapi

phk at varnish-cache.org phk at varnish-cache.org
Sun Jun 6 00:41:54 CEST 2010


Author: phk
Date: 2010-06-06 00:41:54 +0200 (Sun, 06 Jun 2010)
New Revision: 4911

Modified:
   trunk/varnish-cache/bin/varnishstat/varnishstat.c
   trunk/varnish-cache/bin/varnishstat/varnishstat.h
   trunk/varnish-cache/bin/varnishstat/varnishstat_curses.c
   trunk/varnish-cache/bin/varnishtest/vtc_varnish.c
   trunk/varnish-cache/include/varnishapi.h
   trunk/varnish-cache/lib/libvarnishapi/Makefile.am
   trunk/varnish-cache/lib/libvarnishapi/vsl.c
   trunk/varnish-cache/lib/libvarnishapi/vsl.h
   trunk/varnish-cache/lib/libvarnishapi/vsl_arg.c
   trunk/varnish-cache/lib/libvarnishapi/vsl_log.c
   trunk/varnish-cache/lib/libvarnishapi/vsl_stat.c
Log:
Move the varnishstat -f argument into varnishapi, it is broadly
applicable and can be implemented more efficiently this way.

The new syntax is an expansion of the old, which allows
"class.ident.name" or just "name" patterns to be specified.

A pattern which starts with '^' excludes the matching fields,
otherwise the pattern includes them.

If the first pattern is an exclude pattern, all fields start
out included, and vice versa.

Notice that "class" and "ident" fields always must have their
trailing '.' even if they are empty.

Each subcomponent can have a '*' suffix, which will ("glob") match
anything.

Multiple "-f" arguments can be given, they will be concatenated.

All patterns will be tested sequentially, and the last one that
matches determines the result.

Example:

	-f "SMA..sma_nreq,^SMA.ba*." -f "shm_*"

This will return:
	SMA.storage_0.sma_nreq
	shm_records
	shm_writes
	...

but not:
	SMA.storage_0.sma_nobj
	SMA.bar.sma_nreq
	sms_nreq
	...




Modified: trunk/varnish-cache/bin/varnishstat/varnishstat.c
===================================================================
--- trunk/varnish-cache/bin/varnishstat/varnishstat.c	2010-06-05 20:50:01 UTC (rev 4910)
+++ trunk/varnish-cache/bin/varnishstat/varnishstat.c	2010-06-05 22:41:54 UTC (rev 4911)
@@ -49,62 +49,23 @@
 #include "varnishapi.h"
 #include "varnishstat.h"
 
-#define FIELD_EXCLUSION_CHARACTER '^'
-
-int
-show_field(const char* field, const char *fields)
-{
-	const char* field_start;
-	const char* field_end;
-	int field_length;
-	int match_value = 1;
-
-	if (fields[0] == FIELD_EXCLUSION_CHARACTER) {
-		match_value = 0;
-		fields++;
-	}
-
-	field_start = strstr(fields, field);
-	if (field_start != NULL) {
-		field_length = strlen( field );
-
-		while (field_start != NULL) {
-			field_end = field_start + field_length;
-			if ((field_start == fields ||
-			    *(field_start - 1) == ',') &&
-			    (*field_end == ',' || *field_end == '\0'))
-				return (match_value);
-			field_start = strstr( field_end, field );
-		}
-	}
-
-	return (!match_value);
-}
-
 /*--------------------------------------------------------------------*/
 
-struct xml_priv {
-	const char *fields;
-};
-
 static int
 do_xml_cb(void *priv, const struct vsl_statpt * const pt)
 {
 	uint64_t val;
-	struct xml_priv *xp;
 
-	xp = priv;
-	if (xp->fields != NULL && !show_field(pt->nm, xp->fields))
-		return (0);
+	(void)priv;
 	assert(!strcmp(pt->fmt, "uint64_t"));
 	val = *(const volatile uint64_t*)pt->ptr;
 
 	printf("\t<stat>\n");
-	if (strcmp(pt->type, ""))
-		printf("\t\t<type>%s</type>\n", pt->type);
+	if (strcmp(pt->class, ""))
+		printf("\t\t<type>%s</type>\n", pt->class);
 	if (strcmp(pt->ident, ""))
 		printf("\t\t<ident>%s</ident>\n", pt->ident);
-	printf("\t\t<name>%s</name>\n", pt->nm);
+	printf("\t\t<name>%s</name>\n", pt->name);
 	printf("\t\t<value>%ju</value>\n", val);
 	printf("\t\t<flag>%c</flag>\n", pt->flag);
 	printf("\t\t<description>%s</description>\n", pt->desc);
@@ -113,19 +74,16 @@
 }
 
 static void
-do_xml(const struct VSL_data *vd, const char* fields)
+do_xml(const struct VSL_data *vd)
 {
 	char time_stamp[20];
 	time_t now;
-	struct xml_priv xp;
 
-	xp.fields = fields;
-
 	printf("<?xml version=\"1.0\"?>\n");
 	now = time(NULL);
 	(void)strftime(time_stamp, 20, "%Y-%m-%dT%H:%M:%S", localtime(&now));
 	printf("<varnishstat timestamp=\"%s\">\n", time_stamp);
-	(void)VSL_IterStat(vd, do_xml_cb, &xp);
+	(void)VSL_IterStat(vd, do_xml_cb, NULL);
 	printf("</varnishstat>\n");
 }
 
@@ -133,7 +91,6 @@
 
 struct once_priv {
 	double	up;
-	const char *fields;
 	int pad;
 };
 
@@ -145,16 +102,14 @@
 	int i;
 
 	op = priv;
-	if (op->fields != NULL && !show_field(pt->nm, op->fields))
-		return (0);
 	assert(!strcmp(pt->fmt, "uint64_t"));
 	val = *(const volatile uint64_t*)pt->ptr;
 	i = 0;
-	if (strcmp(pt->type, "")) 
-		i += printf("%s.", pt->type);
+	if (strcmp(pt->class, "")) 
+		i += printf("%s.", pt->class);
 	if (strcmp(pt->ident, ""))
 		i += printf("%s.", pt->ident);
-	i += printf("%s", pt->nm);
+	i += printf("%s", pt->name);
 	if (i > op->pad)
 		op->pad = i + 1;
 	printf("%*.*s", op->pad - i, op->pad - i, "");
@@ -166,13 +121,12 @@
 }
 
 static void
-do_once(const struct VSL_data *vd, const struct varnish_stats *VSL_stats, const char* fields)
+do_once(const struct VSL_data *vd, const struct varnish_stats *VSL_stats)
 {
 	struct once_priv op;
 
 	memset(&op, 0, sizeof op);
 	op.up = VSL_stats->uptime;
-	op.fields = fields;
 	op.pad = 18;
 
 	(void)VSL_IterStat(vd, do_once_cb, &op);
@@ -180,7 +134,37 @@
 
 /*--------------------------------------------------------------------*/
 
+static int
+do_list_cb(void *priv, const struct vsl_statpt * const pt)
+{
+	int i;
+
+	(void)priv;
+	i = 0;
+	if (strcmp(pt->class, "")) 
+		i += fprintf(stderr, "%s.", pt->class);
+	if (strcmp(pt->ident, ""))
+		i += fprintf(stderr, "%s.", pt->ident);
+	i += fprintf(stderr, "%s", pt->name);
+	if (i < 30)
+		fprintf(stderr, "%*s", i - 30, "");
+	fprintf(stderr, " %s\n", pt->desc);
+	return (0);
+}
+
 static void
+list_fields(const struct VSL_data *vd)
+{
+	fprintf(stderr, "Varnishstat -f option fields:\n");
+	fprintf(stderr, "Field name                     Description\n");
+	fprintf(stderr, "----------                     -----------\n");
+
+	(void)VSL_IterStat(vd, do_list_cb, NULL);
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
 usage(void)
 {
 #define FMT "    %-28s # %s\n"
@@ -204,66 +188,6 @@
 	exit(1);
 }
 
-static void
-list_fields(void)
-{
-	fprintf(stderr, "Varnishstat -f option fields:\n");
-	fprintf(stderr, "Field name           Description\n");
-	fprintf(stderr, "----------           -----------\n");
-
-#define MAC_STAT(n, t, l, f, d)						\
-	do {								\
-		fprintf(stderr, "%-20s %s\n", #n, d);			\
-	} while (0);
-#include "stat_field.h"
-#undef MAC_STAT
-}
-
-static int
-valid_fields(const char* fields)
-{
-	int i, valid_field, field_length;
-	const char *all_fields[] = {
-#define MAC_STAT(n, t, l, f, d) \
-	#n,
-#include "stat_field.h"
-#undef MAC_STAT
-	NULL };
-	const char *field_start, *field_end;
-
-	if (fields[0] == FIELD_EXCLUSION_CHARACTER)
-		fields++;
-
-	for (field_start = fields; ; field_start = field_end + 1) {
-		field_end = strchr(field_start, ',');
-		if (field_end != NULL)
-			field_length = field_end - field_start;
-		else
-			field_length = strlen(field_start);
-
-		valid_field = 0;
-		for (i = 0; all_fields[i] != NULL; i++) {
-			if (strncmp(field_start, all_fields[i], field_length)
-			     == 0 && field_length == strlen( all_fields[i])) {
-				valid_field = 1;
-				break;
-			}
-		}
-
-		if (!valid_field) {
-			(void)fputs("The field '", stderr);
-			(void)fwrite(field_start, 1, field_length, stderr);
-			(void)fputs("' is not a valid field\n", stderr);
-			return (0);
-		}
-
-		if (field_end == NULL || *field_end == '\0')
-			break;
-	}
-
-	return (1);
-}
-
 int
 main(int argc, char * const *argv)
 {
@@ -271,7 +195,6 @@
 	struct VSL_data *vd;
 	const struct varnish_stats *VSL_stats;
 	int delay = 1, once = 0, xml = 0;
-	const char *fields = NULL;
 
 	vd = VSL_New();
 
@@ -281,10 +204,12 @@
 			once = 1;
 			break;
 		case 'f':
-			fields = optarg;
+			(void)VSL_Stat_Arg(vd, c, optarg);
 			break;
 		case 'l':
-			list_fields();
+			if (VSL_Open(vd))
+				exit(1);
+			list_fields(vd);
 			exit(0);
 		case 'V':
 			varnish_version("varnishstat");
@@ -308,17 +233,12 @@
 	if ((VSL_stats = VSL_OpenStats(vd)) == NULL)
 		exit(1);
 
-	if (fields != NULL && !valid_fields(fields)) {
-		usage();
-		exit(1);
-	}
-
 	if (xml)
-		do_xml(vd, fields);
+		do_xml(vd);
 	else if (once)
-		do_once(vd, VSL_stats, fields);
+		do_once(vd, VSL_stats);
 	else
-		do_curses(vd, VSL_stats, delay, fields);
+		do_curses(vd, VSL_stats, delay);
 
 	exit(0);
 }

Modified: trunk/varnish-cache/bin/varnishstat/varnishstat.h
===================================================================
--- trunk/varnish-cache/bin/varnishstat/varnishstat.h	2010-06-05 20:50:01 UTC (rev 4910)
+++ trunk/varnish-cache/bin/varnishstat/varnishstat.h	2010-06-05 22:41:54 UTC (rev 4911)
@@ -27,5 +27,4 @@
  *
  */
 
-int show_field(const char* field, const char *fields);
-void do_curses(struct VSL_data *vd, const struct varnish_stats *VSL_stats, int delay, const char *fields);
+void do_curses(struct VSL_data *vd, const struct varnish_stats *VSL_stats, int delay);

Modified: trunk/varnish-cache/bin/varnishstat/varnishstat_curses.c
===================================================================
--- trunk/varnish-cache/bin/varnishstat/varnishstat_curses.c	2010-06-05 20:50:01 UTC (rev 4910)
+++ trunk/varnish-cache/bin/varnishstat/varnishstat_curses.c	2010-06-05 22:41:54 UTC (rev 4911)
@@ -65,21 +65,13 @@
 
 static VTAILQ_HEAD(, pt) pthead = VTAILQ_HEAD_INITIALIZER(pthead);
 
-
-struct curses_priv {
-	const char *fields;
-};
-
 static int
 do_curses_cb(void *priv, const struct vsl_statpt * const sp)
 {
-	struct curses_priv *cp;
 	struct pt *pt;
 	char buf[128];
 
-	cp = priv;
-	if (cp->fields != NULL && !show_field(sp->nm, cp->fields))
-		return (0);
+	(void)priv;
 	assert(!strcmp(sp->fmt, "uint64_t"));
 
 	pt = calloc(sizeof *pt, 1);
@@ -91,15 +83,15 @@
 	pt->type = sp->flag;
 
 	*buf = '\0';
-	if (strcmp(sp->type, "")) {
-		strcat(buf, sp->type);
+	if (strcmp(sp->class, "")) {
+		strcat(buf, sp->class);
 		strcat(buf, ".");
 	}
 	if (strcmp(sp->ident, "")) {
 		strcat(buf, sp->ident);
 		strcat(buf, ".");
 	}
-	strcat(buf, sp->nm);
+	strcat(buf, sp->name);
 	strcat(buf, " - ");
 	strcat(buf, sp->desc);
 	pt->name = strdup(buf);
@@ -108,9 +100,8 @@
 }
 
 static void
-prep_pts(const struct VSL_data *vd, const char *fields)
+prep_pts(const struct VSL_data *vd)
 {
-	struct curses_priv cp;
 	struct pt *pt, *pt2;
 
 	VTAILQ_FOREACH_SAFE(pt, &pthead, next, pt2) {
@@ -118,10 +109,8 @@
 		free(pt->name);
 		free(pt);
 	}
-	cp.fields = fields;
 
-	(void)VSL_IterStat(vd, do_curses_cb, &cp);
-
+	(void)VSL_IterStat(vd, do_curses_cb, NULL);
 }
 
 static void
@@ -135,7 +124,7 @@
 
 void
 do_curses(struct VSL_data *vd, const struct varnish_stats *VSL_stats,
-    int delay, const char *fields)
+    int delay)
 {
 	intmax_t ju;
 	struct timeval tv;
@@ -158,7 +147,7 @@
 		/*
 		 * Initialization goes in outher loop
 		 */
-		prep_pts(vd, fields);
+		prep_pts(vd);
 		AC(erase());
 		AC(refresh());
 

Modified: trunk/varnish-cache/bin/varnishtest/vtc_varnish.c
===================================================================
--- trunk/varnish-cache/bin/varnishtest/vtc_varnish.c	2010-06-05 20:50:01 UTC (rev 4910)
+++ trunk/varnish-cache/bin/varnishtest/vtc_varnish.c	2010-06-05 22:41:54 UTC (rev 4911)
@@ -612,9 +612,9 @@
 	const char *p = sp->target;
 	int i;
 
-	if (strcmp(pt->type, "")) {
-		i = strlen(pt->type);
-		if (memcmp(pt->type, p, i))
+	if (strcmp(pt->class, "")) {
+		i = strlen(pt->class);
+		if (memcmp(pt->class, p, i))
 			return (0);
 		p += i;
 		if (*p != '.')
@@ -630,7 +630,7 @@
 			return (0);
 		p++;
 	}
-	if (strcmp(pt->nm, p))
+	if (strcmp(pt->name, p))
 		return (0);
 
 	assert(!strcmp(pt->fmt, "uint64_t"));

Modified: trunk/varnish-cache/include/varnishapi.h
===================================================================
--- trunk/varnish-cache/include/varnishapi.h	2010-06-05 20:50:01 UTC (rev 4910)
+++ trunk/varnish-cache/include/varnishapi.h	2010-06-05 22:41:54 UTC (rev 4911)
@@ -75,9 +75,9 @@
 	for((var) = vsl_iter0((vd)); (var) != NULL; vsl_itern((vd), &(var)))
 
 struct vsl_statpt {
-	const char *type;	/* stat struct type			*/
+	const char *class;	/* stat struct type			*/
 	const char *ident;	/* stat struct ident			*/
-	const char *nm;		/* field name				*/
+	const char *name;	/* field name				*/
 	const char *fmt;	/* field format ("uint64_t")		*/
 	int flag;		/* 'a' = counter, 'i' = gauge		*/
 	const char *desc;	/* description				*/

Modified: trunk/varnish-cache/lib/libvarnishapi/Makefile.am
===================================================================
--- trunk/varnish-cache/lib/libvarnishapi/Makefile.am	2010-06-05 20:50:01 UTC (rev 4910)
+++ trunk/varnish-cache/lib/libvarnishapi/Makefile.am	2010-06-05 22:41:54 UTC (rev 4911)
@@ -10,6 +10,7 @@
 	vsl.h \
 	\
 	../libvarnish/assert.c \
+	../libvarnish/argv.c \
 	../libvarnish/svn_version.c \
 	../libvarnish/version.c \
 	../libvarnish/vin.c \

Modified: trunk/varnish-cache/lib/libvarnishapi/vsl.c
===================================================================
--- trunk/varnish-cache/lib/libvarnishapi/vsl.c	2010-06-05 20:50:01 UTC (rev 4910)
+++ trunk/varnish-cache/lib/libvarnishapi/vsl.c	2010-06-05 22:41:54 UTC (rev 4911)
@@ -47,6 +47,7 @@
 #include "shmlog.h"
 #include "vre.h"
 #include "vbm.h"
+#include "vqueue.h"
 #include "miniobj.h"
 #include "varnishapi.h"
 
@@ -81,6 +82,8 @@
 	vd->rbuf = malloc(vd->rbuflen);
 	assert(vd->rbuf != NULL);
 
+	VTAILQ_INIT(&vd->sf_list);
+
 	return (vd);
 }
 
@@ -89,6 +92,7 @@
 void
 VSL_Delete(struct VSL_data *vd)
 {
+	struct vsl_sf *sf;
 
 	VSL_Close(vd);
 	vbit_destroy(vd->vbm_client);
@@ -98,6 +102,16 @@
 	free(vd->n_opt);
 	free(vd->rbuf);
 	free(vd->fname);
+
+	while(!VTAILQ_EMPTY(&vd->sf_list)) {
+		sf = VTAILQ_FIRST(&vd->sf_list);	
+		VTAILQ_REMOVE(&vd->sf_list, sf, next);
+		free(sf->class);
+		free(sf->ident);
+		free(sf->name);
+		free(sf);
+	}
+
 	free(vd);
 }
 

Modified: trunk/varnish-cache/lib/libvarnishapi/vsl.h
===================================================================
--- trunk/varnish-cache/lib/libvarnishapi/vsl.h	2010-06-05 20:50:01 UTC (rev 4910)
+++ trunk/varnish-cache/lib/libvarnishapi/vsl.h	2010-06-05 22:41:54 UTC (rev 4911)
@@ -33,6 +33,20 @@
 #define			SLEEP_USEC	(50*1000)
 #define			TIMEOUT_USEC	(5*1000*1000)
 
+struct vsl_sf {
+	unsigned		magic;
+#define VSL_SF_MAGIC		0x558478dd
+	VTAILQ_ENTRY(vsl_sf)	next;
+	int			flags;
+#define VSL_SF_EXCL		(1 << 0)
+#define VSL_SF_CL_WC		(1 << 1)
+#define VSL_SF_ID_WC		(1 << 2)
+#define VSL_SF_NM_WC		(1 << 3)
+	char			*class;
+	char			*ident;
+	char			*name;
+};
+
 struct VSL_data {
 	unsigned		magic;
 #define VSL_MAGIC		0x6e3bd69b
@@ -45,6 +59,13 @@
 	void			*vsl_end;
 	unsigned		alloc_seq;
 
+	/* Stuff relating the stats fields start here */
+
+	int			sf_init;
+	VTAILQ_HEAD(, vsl_sf)	sf_list;
+
+	/* Stuff relating the log records below here */
+
 	unsigned char		*log_start;
 	unsigned char		*log_end;
 	unsigned char		*log_ptr;

Modified: trunk/varnish-cache/lib/libvarnishapi/vsl_arg.c
===================================================================
--- trunk/varnish-cache/lib/libvarnishapi/vsl_arg.c	2010-06-05 20:50:01 UTC (rev 4910)
+++ trunk/varnish-cache/lib/libvarnishapi/vsl_arg.c	2010-06-05 22:41:54 UTC (rev 4911)
@@ -44,9 +44,11 @@
 #include <unistd.h>
 
 #include "vas.h"
+#include "argv.h"
 #include "shmlog.h"
 #include "vre.h"
 #include "vbm.h"
+#include "vqueue.h"
 #include "miniobj.h"
 #include "varnishapi.h"
 
@@ -242,12 +244,93 @@
 
 /*--------------------------------------------------------------------*/
 
+static int
+vsl_sf_arg(struct VSL_data *vd, const char *opt)
+{
+	struct vsl_sf *sf;
+	char **av, *q, *p;
+	int i;
+
+	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
+
+	if (VTAILQ_EMPTY(&vd->sf_list)) {
+		if (*opt == '^')
+			vd->sf_init = 1;
+	}
+
+	av = ParseArgv(opt, ARGV_COMMA);
+	AN(av);
+	if (av[0] != NULL) {
+		fprintf(stderr, "Parse error: %s", av[0]);
+		exit (1);
+	}
+	for (i = 1; av[i] != NULL; i++) {
+		ALLOC_OBJ(sf, VSL_SF_MAGIC);
+		AN(sf);
+		VTAILQ_INSERT_TAIL(&vd->sf_list, sf, next);
+
+		p = av[i];
+		if (*p == '^') {
+			sf->flags |= VSL_SF_EXCL;
+			p++;
+		}
+
+		q = strchr(p, '.');
+		if (q != NULL) {
+			*q++ = '\0';
+			if (*p != '\0')
+				REPLACE(sf->class, p);
+			p = q;
+			if (*p != '\0') {
+				q = strchr(p, '.');
+				if (q != NULL) {
+					*q++ = '\0';
+					if (*p != '\0')
+						REPLACE(sf->ident, p);
+					p = q;
+				}
+			}
+		}
+		if (*p != '\0') {
+			REPLACE(sf->name, p);
+		}
+
+		/* Check for wildcards */
+		if (sf->class != NULL) {
+			q = strchr(sf->class, '*');
+			if (q != NULL && q[1] == '\0') {
+				*q = '\0';
+				sf->flags |= VSL_SF_CL_WC;
+			}
+		}
+		if (sf->ident != NULL) {
+			q = strchr(sf->ident, '*');
+			if (q != NULL && q[1] == '\0') {
+				*q = '\0';
+				sf->flags |= VSL_SF_ID_WC;
+			}
+		}
+		if (sf->name != NULL) {
+			q = strchr(sf->name, '*');
+			if (q != NULL && q[1] == '\0') {
+				*q = '\0';
+				sf->flags |= VSL_SF_NM_WC;
+			}
+		}
+	}
+	FreeArgv(av);
+	return (1);
+}
+
+/*--------------------------------------------------------------------*/
+
 int
 VSL_Stat_Arg(struct VSL_data *vd, int arg, const char *opt)
 {
 
 	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
 	switch (arg) {
+	case 'f': return (vsl_sf_arg(vd, opt));
 	case 'n': return (vsl_n_arg(vd, opt));
 	default:
 		return (0);

Modified: trunk/varnish-cache/lib/libvarnishapi/vsl_log.c
===================================================================
--- trunk/varnish-cache/lib/libvarnishapi/vsl_log.c	2010-06-05 20:50:01 UTC (rev 4910)
+++ trunk/varnish-cache/lib/libvarnishapi/vsl_log.c	2010-06-05 22:41:54 UTC (rev 4911)
@@ -44,6 +44,7 @@
 #include "shmlog.h"
 #include "vre.h"
 #include "vbm.h"
+#include "vqueue.h"
 #include "miniobj.h"
 #include "varnishapi.h"
 

Modified: trunk/varnish-cache/lib/libvarnishapi/vsl_stat.c
===================================================================
--- trunk/varnish-cache/lib/libvarnishapi/vsl_stat.c	2010-06-05 20:50:01 UTC (rev 4910)
+++ trunk/varnish-cache/lib/libvarnishapi/vsl_stat.c	2010-06-05 22:41:54 UTC (rev 4911)
@@ -39,6 +39,7 @@
 #include "vas.h"
 #include "shmlog.h"
 #include "vre.h"
+#include "vqueue.h"
 #include "miniobj.h"
 #include "varnishapi.h"
 
@@ -52,6 +53,7 @@
 	struct shmalloc *sha;
 
 	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
+
 	if (VSL_Open(vd))
 		return (NULL);
 	sha = vsl_find_alloc(vd, VSL_CLASS_STAT, "", "");
@@ -63,22 +65,63 @@
  * -1 -> unknown stats encountered.
  */
 
+static inline int 
+iter_test(const char *s1, const char *s2, int wc)
+{
+
+	if (s1 == NULL)
+		return (0);
+	if (!wc)
+		return (strcmp(s1, s2));
+	for (; *s1 != '\0' && *s1 == *s2; s1++, s2++)
+		continue;
+	return (*s1 != '\0');
+}
+
 static int
-iter_main(struct shmalloc *sha, vsl_stat_f *func, void *priv)
+iter_call(const struct VSL_data *vd, vsl_stat_f *func, void *priv,
+    const struct vsl_statpt *const sp)
 {
+	struct vsl_sf *sf;
+	int good = vd->sf_init;
+
+	if (VTAILQ_EMPTY(&vd->sf_list))
+		return (func(priv, sp));
+
+	VTAILQ_FOREACH(sf, &vd->sf_list, next) {
+		if (iter_test(sf->class, sp->class, sf->flags & VSL_SF_CL_WC))
+			continue;
+		if (iter_test(sf->ident, sp->ident, sf->flags & VSL_SF_ID_WC))
+			continue;
+		if (iter_test(sf->name, sp->name, sf->flags & VSL_SF_NM_WC))
+			continue;
+		if (sf->flags & VSL_SF_EXCL)
+			good = 0;
+		else
+			good = 1;
+	}
+	if (!good)
+		return (0);
+	return (func(priv, sp));
+}
+
+static int
+iter_main(const struct VSL_data *vd, struct shmalloc *sha, vsl_stat_f *func,
+    void *priv)
+{
 	struct varnish_stats *st = SHA_PTR(sha);
 	struct vsl_statpt sp;
 	int i;
 
-	sp.type = "";
+	sp.class = "";
 	sp.ident = "";
 #define MAC_STAT(nn, tt, ll, ff, dd)					\
-	sp.nm = #nn;							\
+	sp.name = #nn;							\
 	sp.fmt = #tt;							\
 	sp.flag = ff;							\
 	sp.desc = dd;							\
 	sp.ptr = &st->nn;						\
-	i = func(priv, &sp);						\
+	i = iter_call(vd, func, priv, &sp);				\
 	if (i)								\
 		return(i);
 #include "stat_field.h"
@@ -87,21 +130,22 @@
 }
 
 static int
-iter_sma(struct shmalloc *sha, vsl_stat_f *func, void *priv)
+iter_sma(const struct VSL_data *vd, struct shmalloc *sha, vsl_stat_f *func,
+    void *priv)
 {
 	struct varnish_stats_sma *st = SHA_PTR(sha);
 	struct vsl_statpt sp;
 	int i;
 
-	sp.type = VSL_TYPE_STAT_SMA;
+	sp.class = VSL_TYPE_STAT_SMA;
 	sp.ident = sha->ident;
 #define MAC_STAT_SMA(nn, tt, ll, ff, dd)				\
-	sp.nm = #nn;							\
+	sp.name = #nn;							\
 	sp.fmt = #tt;							\
 	sp.flag = ff;							\
 	sp.desc = dd;							\
 	sp.ptr = &st->nn;						\
-	i = func(priv, &sp);						\
+	i = iter_call(vd, func, priv, &sp);				\
 	if (i)								\
 		return(i);
 #include "stat_field.h"
@@ -121,9 +165,9 @@
 		if (strcmp(sha->class, VSL_CLASS_STAT))
 			continue;
 		if (!strcmp(sha->type, VSL_TYPE_STAT))
-			i = iter_main(sha, func, priv);
+			i = iter_main(vd, sha, func, priv);
 		else if (!strcmp(sha->type, VSL_TYPE_STAT_SMA))
-			i = iter_sma(sha, func, priv);
+			i = iter_sma(vd, sha, func, priv);
 		else
 			i = -1;
 		if (i != 0)




More information about the varnish-commit mailing list