[master] bcd9ef1 Implement -I and -X varnishlog options
Martin Blix Grydeland
martin at varnish-cache.org
Thu Jun 13 12:41:24 CEST 2013
commit bcd9ef1e9a961e0d9f2d9d70ef204bf239d60e97
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date: Wed May 29 11:09:06 2013 +0200
Implement -I and -X varnishlog options
diff --git a/bin/varnishlog/varnishlog_options.h b/bin/varnishlog/varnishlog_options.h
index 0eb4821..5c09c58 100644
--- a/bin/varnishlog/varnishlog_options.h
+++ b/bin/varnishlog/varnishlog_options.h
@@ -35,6 +35,7 @@ VSL_OPT_d
VUT_OPT_D
VSL_OPT_g
VSL_OPT_i
+VSL_OPT_I
VSM_OPT_n
VSM_OPT_N
VUT_OPT_P
@@ -43,3 +44,4 @@ VSL_OPT_u
VSL_OPT_v
VSL_OPT_w
VSL_OPT_x
+VSL_OPT_X
diff --git a/doc/sphinx/reference/varnishlog.rst b/doc/sphinx/reference/varnishlog.rst
index d7cc290..6c1fd9d 100644
--- a/doc/sphinx/reference/varnishlog.rst
+++ b/doc/sphinx/reference/varnishlog.rst
@@ -49,14 +49,6 @@ The following options are available:
XXX: Not yet implemented
--I [tag:]regex
-
- Output only records matching this regular expression. If tag
- is given, limit the regex matching to records of that
- tag. Multiple -I options may be given.
-
- XXX: Not yet implemented
-
-k num
Only show the first num log transactions (or log records
@@ -78,15 +70,6 @@ The following options are available:
XXX: Not yet implemented
--X [tag:]regex
-
- Do not output log records matching this regex. If tag is
- given, limit the regex matching to records of that tag.
- Multiple -X options may be given.
-
- XXX: Not yet implemented
-
-
DESCRIPTION
===========
diff --git a/include/vapi/vapi_options.h b/include/vapi/vapi_options.h
index 71ef712..a6f316a 100644
--- a/include/vapi/vapi_options.h
+++ b/include/vapi/vapi_options.h
@@ -43,6 +43,10 @@
/* VSL options */
+#define VSL_iI_PS \
+ "If a tag include option is the first of any tag selection" \
+ " options, all tags are first marked excluded."
+
#define VSL_OPT_a \
VOPT("a", "[-a]", "Append binary file output", \
"When writing binary output to a file, append to it rather" \
@@ -63,10 +67,19 @@
#define VSL_OPT_i \
VOPT("i:", "[-i tag]", "Include tag", \
- "Output only this tag. Multiple -i options may be given." \
+ "Include log records of this tag in output. Multiple -i" \
+ " options may be given.\n" \
+ "\n" \
+ VSL_iI_PS \
+ )
+
+#define VSL_OPT_I \
+ VOPT("I:", "[-I [tag:]regex]", "Include by regex", \
+ "Include by regex matching. Output only records matching" \
+ " tag and regular expression. Applies to any tag if tag" \
+ " is * or empty.\n" \
"\n" \
- "If an -i option is the first of any -ix options, all tags" \
- " are disabled before -ix processing." \
+ VSL_iI_PS \
)
#define VSL_OPT_r \
@@ -97,9 +110,13 @@
#define VSL_OPT_x \
VOPT("x:", "[-x tag]", "Exclude tag", \
- "Exclude log records of this tag. Multiple -x options" \
- " may be given.\n" \
- "\n" \
- "If an -x option is the first of any -ix options, all tags" \
- " are enabled for output before -ix processing." \
+ "Exclude log records of this tag in output. Multiple -x" \
+ " options may be given." \
+ )
+
+#define VSL_OPT_X \
+ VOPT("X:", "[-X [tag:]regex]", "Exclude by regex", \
+ "Exclude by regex matching. Do not output records matching" \
+ " tag and regular expression. Applies to any tag if tag" \
+ " is * or empty." \
)
diff --git a/lib/libvarnishapi/vsl.c b/lib/libvarnishapi/vsl.c
index 28d0e44..f263862 100644
--- a/lib/libvarnishapi/vsl.c
+++ b/lib/libvarnishapi/vsl.c
@@ -94,10 +94,27 @@ VSL_New(void)
vsl->vbm_select = vbit_init(256);
vsl->vbm_supress = vbit_init(256);
+ VTAILQ_INIT(&vsl->vslf_select);
+ VTAILQ_INIT(&vsl->vslf_suppress);
return (vsl);
}
+static void
+vsl_IX_free(vslf_list *list)
+{
+ struct vslf *vslf;
+
+ while (!VTAILQ_EMPTY(list)) {
+ vslf = VTAILQ_FIRST(list);
+ CHECK_OBJ_NOTNULL(vslf, VSLF_MAGIC);
+ VTAILQ_REMOVE(list, vslf, list);
+ AN(vslf->vre);
+ VRE_free(&vslf->vre);
+ AZ(vslf->vre);
+ }
+}
+
void
VSL_Delete(struct VSL_data *vsl)
{
@@ -106,6 +123,8 @@ VSL_Delete(struct VSL_data *vsl)
vbit_destroy(vsl->vbm_select);
vbit_destroy(vsl->vbm_supress);
+ vsl_IX_free(&vsl->vslf_select);
+ vsl_IX_free(&vsl->vslf_suppress);
VSL_ResetError(vsl);
FREE_OBJ(vsl);
}
@@ -134,6 +153,29 @@ VSL_ResetError(struct VSL_data *vsl)
vsl->diag = NULL;
}
+static int
+vsl_match_IX(struct VSL_data *vsl, vslf_list *list, const struct VSL_cursor *c)
+{
+ enum VSL_tag_e tag;
+ const char *cdata;
+ int len;
+ const struct vslf *vslf;
+
+ (void)vsl;
+ tag = VSL_TAG(c->rec.ptr);
+ cdata = VSL_CDATA(c->rec.ptr);
+ len = VSL_LEN(c->rec.ptr);
+
+ VTAILQ_FOREACH(vslf, list, list) {
+ CHECK_OBJ_NOTNULL(vslf, VSLF_MAGIC);
+ if (vslf->tag >= 0 && vslf->tag != tag)
+ continue;
+ if (VRE_exec(vslf->vre, cdata, len, 0, 0, NULL, 0, NULL) >= 0)
+ return (1);
+ }
+ return (0);
+}
+
int
VSL_Match(struct VSL_data *vsl, const struct VSL_cursor *c)
{
@@ -145,8 +187,14 @@ VSL_Match(struct VSL_data *vsl, const struct VSL_cursor *c)
tag = VSL_TAG(c->rec.ptr);
if (tag <= SLT__Bogus || tag >= SLT__Reserved)
return (0);
- if (vbit_test(vsl->vbm_select, tag))
+ if (!VTAILQ_EMPTY(&vsl->vslf_select) &&
+ vsl_match_IX(vsl, &vsl->vslf_select, c))
+ return (1);
+ else if (vbit_test(vsl->vbm_select, tag))
return (1);
+ else if (!VTAILQ_EMPTY(&vsl->vslf_suppress) &&
+ vsl_match_IX(vsl, &vsl->vslf_suppress, c))
+ return (0);
else if (vbit_test(vsl->vbm_supress, tag))
return (0);
@@ -268,7 +316,9 @@ VSL_PrintTransactions(struct VSL_data *vsl, struct VSL_transaction *pt[],
int delim = 0;
int verbose;
- (void)vsl;
+ CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
+ if (fo == NULL)
+ fo = stdout;
if (pt[0] == NULL)
return (0);
diff --git a/lib/libvarnishapi/vsl_api.h b/lib/libvarnishapi/vsl_api.h
index 05987a6..989effd 100644
--- a/lib/libvarnishapi/vsl_api.h
+++ b/lib/libvarnishapi/vsl_api.h
@@ -31,6 +31,7 @@
#include "vdef.h"
#include "vqueue.h"
+#include "vre.h"
#include "vapi/vsm.h"
#define VSL_FILE_ID "VSL"
@@ -67,6 +68,17 @@ struct vslc {
const struct vslc_tbl *tbl;
};
+struct vslf {
+ unsigned magic;
+#define VSLF_MAGIC 0x08650B39
+ VTAILQ_ENTRY(vslf) list;
+
+ int tag;
+ vre_t *vre;
+};
+
+typedef VTAILQ_HEAD(,vslf) vslf_list;
+
struct VSL_data {
unsigned magic;
#undef VSL_MAGIC
@@ -75,12 +87,16 @@ struct VSL_data {
struct vsb *diag;
unsigned flags;
-#define F_SEEN_ix (1 << 0)
+#define F_SEEN_ixIX (1 << 0)
/* Bitmaps of -ix selected tags */
struct vbitmap *vbm_select;
struct vbitmap *vbm_supress;
+ /* Lists of -IX filters */
+ vslf_list vslf_select;
+ vslf_list vslf_suppress;
+
int v_opt;
};
diff --git a/lib/libvarnishapi/vsl_arg.c b/lib/libvarnishapi/vsl_arg.c
index c0c964a..22af6a4 100644
--- a/lib/libvarnishapi/vsl_arg.c
+++ b/lib/libvarnishapi/vsl_arg.c
@@ -120,11 +120,7 @@ vsl_ix_arg(struct VSL_data *vsl, int opt, const char *arg)
const char *b, *e;
CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
- /* If first option is 'i', set all bits for supression */
- if (opt == 'i' && !(vsl->flags & F_SEEN_ix))
- for (i = 0; i < 256; i++)
- vbit_set(vsl->vbm_supress, i);
- vsl->flags |= F_SEEN_ix;
+ vsl->flags |= F_SEEN_ixIX;
for (b = arg; *b; b = e) {
while (isspace(*b))
@@ -156,11 +152,80 @@ vsl_ix_arg(struct VSL_data *vsl, int opt, const char *arg)
return (1);
}
+static int
+vsl_IX_arg(struct VSL_data *vsl, int opt, const char *arg)
+{
+ int i, l, off;
+ const char *b, *e, *err;
+ vre_t *vre;
+ struct vslf *vslf;
+
+ CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
+ vsl->flags |= F_SEEN_ixIX;
+
+ l = 0;
+ b = arg;
+ e = strchr(b, ':');
+ if (e) {
+ while (isspace(*b))
+ b++;
+ l = e - b;
+ while (l > 0 && isspace(b[l - 1]))
+ l--;
+ }
+ if (l > 0 && strncmp(b, "*", l))
+ i = VSL_Name2Tag(b, l);
+ else
+ i = -3;
+ if (i == -2)
+ return (vsl_diag(vsl,
+ "-%c: \"%*.*s\" matches multiple tags\n",
+ (char)opt, l, l, b));
+ else if (i == -1)
+ return (vsl_diag(vsl,
+ "-%c: Could not match \"%*.*s\" to any tag\n",
+ (char)opt, l, l, b));
+ assert(i >= -3);
+
+ if (e)
+ b = e + 1;
+ vre = VRE_compile(b, 0, &err, &off);
+ if (vre == NULL)
+ return (vsl_diag(vsl, "-%c: Regex error at position %d (%s)\n",
+ (char)opt, off, err));
+
+ ALLOC_OBJ(vslf, VSLF_MAGIC);
+ if (vslf == NULL) {
+ VRE_free(&vre);
+ return (vsl_diag(vsl, "Out of memory"));
+ }
+ vslf->tag = i;
+ vslf->vre = vre;
+
+ if (opt == 'I')
+ VTAILQ_INSERT_TAIL(&vsl->vslf_select, vslf, list);
+ else {
+ assert(opt == 'X');
+ VTAILQ_INSERT_TAIL(&vsl->vslf_suppress, vslf, list);
+ }
+
+ return (1);
+}
+
int
VSL_Arg(struct VSL_data *vsl, int opt, const char *arg)
{
+ int i;
+
+ CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
+ /* If first option is 'i', set all bits for supression */
+ if ((opt == 'i' || opt == 'I') && !(vsl->flags & F_SEEN_ixIX))
+ for (i = 0; i < 256; i++)
+ vbit_set(vsl->vbm_supress, i);
+
switch (opt) {
- case 'i': case'x': return (vsl_ix_arg(vsl, opt, arg));
+ case 'i': case 'x': return (vsl_ix_arg(vsl, opt, arg));
+ case 'I': case 'X': return (vsl_IX_arg(vsl, opt, arg));
case 'v': vsl->v_opt = 1; return (1);
default:
return (0);
diff --git a/lib/libvarnishtools/vut.c b/lib/libvarnishtools/vut.c
index 9682c7d..d3e5abd 100644
--- a/lib/libvarnishtools/vut.c
+++ b/lib/libvarnishtools/vut.c
@@ -106,6 +106,8 @@ VUT_g_Arg(const char *arg)
int
VUT_Arg(int opt, const char *arg)
{
+ int i;
+
switch (opt) {
case 'a':
/* Binary file append */
@@ -148,7 +150,10 @@ VUT_Arg(int opt, const char *arg)
return (1);
default:
AN(VUT.vsl);
- return (VSL_Arg(VUT.vsl, opt, arg));
+ i = VSL_Arg(VUT.vsl, opt, arg);
+ if (i < 0)
+ VUT_Error(1, "%s", VSL_Error(VUT.vsl));
+ return (i);
}
}
More information about the varnish-commit
mailing list