July 29, 2015
2 min read time

Libvmod-rtstatus: realtime stats and counters for Varnish

I'm happy to introduce a VMOD that collects metrics and stats from Varnish into a JSON file and presents it through a user interface. If you want to know how Varnish is doing and how your backends are working in real­-time, then this is the VMOD for you. The neat thing is that this VMOD gives you an overview on some Varnish counters with particular attention to backends' metrics and stats per backend. This is great if you're using Varnish as load balancer because it allows you to know what kind of transactions are happening and how Varnish is performing in real­-time. Checking your backends can prevent possible annoying situations and help you to understand how Varnish works.

The VMOD with examples and documentation can be found here: https://github.com/varnish/libvmod-rtstatus

The VMOD has two functions:

  • rtstatus(REAL delta): this is the function responsible for collecting stats from Varnish and generating the JSON object. The param delta is used for hitrate and the request load calculations, they are evaluated on a differential basis.

  • html(): this function is fed with the JSON object generated from the previous one and provide a nice UI.

Let me spend a couple of words on this function. This is c-­wrapper around an HTML/Javascript application, basically this application is presented to Varnish as a big string, that will be used to generate a synthetic object. The UI provided by the VMOD is the default one, but this string is absolutely tunable: the JSON object gives you a lot of raw stats and these can be used to evaluate some other numbers and metrics. This is absolutely up to you. You wish to see the number of KB exchange between Varnish and the backend after every lock operation in your user interface? You can do that it.

In order to use the VMOD you have to write something like this in your VCL:

import rtstatus;

sub vcl_recv {
        if (req.url ~ "/rtstatus.json") {
                return(synth(700, "OK"));
        }
        if (req.url ~ "/rtstatus") {
                return(synth(800, "OK"));
        }
}
sub vcl_synth {
        if (resp.status == 700){
                set resp.status = 200;
                set resp.http.Content-Type = "text/plain; charset=utf-8";
                synthetic(rtstatus.rtstatus(5));
                return (deliver);
        }
        if (resp.status == 800) {
                set resp.status = 200;
                set resp.http.Content-Type = "text/html; charset=utf-8";
                synthetic(rtstatus.html());
                return (deliver);
                }
}