Mailing List Archive

r2946 - trunk/varnish-cache/bin/varnishstat
Author: petter
Date: 2008-07-17 11:58:54 +0200 (Thu, 17 Jul 2008)
New Revision: 2946

Modified:
trunk/varnish-cache/bin/varnishstat/varnishstat.1
trunk/varnish-cache/bin/varnishstat/varnishstat.c
Log:
Added support for choosing what fields to show in varniststat. This is done by using the new -f option. To list avaialble fields, use the new -l option. Fixes #208.


Modified: trunk/varnish-cache/bin/varnishstat/varnishstat.1
===================================================================
--- trunk/varnish-cache/bin/varnishstat/varnishstat.1 2008-07-14 15:53:22 UTC (rev 2945)
+++ trunk/varnish-cache/bin/varnishstat/varnishstat.1 2008-07-17 09:58:54 UTC (rev 2946)
@@ -37,6 +37,8 @@
.Sh SYNOPSIS
.Nm
.Op Fl 1
+.Op Fl f Ar field_list
+.Op Fl l
.Op Fl n Ar varnish_name
.Op Fl V
.Op Fl w Ar delay
@@ -52,6 +54,13 @@
.It Fl 1
Instead of presenting of a continuously updated display, print the
statistics once and exit.
+.It Fl f
+A comma separated list of the fields to display.
+If it starts with '^' it is used as an exclusion list.
+.It Fl l
+Lists the available fields to use with the
+.Fl f
+option.
.It Fl n
Specifies the name of the
.Nm varnishd

Modified: trunk/varnish-cache/bin/varnishstat/varnishstat.c
===================================================================
--- trunk/varnish-cache/bin/varnishstat/varnishstat.c 2008-07-14 15:53:22 UTC (rev 2945)
+++ trunk/varnish-cache/bin/varnishstat/varnishstat.c 2008-07-17 09:58:54 UTC (rev 2946)
@@ -50,6 +50,8 @@
#include "shmlog.h"
#include "varnishapi.h"

+#define FIELD_EXCLUSION_CHARACTER '^'
+
static void
myexp(double *acc, double val, unsigned *n, unsigned nmax)
{
@@ -59,8 +61,37 @@
(*acc) += (val - *acc) / (double)*n;
}

+static int
+show_field(const char* field, const char *fields)
+{
+ char* field_start;
+ 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);
+}
+
static void
-do_curses(struct varnish_stats *VSL_stats, int delay)
+do_curses(struct varnish_stats *VSL_stats, int delay, const char *fields)
{
struct varnish_stats copy;
intmax_t ju;
@@ -112,7 +143,7 @@

line = 3;
#define MAC_STAT(n, t, f, d) \
- if (++line < LINES) { \
+ if ((fields == NULL || show_field( #n, fields )) && ++line < LINES) { \
ju = VSL_stats->n; \
if (f == 'a') { \
mvprintw(line, 0, "%12ju %12.2f %12.2f %s\n", \
@@ -172,7 +203,7 @@
}

static void
-do_once(struct varnish_stats *VSL_stats)
+do_once(struct varnish_stats *VSL_stats, const char* fields)
{
struct timeval tv;
double up;
@@ -182,6 +213,7 @@

#define MAC_STAT(n, t, f, d) \
do { \
+ if (fields != NULL && ! show_field( #n, fields )) break; \
intmax_t ju = VSL_stats->n; \
if (f == 'a') \
printf("%-16s %12ju %12.2f %s\n", #n, ju, ju / up, d); \
@@ -195,10 +227,77 @@
static void
usage(void)
{
- fprintf(stderr, "usage: varnishstat [-1V] [-n varnish_name] [-w delay]\n");
+#define FMT " %-28s # %s\n"
+ fprintf(stderr, "usage: varnishstat [-1lV] [-f field_list] [-n varnish_name] [-w delay]\n");
+ fprintf(stderr, FMT, "-1", "Print the statistics once and exit");
+ fprintf(stderr, FMT, "-f field_list", "Comma separated list of fields to display. ");
+ fprintf(stderr, FMT, "", "If it starts with '^' it is used as an exclusion list");
+ fprintf(stderr, FMT, "-l", "Lists the available fields to use with the -f option");
+ fprintf(stderr, FMT, "-n varnish_name", "The varnishd instance to get logs from");
+ fprintf(stderr, FMT, "-V", "Display the version number and exit");
+ fprintf(stderr, FMT, "-w delay", "Wait delay seconds between updates. The default is 1.");
+#undef FMT
exit(1);
}

+static void
+list_fields(void)
+{
+ fprintf(stderr, "Available fields to use with the varnishstat -f option:\n");
+ fprintf(stderr, "Field name Description\n");
+ fprintf(stderr, "---------- -----------\n");
+#define MAC_STAT(n, t, 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, 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) {
+ fputs("The field '", stderr);
+ fwrite(field_start, 1, field_length, stderr);
+ 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 **argv)
{
@@ -206,12 +305,19 @@
struct varnish_stats *VSL_stats;
int delay = 1, once = 0;
const char *n_arg = NULL;
+ const char *fields = NULL;

- while ((c = getopt(argc, argv, "1n:Vw:")) != -1) {
+ while ((c = getopt(argc, argv, "1f:ln:Vw:")) != -1) {
switch (c) {
case '1':
once = 1;
break;
+ case 'f':
+ fields = optarg;
+ break;
+ case 'l':
+ list_fields();
+ exit(0);
case 'n':
n_arg = optarg;
break;
@@ -228,11 +334,16 @@

if ((VSL_stats = VSL_OpenStats(n_arg)) == NULL)
exit(1);
+
+ if (fields != NULL && !valid_fields(fields)) {
+ usage();
+ exit(1);
+ }

if (once)
- do_once(VSL_stats);
+ do_once(VSL_stats, fields);
else
- do_curses(VSL_stats, delay);
+ do_curses(VSL_stats, delay, fields);

exit(0);
}