Generating Varnish access logs with varnishncsa
Because Varnish sits in front of the web server and caches its output, the access logs of the web server no longer give the full picture of your site’s traffic. Only cache misses and bypassed requests will end up in the log.
To ensure that these logs still get generated in spite of the cache, the varnishncsa
program can be used.
The Varnish Shared Memory Log
The varnishd
process reserves shared memory for logging by creating and mapping files in a tmpfs
memory file system. The files are subsequently mapped by log consumers like varnishlog
, varnishncsa
, and varnishstat
in read-only mode, allowing them to get information and logs from varnishd
without affecting the caching process. These files are collectively know as Varnish Shared Memory (VSM). The part of the VSM responsible for communicating information about the traffic flowing through Varnish is called the Varnish Shared Memory Log (VSL).
tmpfs
volume to get the expected performance.The VSL is a circular buffer with a default size of 80 MB, but the size can be changed through the vsl_space
runtime parameter.
-l
option of varnishd
is shorthand for -p vsl_space=
Because Varnish is positioned on the edge of web content delivery platforms, it receives all the incoming requests. Therefore Varnish is in an excellent position to generate access logs through the VSL mechanism.
The varnishncsa program
The varnishncsa
program is a utility that comes with any Varnish installation. It reads from the varnishd
shared memory logs and presents the output in a NCSA combined log format.
The NCSA combined log format
The NCSA combined log format is the conventional web server log format and contains the following fields:
%h %l %u %t "%r" %s %b "%{Referer}i" "%{User-agent}i"
%h
: the client hostname or IP address%l
: the client identifier or-
if none is set%u
: the username used by the client for authentication or-
if none is set%t
: the date and time of the HTTP request%r
: the first line of the HTTP request%s
: the status code of the HTTP response%b
: the byte size of the HTTP response%{Referer}i
: the URL that linked to the requested page or-
if none is set%{User-agent}i
: the web browser and platform used by the client
Here’s an example of such a log line that was generated by varnishncsa
172.17.0.1 - - [18/May/2022:11:57:56 +0000] "GET / HTTP/1.1" 200 45 "-" "curl"
Even though the NCSA combined log format contains the essential information of a request, you can customize it through the -F
option. There are many formatters in addition to the standard ones, and you can even use VCL logging to further improve the information value from varnishncsa
logs.
If you need more verbose logging that is not in NCSA combined log format, you should take a look at varnishlog
.
The varnishncsa systemd service
When Varnish is installed using the official Linux packages, a varnishncsa.service
systemd service is automatically created.
The contents of this service can be viewed by running the following command:
sudo systemctl cat varnishncsa
This is the output:
[Unit]
Description=Varnish Cache HTTP accelerator NCSA logging daemon
After=varnish.service
[Service]
RuntimeDirectory=varnishncsa
Type=forking
User=varnishlog
Group=varnish
# Beware of custom formats! If you wish to use a different format using the
# -F option for varnishncsa, please note that systemd also uses percent '%'
# expansion in unit files: you need to double the percent signs in your
# format string.
#
# For example the default format would look like this:
#
# -F '%%h %%l %%u %%t "%%r" %%s %%b "%%{Referer}i" "%%{User-agent}i"'
#
# Alternatively you can read the ncsa format from a file using the -f
# option in your varnishncsa command line.
ExecStart=/usr/bin/varnishncsa -a -w /var/log/varnish/varnishncsa.log -D
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
This service runs the following command:
/usr/bin/varnishncsa -a -w /var/log/varnish/varnishncsa.log -D
This command continuously appends the output from varnishncsa
to /var/log/varnish/varnishncsa.log
. This command is daemonized through the -D
option.
Enabling the varnishncsa service
The varnishncsa.service
systemd service is not enabled by default. Because Varnish is so powerful and can handle so many concurrent requests, the sheer number of log lines written to the varnishncsa.log
file can potentially overwhelm the system.
varnishncsa.service
if you know your disk and your system can keep up with the number of log lines that varnishncsa
is writing to the varnishncsa.log
log file.Enabling varnishncsa.service
means starting the service, but also ensuring it automatically gets started after a reboot.
Please run the following commands to enable and start the varnishncsa.service
:
sudo systemctl enable varnishncsa
sudo systemctl start varnishncsa
Any new request that is received by Varnish will now end up in /var/log/varnish/varnishncsa.log
.
Log rotation
The Varnish installation also comes with a logrotate
configuration. This configuration ensures that /var/log/varnish/varnishncsa.log
is rotated daily to ensure that the logs don’t fill the disk.
The logrotate
configuration is located in /etc/logrotate.d/varnish
and looks like this:
/var/log/varnish/varnishncsa.log {
daily
rotate 7
compress
delaycompress
missingok
postrotate
systemctl -q is-active varnishncsa.service || exit 0
systemctl reload varnishncsa.service
endscript
}
Based on this configuration, logrotate
inspects the log on a daily basis, copies it to another file and eventually compresses the output into a gzip file.
Only seven log files are kept on the disk and are rotated on a daily basis.
These are the filenames of the logs:
/var/log/varnishncsa.log
/var/log/varnishncsa.log.1
/var/log/varnishncsa.log.2.gz
/var/log/varnishncsa.log.3.gz
/var/log/varnishncsa.log.4.gz
/var/log/varnishncsa.log.5.gz
/var/log/varnishncsa.log.6.gz
/var/log/varnishncsa.log.7.gz
Rate limiting
If the varnishncsa.service
has too much of an impact on your disk or the performance of your system, you can reduce the output of varnishncsa
by adding rate limiting.
Rate limiting suppresses VSL transactions that exceed the limit. The -R
option allows you to set the limit for a given duration.
Here’s an example where we only log one line every ten seconds:
varnishncsa -R 1/10s
To integrate rate limiting into your varnishncsa.service
, run the following command:
sudo systemctl edit --full varnishncsa
This will open up an editor for the varnishncsa.service
. Please add the -R
option as illustrated below:
[Unit]
Description=Varnish Cache HTTP accelerator NCSA logging daemon
After=varnish.service
[Service]
RuntimeDirectory=varnishncsa
Type=forking
User=varnishlog
Group=varnish
# Beware of custom formats! If you wish to use a different format using the
# -F option for varnishncsa, please note that systemd also uses percent '%'
# expansion in unit files: you need to double the percent signs in your
# format string.
#
# For example the default format would look like this:
#
# -F '%%h %%l %%u %%t "%%r" %%s %%b "%%{Referer}i" "%%{User-agent}i"'
#
# Alternatively you can read the ncsa format from a file using the -f
# option in your varnishncsa command line.
ExecStart=/usr/bin/varnishncsa -a -w /var/log/varnish/varnishncsa.log -D -R 1/10s
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
After saving the file and closing the editor, run the following command to activate these changes:
sudo systemctl restart varnishncsa
Customizing logs
To customize your logs, either alter the format of the log lines or only log certain lines.
To alter the log format will, use the -F
parameter and specify a format using the fields that were mentioned in the varnishncsa log format section.
To only log certain lines, you’re going to issue a VSL query through the -q
parameter. Have a look at the VSL queries section of the varnishlog
tutorial, for more information.
Here are a couple of log customization examples:
Extending the log format with a hit/miss marker
If you want to extend the NCSA combined log format and add a hit/miss marker, simply add the %{Varnish:handling}x
field.
For Varnish versions 7.5 or more recent, you can simply use the following command and log formatting:
varnishncsa -F "%{Varnish:default_format}x %{Varnish:handling}x"
When you use an older version of Varnish, you’ll have to specificy the complete format instead of referring to %{Varnish:default_format}x
, which will look like this:
varnishncsa -F "%h %l %u %t "%r" %s %b \"%{Referer}i\" \"%{User-agent}i\" %{Varnish:handling}x"
Only log errors
To only log for response or backend response status codes above 399, add the below query to your varnishncsa
command:
-q "RespStatus >= 400 or BerespStatus >= 400"
Log problem requests
To log all requests that took more than two seconds to be delivered or with a non-200 response status, add the below query to your varnishncsa
command:
-q "Timestamp:Resp[3] > 2.0 or RespStatus != 200"
Limit logs to a certain domain
To only log requests for a certain domain (e.g., example.com
), add the following query to your varnishncsa
command:
-q "ReqHeader ~ '^Host: .*\.example.com'"
Documentation
Fore more information about the varnishncsa
program and VSL, you can consult the official documentation on varnish-cache.org.