#include <poll.h>
#include "shmlog.h"
+#include "counter.h"
#include "cli.h"
#include "cli_priv.h"
#include "cli_common.h"
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, "<name> <value>\n");
+ while (c) {
+ cli_out(cli, "%s %d\n", c->name, c->value);
+ c = c->next;
+ }
+}
+
/*--------------------------------------------------------------------*/
static void
{ "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 }
};
#include <stdarg.h>
#include "shmlog.h"
+#include "counter.h"
#include "vrt.h"
#include "vrt_obj.h"
#include "vcl.h"
/*--------------------------------------------------------------------*/
+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)
{
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 */
struct heritage heritage;
volatile struct params *params;
+struct varnish_counters *VSL_counters;
+
/*--------------------------------------------------------------------*/
struct choice {
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);
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 *);
STRING,
IP,
HASH,
- HEADER
+ HEADER,
+ COUNTER
};
enum var_access {
void
vcl_output_lang_h(struct vsb *sb)
{
+ vsb_cat(sb, "#include <stdint.h>\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");
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");
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");
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");
}
puts $fo "void"
puts $fo "vcl_output_lang_h(struct vsb *sb)"
puts $fo "{"
+puts $fo "\tvsb_cat(sb, \"#include <stdint.h>\\n\");"
copy_include ../../include/vcl.h
copy_include ../../include/vrt.h
{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 *"
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 *"
| 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 }
};
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 *
{
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);