Suppose that you have an nginx server hosts some files, and you want to track how many people has successfully download and how many has fails or cancel. This post will show you how to do that with nginx post_action directive.

Requirement :
Let's see the picture below
Topology
In this LAB, I'll use two servers :
NginxServer# cd /usr/share/nginx/html/
- Host files server running nginx, IP address = 10.254.10.30
- Counting server : host some webservice .php page (running by apache httpd) to count the download session, maybe connect to some database for store the info. IP address = 10.254.10.31
Steps in detail :
Create some test file on the NginxServer.
NginxServer# cd /usr/share/nginx/html/
NginxServer# dd if=/dev/zero of=file.bin bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 0.113983 seconds, 920 MB/s
On the client, try download the file.
Client# wget http://10.254.10.30/file.bin
http://10.254.10.30/file.bin
Checking the logfile on the NginxServer
NginxServer# tail /var/log/nginx/access.log
Let's add some configuration in the NginxServer :
NginXServer# vim /etc/nginx/nginx.conf
location /
Client# wget http://10.254.10.30/file.bin
http://10.254.10.30/file.bin
Connecting to 10.254.10.30:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: `file.bin'
100%[==========================================================>]
104,857,600 54.4M/s in 1.8s
09:35:34 (54.4 MB/s) - `file.bin' saved [104857600/104857600]
Checking the logfile on the NginxServerNginxServer# tail /var/log/nginx/access.log
10.254.10.29 - - [21/Jun/2012:09:35:31 +0700] "GET /file.bin HTTP/1.1" 200 104857600 "-" "Wget/1.13.4 (linux-gnu)" "-"
Yes, you can see the logfile that client has downloaded the file, but you can not know whether the client successfully or fail or cancel the download because in the logfile there is no entry for that infomation.Let's add some configuration in the NginxServer :
location /
{
root /usr/share/nginx/html;
index index.html index.htm;
post_action /afterdownload;
}
location /afterdownload
{
proxy_pass http://10.254.10.31/counting.php?FileName=$request&ClientIP=$remote_addr&body_bytes_sent=$body_bytes_sent&status=$request_completion;
internal;
}
Yes, after finishing a download session (no matter what if successful | fails | user cancel), the nginx server will make a proxy call to some external URL (in this case, i've point it to the CountingServer).
Let's download the file again.
Client# wget http://10.254.10.30/file.bin
http://10.254.10.30/file.bin
Connecting to 10.254.10.30:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: `file.bin'
100%[=========================================================>]
104,857,600 52.4M/s in 1.9s
10:14:08 (52.4 MB/s) - `file.bin' saved [104857600/104857600]
Check the CountingServer log.CountingServer# tail /var/log/httpd/access.log
10.254.10.30 - - [21/Jun/2012:10:14:06 +0700] "GET /counting.php?FileName=GET /file.bin HTTP/1.1&ClientIP=10.254.10.29&body_bytes_sent=104857600&status=OK HTTP/1.0" 200 10 "-" "Wget/1.13.4 (linux-gnu)"
Yeah. The access log is very clearly. The file has been successfully downloaded (status=OK).Let's download the file again, and cancel it when processing (by pressing Ctrl+c)
Client# wget http://10.254.10.30/file.bin
http://10.254.10.30/file.bin
Connecting to 10.254.10.30:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: `file.bin'
63% [=========================================> ] 66,981,354 53.2M/s
Check the log of the CountingServer.CountingServer# tail /var/log/httpd/access.log
10.254.10.30 - - [21/Jun/2012:10:13:39 +0700] "GET /counting.php?FileName=GET /file.bin HTTP/1.1&ClientIP=10.254.10.29&body_bytes_sent=75427840&status= HTTP/1.0" 200 10 "-" "Wget/1.13.4 (linux-gnu)"
The entry "status= " has been blanked instead of "OK". That mean the progress was terminated when going on (maybe user cancel)So, by using nginx post_action directive, you can now trigger an action after client finish downloading.
very nice info Thanks!
ReplyDelete/dara
Hello
ReplyDeleteIn the download log I see 502 error from the proxy, any idea why that could happen?
It looks like the server can not reach the backend. You can try use IPaddress instead of DNS name. More detail about 502 code : http://www.checkupdown.com/status/E502.html
Deleteok, all clear I get the calls now.
DeleteDO you have any idea how to escape the call parameters in nxing so that I get them in php on counter server?
Right now everything is lost after first SPACE (GET_)
In my script I only see 'FileName' => 'GET', nothing else
yes, I figured that mean time, but now the log for download is saying 302 with no sign of call on the counter server
ReplyDeletecorrection, the status is HTTP/1.1" 301
ReplyDelete