TL;DR: Origin Response Headers In Fastly Logs
CDNs are great, but they can be a bit of a black box. What if you want to see your CDN traffic broken down by customer? The CDN has that information, but how can we get it out?
Fastly’s CDN hosts our customer’s configuration data so that it is available even if Prefab’s API were to be unavailable. In order to understand our CDN traffic broken down by customer, we set out to use Fastly’s logging product to stream data back to us containing information from our API response but hit a bump in understanding the varnish/Fastly object model.
First Problem: Customer Identification
The default Fastly Log format doesn’t contain a lot of data. To make downstream computation more straightforward, we set out to add a couple of headers to our API’s configuration responses that would identify the API key used to request the configuration. Those are the prefab-key-id and prefab-env-id.
Second Problem: Getting New Headers Back In Fastly Logs
First, I thought it would be as easy as adding something like “prefab_env_key_id”: %{beresp.http.Prefab-EnvId}V"
to the JSON log format to get the new headers shipped our way, but I was confronted with an error message indicating the vcl_log
method didn’t have access to that variable. I asked a question in the Fastly Developers community and got a helpful answer.
Varnish All The Way Down
Fastly is a great user experience wrapped around the Varnish HTTP Cache, which shows in its references to VCL (Varnish Control Language) snippets and callbacks like vcl_fetch, vcl_deliver, and vcl_log. Each of those callbacks (subroutines) has access to different objects, so the trick is to use those subroutines to copy data from the original (origin) response (known as beresp
) in varnish to the cache object resp
so that future invocations of vcl_log have access to that.
In Fastly Configuration, Content → Headers let us do this without writing any VCL.
Now that the header Prefab-EnvId is set on the cached object, we can refer to that using resp.http.Prefab-EnvId
in the JSON logging format like this
"pf_env_id": "%{json.escape(resp.http.Prefab-EnvId)}V"