From 52837b97d8e69ddea9523b650af636b5c5ec0ca4 Mon Sep 17 00:00:00 2001 From: Tollef Fog Heen Date: Sun, 16 Nov 2008 17:07:01 +0100 Subject: [PATCH] First, rough implementation of dynamic counters --- varnish-cache/bin/varnishd/cache_cli.c | 17 ++++++ varnish-cache/bin/varnishd/cache_vrt.c | 46 ++++++++++++++++ varnish-cache/bin/varnishd/common.h | 2 + varnish-cache/bin/varnishd/varnishd.c | 2 + varnish-cache/include/vrt.h | 4 ++ varnish-cache/include/vrt_obj.h | 2 + varnish-cache/lib/libvcl/vcc_compile.h | 3 +- varnish-cache/lib/libvcl/vcc_fixed_token.c | 40 ++++++++------ .../lib/libvcl/vcc_gen_fixed_token.tcl | 1 + varnish-cache/lib/libvcl/vcc_gen_obj.tcl | 7 ++- varnish-cache/lib/libvcl/vcc_obj.c | 7 +++ varnish-cache/lib/libvcl/vcc_var.c | 52 +++++++++++++++++-- 12 files changed, 160 insertions(+), 23 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache_cli.c b/varnish-cache/bin/varnishd/cache_cli.c index 2a948165..724e3793 100644 --- a/varnish-cache/bin/varnishd/cache_cli.c +++ b/varnish-cache/bin/varnishd/cache_cli.c @@ -46,6 +46,7 @@ #include #include "shmlog.h" +#include "counter.h" #include "cli.h" #include "cli_priv.h" #include "cli_common.h" @@ -198,6 +199,19 @@ cli_debug_sizeof(struct cli *cli, const char * const *av, void *priv) SZOF(struct varnish_stats); } +static void +cli_debug_counters(struct cli *cli, const char * const *av, void *priv) +{ + (void)av; + (void)priv; + struct varnish_counters *c = VSL_counters; + cli_out(cli, " \n"); + while (c) { + cli_out(cli, "%s %d\n", c->name, c->value); + c = c->next; + } +} + /*--------------------------------------------------------------------*/ static void @@ -231,6 +245,9 @@ static struct cli_proto debug_cmds[] = { { "debug.sizeof", "debug.sizeof", "\tDump sizeof various data structures\n", 0, 0, cli_debug_sizeof }, + { "debug.counters", "debug.counters", + "\tDump counters\n", + 0, 0, cli_debug_counters }, { NULL } }; diff --git a/varnish-cache/bin/varnishd/cache_vrt.c b/varnish-cache/bin/varnishd/cache_vrt.c index f9db47ae..979264e2 100644 --- a/varnish-cache/bin/varnishd/cache_vrt.c +++ b/varnish-cache/bin/varnishd/cache_vrt.c @@ -46,6 +46,7 @@ #include #include "shmlog.h" +#include "counter.h" #include "vrt.h" #include "vrt_obj.h" #include "vcl.h" @@ -343,6 +344,51 @@ VRT_r_bereq_between_bytes_timeout(struct sess *sp) /*--------------------------------------------------------------------*/ +static MTX counter_mtx; + +struct varnish_counters* +VRT_FindCounter(const struct sess *sp, const char *name) +{ + struct varnish_counters *c = VSL_counters; + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + while (c) { + if (strcmp(name, c->name) == 0) + return c; + c = c->next; + } + /* Not found, create a new one. */ + c = malloc(sizeof (struct varnish_counters)); + c->name = strdup(name); + c->value = 0; + + AZ(pthread_mutex_lock(&counter_mtx)); + c->next = VSL_counters; + VSL_counters = c; + AZ(pthread_mutex_unlock(&counter_mtx)); + return c; +} + +uint64_t +VRT_GetCounter(const struct sess *sp, const char *name) +{ + struct varnish_counters *c; + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + c = VRT_FindCounter(sp, name); + return c->value; +} + +void +VRT_SetCounter(const struct sess *sp, const char *name, uint64_t value) +{ + struct varnish_counters *c; + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + c = VRT_FindCounter(sp, name); + c->value = value; +} + +/*--------------------------------------------------------------------*/ + void VRT_handling(struct sess *sp, unsigned hand) { diff --git a/varnish-cache/bin/varnishd/common.h b/varnish-cache/bin/varnishd/common.h index 82913efd..48f2885f 100644 --- a/varnish-cache/bin/varnishd/common.h +++ b/varnish-cache/bin/varnishd/common.h @@ -42,6 +42,8 @@ void VSL_Panic(int *len, char **ptr); void VSL_MgtInit(const char *fn, unsigned size); extern struct varnish_stats *VSL_stats; +extern struct varnish_counters *VSL_counters; + #define TRUST_ME(ptr) ((void*)(uintptr_t)(ptr)) /* Really belongs in mgt.h, but storage_file chokes on both */ diff --git a/varnish-cache/bin/varnishd/varnishd.c b/varnish-cache/bin/varnishd/varnishd.c index c3dd3314..fa087e0c 100644 --- a/varnish-cache/bin/varnishd/varnishd.c +++ b/varnish-cache/bin/varnishd/varnishd.c @@ -79,6 +79,8 @@ struct heritage heritage; volatile struct params *params; +struct varnish_counters *VSL_counters; + /*--------------------------------------------------------------------*/ struct choice { diff --git a/varnish-cache/include/vrt.h b/varnish-cache/include/vrt.h index 5a0f60dc..c41aaadd 100644 --- a/varnish-cache/include/vrt.h +++ b/varnish-cache/include/vrt.h @@ -185,3 +185,7 @@ const char *VRT_backend_string(struct sess *sp); VRT_handling(sp, hand); \ return (1); \ } while (0) + +uint64_t VRT_GetCounter(const struct sess *, const char *name); +void VRT_SetCounter(const struct sess *, const char *, uint64_t value); +struct varnish_counters *VRT_FindCounter(const struct sess *sp, const char *name); diff --git a/varnish-cache/include/vrt_obj.h b/varnish-cache/include/vrt_obj.h index 44c17380..7bc0387e 100644 --- a/varnish-cache/include/vrt_obj.h +++ b/varnish-cache/include/vrt_obj.h @@ -59,3 +59,5 @@ const char * VRT_r_resp_response(const struct sess *); void VRT_l_resp_response(const struct sess *, const char *, ...); double VRT_r_now(const struct sess *); unsigned VRT_r_req_backend_healthy(const struct sess *); +struct counter * VRT_r_counter_(const struct sess *); +void VRT_l_counter_(const struct sess *, struct counter *); diff --git a/varnish-cache/lib/libvcl/vcc_compile.h b/varnish-cache/lib/libvcl/vcc_compile.h index 41db3715..84d032c9 100644 --- a/varnish-cache/lib/libvcl/vcc_compile.h +++ b/varnish-cache/lib/libvcl/vcc_compile.h @@ -106,7 +106,8 @@ enum var_type { STRING, IP, HASH, - HEADER + HEADER, + COUNTER }; enum var_access { diff --git a/varnish-cache/lib/libvcl/vcc_fixed_token.c b/varnish-cache/lib/libvcl/vcc_fixed_token.c index bb6df1d8..39a2f35f 100644 --- a/varnish-cache/lib/libvcl/vcc_fixed_token.c +++ b/varnish-cache/lib/libvcl/vcc_fixed_token.c @@ -156,13 +156,13 @@ const char * const vcl_tnames[256] = { void vcl_output_lang_h(struct vsb *sb) { + vsb_cat(sb, "#include \n"); /* ../../include/vcl.h */ - vsb_cat(sb, "/*\n * $Id: vcc_gen_fixed_token.tcl 3534 2009-01-19 13"); - vsb_cat(sb, ":46:31Z phk $\n *\n * NB: This file is machine genera"); - vsb_cat(sb, "ted, DO NOT EDIT!\n *\n * Edit and run vcc_gen_fixed_t"); - vsb_cat(sb, "oken.tcl instead\n */\n\nstruct sess;\n"); + vsb_cat(sb, "/*\n * $Id$\n *\n * NB: This file is machine generate"); + vsb_cat(sb, "d, DO NOT EDIT!\n *\n * Edit and run vcc_gen_fixed_tok"); + vsb_cat(sb, "en.tcl instead\n */\n\nstruct sess;\n"); vsb_cat(sb, "struct cli;\n\ntypedef void vcl_init_f(struct cli *);\n"); vsb_cat(sb, "typedef void vcl_fini_f(struct cli *);\n"); vsb_cat(sb, "typedef int vcl_func_f(struct sess *sp);\n"); @@ -235,15 +235,15 @@ vcl_output_lang_h(struct vsb *sb) vsb_cat(sb, " * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWI"); vsb_cat(sb, "SE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFT"); vsb_cat(sb, "WARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n"); - vsb_cat(sb, " * SUCH DAMAGE.\n *\n * $Id: vrt.h 3541 2009-01-23 21:"); - vsb_cat(sb, "17:02Z phk $\n *\n * Runtime support for compiled VCL "); - vsb_cat(sb, "programs.\n *\n * XXX: When this file is changed, lib/"); - vsb_cat(sb, "libvcl/vcc_gen_fixed_token.tcl\n"); - vsb_cat(sb, " * XXX: *MUST* be rerun.\n */\n"); - vsb_cat(sb, "\nstruct sess;\nstruct vsb;\nstruct cli;\n"); - vsb_cat(sb, "struct director;\nstruct VCL_conf;\n"); - vsb_cat(sb, "struct sockaddr;\n\n/*\n * A backend probe specificati"); - vsb_cat(sb, "on\n */\n\nextern void *vrt_magic_string_end;\n"); + vsb_cat(sb, " * SUCH DAMAGE.\n *\n * $Id$\n *\n"); + vsb_cat(sb, " * Runtime support for compiled VCL programs.\n"); + vsb_cat(sb, " *\n * XXX: When this file is changed, lib/libvcl/vcc_"); + vsb_cat(sb, "gen_fixed_token.tcl\n * XXX: *MUST* be rerun.\n"); + vsb_cat(sb, " */\n\nstruct sess;\nstruct vsb;\n"); + vsb_cat(sb, "struct cli;\nstruct director;\n"); + vsb_cat(sb, "struct VCL_conf;\nstruct sockaddr;\n"); + vsb_cat(sb, "\n/*\n * A backend probe specification\n"); + vsb_cat(sb, " */\n\nextern void *vrt_magic_string_end;\n"); vsb_cat(sb, "\nstruct vrt_backend_probe {\n\tconst char\t*url;\n"); vsb_cat(sb, "\tconst char\t*request;\n\tdouble\t\ttimeout;\n"); vsb_cat(sb, "\tdouble\t\tinterval;\n\tunsigned\twindow;\n"); @@ -321,12 +321,16 @@ vcl_output_lang_h(struct vsb *sb) vsb_cat(sb, "uct sess *sp);\n\n#define VRT_done(sp, hand)\t\t\t\\\n"); vsb_cat(sb, "\tdo {\t\t\t\t\t\\\n\t\tVRT_handling(sp, hand);\t\t\\\n"); vsb_cat(sb, "\t\treturn (1);\t\t\t\\\n\t} while (0)\n"); + vsb_cat(sb, "\nuint64_t VRT_GetCounter(const struct sess *, const c"); + vsb_cat(sb, "har *name);\nvoid VRT_SetCounter(const struct sess *, "); + vsb_cat(sb, "const char *, uint64_t value);\n"); + vsb_cat(sb, "struct varnish_counters *VRT_FindCounter(const struct "); + vsb_cat(sb, "sess *sp, const char *name);\n"); /* ../../include/vrt_obj.h */ - vsb_cat(sb, "/*\n * $Id: vrt_obj.h 3406 2008-11-19 14:13:57Z petter"); - vsb_cat(sb, " $\n *\n * NB: This file is machine generated, DO NOT"); - vsb_cat(sb, " EDIT!\n *\n * Edit vcc_gen_obj.tcl instead\n"); + vsb_cat(sb, "/*\n * $Id$\n *\n * NB: This file is machine generate"); + vsb_cat(sb, "d, DO NOT EDIT!\n *\n * Edit vcc_gen_obj.tcl instead\n"); vsb_cat(sb, " */\n\nstruct sockaddr * VRT_r_client_ip(const struct "); vsb_cat(sb, "sess *);\nstruct sockaddr * VRT_r_server_ip(struct ses"); vsb_cat(sb, "s *);\nint VRT_r_server_port(struct sess *);\n"); @@ -382,5 +386,7 @@ vcl_output_lang_h(struct vsb *sb) vsb_cat(sb, "\nvoid VRT_l_resp_response(const struct sess *, const "); vsb_cat(sb, "char *, ...);\ndouble VRT_r_now(const struct sess *);\n"); vsb_cat(sb, "unsigned VRT_r_req_backend_healthy(const struct sess *"); - vsb_cat(sb, ");\n"); + vsb_cat(sb, ");\nstruct counter * VRT_r_counter_(const struct sess "); + vsb_cat(sb, "*);\nvoid VRT_l_counter_(const struct sess *, struct c"); + vsb_cat(sb, "ounter *);\n"); } diff --git a/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl b/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl index 648a8257..edd328ec 100755 --- a/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl +++ b/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl @@ -399,6 +399,7 @@ puts $fo "" puts $fo "void" puts $fo "vcl_output_lang_h(struct vsb *sb)" puts $fo "{" +puts $fo "\tvsb_cat(sb, \"#include \\n\");" copy_include ../../include/vcl.h copy_include ../../include/vrt.h diff --git a/varnish-cache/lib/libvcl/vcc_gen_obj.tcl b/varnish-cache/lib/libvcl/vcc_gen_obj.tcl index 405ca02b..286b324c 100755 --- a/varnish-cache/lib/libvcl/vcc_gen_obj.tcl +++ b/varnish-cache/lib/libvcl/vcc_gen_obj.tcl @@ -235,7 +235,11 @@ set spobj { {recv pipe pass hash miss hit fetch deliver discard timeout} "const struct sess *" } - + { counter. + RW COUNTER + {recv pipe pass hash miss hit fetch deliver discard timeout} + "const struct sess *" + } } set tt(IP) "struct sockaddr *" @@ -249,6 +253,7 @@ set tt(HDR_RESP) "const char *" set tt(HDR_OBJ) "const char *" set tt(HDR_REQ) "const char *" set tt(HDR_BEREQ) "const char *" +set tt(COUNTER) "struct counter *" set tt(HOSTNAME) "const char *" set tt(PORTNAME) "const char *" set tt(HASH) "const char *" diff --git a/varnish-cache/lib/libvcl/vcc_obj.c b/varnish-cache/lib/libvcl/vcc_obj.c index a7f98211..a04d1ce9 100644 --- a/varnish-cache/lib/libvcl/vcc_obj.c +++ b/varnish-cache/lib/libvcl/vcc_obj.c @@ -217,5 +217,12 @@ struct var vcc_vars[] = { | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER | VCL_MET_DISCARD | VCL_MET_TIMEOUT }, + { "counter.", COUNTER, 8, + "VRT_r_counter_(sp)", "VRT_l_counter_(sp, ", + V_RW, 0, + VCL_MET_RECV | VCL_MET_PIPE | VCL_MET_PASS | VCL_MET_HASH + | VCL_MET_MISS | VCL_MET_HIT | VCL_MET_FETCH | VCL_MET_DELIVER + | VCL_MET_DISCARD | VCL_MET_TIMEOUT + }, { NULL } }; diff --git a/varnish-cache/lib/libvcl/vcc_var.c b/varnish-cache/lib/libvcl/vcc_var.c index 66a4f211..40e84f68 100644 --- a/varnish-cache/lib/libvcl/vcc_var.c +++ b/varnish-cache/lib/libvcl/vcc_var.c @@ -76,6 +76,39 @@ HeaderVar(struct tokenlist *tl, const struct token *t, const struct var *vh) return (v); } +static struct var * +CounterVar(struct tokenlist *tl, const struct token *t, const struct var *vh) +{ + char *p; + struct var *v; + int i; + + (void)tl; + + v = TlAlloc(tl, sizeof *v); + assert(v != NULL); + i = t->e - t->b; + p = TlAlloc(tl, i + 1); + assert(p != NULL); + memcpy(p, t->b, i); + p[i] = '\0'; + v->name = p; + v->access = V_RW; + v->fmt = INT; + v->hdr = vh->hdr; + v->methods = vh->methods; + asprintf(&p, "VRT_GetCounter(sp, \"%s\")", v->name+vh->len); + AN(p); + TlFree(tl, p); + v->rname = p; + asprintf(&p, "VRT_SetCounter(sp, \"%s\", ", v->name+vh->len); + + AN(p); + TlFree(tl, p); + v->lname = p; + return (v); +} + /*--------------------------------------------------------------------*/ struct var * @@ -83,17 +116,28 @@ vcc_FindVar(struct tokenlist *tl, const struct token *t, struct var *vl) { struct var *v; + printf("%d\n", t->tok); for (v = vl; v->name != NULL; v++) { - if (v->fmt == HEADER && (t->e - t->b) <= v->len) + printf("%s %d (%d %d)\n", v->name, v->fmt, t->e - t->b, v->len); + if ((v->fmt == HEADER || + v->fmt == COUNTER) && (t->e - t->b) <= v->len) continue; - if (v->fmt != HEADER && t->e - t->b != v->len) + if ((v->fmt != HEADER && + v->fmt != COUNTER) && (t->e - t->b) != v->len) continue; if (memcmp(t->b, v->name, v->len)) continue; vcc_AddUses(tl, v); - if (v->fmt != HEADER) + switch (v->fmt) { + case HEADER: + return (HeaderVar(tl, t, v)); + break; + case COUNTER: + return (CounterVar(tl, t, v)); + break; + default: return (v); - return (HeaderVar(tl, t, v)); + } } vsb_printf(tl->sb, "Unknown variable "); vcc_ErrToken(tl, t); -- 2.39.5