Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
#########################################
### Initialize timing/stats modules
#########################################
### https://github.com/jib/libvmod-statsd
import statsd;
### https://github.com/jib/libvmod-timers
import timers;
### If you do not end with a return() statement, all instances of
### vcl_* will be concatenated.
sub vcl_init {
### Prefix all stats with the ENVIRONMENT, the TYPE OF SERVICE
### and the CLUSTER NAME. Then suffix with the MACHINE NAME.
### Optional, but distinguishes per host/cluster/env/service type.
statsd.prefix( "prod.httpd.apiservices." );
statsd.suffix( ".apiservices001" );
### Connect to statsd
statsd.server( "localhost", "8125" );
### Set the timing units - seconds, milli, micro or nano.
timers.unit( "milliseconds" );
}
######################
### Determine backend
######################
### Backend will have been determined in vcl_recv, but it's
### not available in vcl_deliver. So communicate via header.
### All (non pipe) requests will go through vcl_hit or vcl_miss,
### where we have req.backend in scope. Catch a pass() as well,
### so anything that's not cachable by design gets it's backend
### assigned too.
sub vcl_miss {
set req.http.X-Stats-Backend = req.backend;
}
sub vcl_hit {
set req.http.X-Stats-Backend = req.backend;
}
sub vcl_pass {
set req.http.X-Stats-Backend = req.backend;
}
######################
### Determine status
######################
### obj/beresp.status may be changed elsewhere in the
### VCL to show a different response code to the end
### user - capture it now so we are reporting on the
### actually backend response, not what the user sees
sub vcl_fetch {
set req.http.X-Stats-Status = beresp.status;
}
sub vcl_error {
### An error may have occurred, and we've been sent to vcl_error
### capture the response code that the backend sent if it wasn't
### already
if( !req.http.X-Stats-Status ) {
set req.http.X-Stats-Status = obj.status;
}
}
######################
### Send stats
######################
sub vcl_deliver {
### Hit or Miss?
if( obj.hits == 0 ) {
set req.http.X-Stats-HitMiss = "miss";
} else {
set req.http.X-Stats-HitMiss = "hit";
}
### So, not set in vcl_fetch or vcl_error? Use the response code
### as will be sent to the client then.
if( !req.http.X-Stats-Status ) {
set req.http.X-Stats-Status = resp.status;
}
### Which backend was used?
### You set one explicitly
if( req.http.X-Request-Backend ) {
set req.http.X-Stats-Backend = req.http.X-Request-Backend;
### We discovered it in vcl_hit/miss/pass
} elsif ( req.http.X-Stats-Backend ) {
# No op;
### We didn't discover it. Probably means you hit an error, or
### you synthesized a response. Set it to 'internal'
} else {
set req.http.X-Stats-Backend = "internal";
}
### Key to use for statsd. Something like: config.hit.200
set req.http.X-Stats-Key =
req.http.X-Stats-Backend + "." +
req.http.X-Stats-HitMiss + "." +
req.http.X-Stats-Status;
### Increment the amount of requests here, and how long this
### particular backend took.
statsd.incr( req.http.X-Stats-Key );
statsd.timing( req.http.X-Stats-Key, timers.req_response_time() );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment