Sometimes, we prefer to view statistics in graphical form rather than numerical values, which is not too attractive to be displayed. Nginx supports stub_status directive module, which we can use to print:
- Active connections
- Server accepts handled requests
- Reading
- Writing
- Waiting
For example:
Active connections: 6 server accepts handled requests 15561 15561 26602 Reading: 4 Writing: 2 Waiting: 0
However, This module is not compiled by default and must be specified using this argument when compiling nginx.
--with-http_stub_status_module
First, to get statistics like the above example, you should modify nginx config file and add location directive this
server { .... .... location /nginx_status { stub_status on; access_log off; allow 1.2.3.4; allow 5.6.7.8; deny all; } }
perl scripts used to generate statistical images can be downloaded here:
http://kovyrin.net/files/mrtg/rrd_nginx.pl.txt
Rename rrd_nginx.pl.txt to rrd_nginx.pl and make it executable
Or you can simply copy and paste from here
#!/usr/bin/perl use RRDs; use LWP::UserAgent; # define location of rrdtool databases my $rrd = '/opt/rrd'; # define location of images my $img = '/var/www/html/rrd'; # define your nginx stats URL my $URL = "http://www.example.com/nginx_status"; my $ua = LWP::UserAgent->new(timeout => 30); my $response = $ua->request(HTTP::Request->new('GET', $URL)); my $requests = 0; my $total = 0; my $reading = 0; my $writing = 0; my $waiting = 0; foreach (split(/\n/, $response->content)) { $total = $1 if (/^Active connections:\s+(\d+)/); if (/^Reading:\s+(\d+).*Writing:\s+(\d+).*Waiting:\s+(\d+)/) { $reading = $1; $writing = $2; $waiting = $3; } $requests = $3 if (/^\s+(\d+)\s+(\d+)\s+(\d+)/); } #print "RQ:$requests; TT:$total; RD:$reading; WR:$writing; WA:$waiting\n"; # if rrdtool database doesn't exist, create it if (! -e "$rrd/nginx.rrd") { RRDs::create "$rrd/nginx.rrd", "-s 60", "DS:requests:COUNTER:120:0:100000000", "DS:total:ABSOLUTE:120:0:60000", "DS:reading:ABSOLUTE:120:0:60000", "DS:writing:ABSOLUTE:120:0:60000", "DS:waiting:ABSOLUTE:120:0:60000", "RRA:AVERAGE:0.5:1:2880", "RRA:AVERAGE:0.5:30:672", "RRA:AVERAGE:0.5:120:732", "RRA:AVERAGE:0.5:720:1460"; } # insert values into rrd database RRDs::update "$rrd/nginx.rrd", "-t", "requests:total:reading:writing:waiting", "N:$requests:$total:$reading:$writing:$waiting"; # Generate graphs CreateGraphs("day"); CreateGraphs("week"); CreateGraphs("month"); CreateGraphs("year"); #------------------------------------------------------------------------------ sub CreateGraphs($){ my $period = shift; RRDs::graph "$img/requests-$period.png", "-s -1$period", "-t Requests on nginx", "--lazy", "-h", "150", "-w", "700", "-l 0", "-a", "PNG", "-v requests/sec", "DEF:requests=$rrd/nginx.rrd:requests:AVERAGE", "LINE2:requests#336600:Requests", "GPRINT:requests:MAX: Max\\: %5.1lf %S", "GPRINT:requests:AVERAGE: Avg\\: %5.1lf %S", "GPRINT:requests:LAST: Current\\: %5.1lf %Sreq/sec", "HRULE:0#000000"; if ($ERROR = RRDs::error) { print "$0: unable to generate $period graph: $ERROR\n"; } RRDs::graph "$img/connections-$period.png", "-s -1$period", "-t Requests on nginx", "--lazy", "-h", "150", "-w", "700", "-l 0", "-a", "PNG", "-v requests/sec", "DEF:total=$rrd/nginx.rrd:total:AVERAGE", "DEF:reading=$rrd/nginx.rrd:reading:AVERAGE", "DEF:writing=$rrd/nginx.rrd:writing:AVERAGE", "DEF:waiting=$rrd/nginx.rrd:waiting:AVERAGE", "LINE2:total#22FF22:Total", "GPRINT:total:LAST: Current\\: %5.1lf %S", "GPRINT:total:MIN: Min\\: %5.1lf %S", "GPRINT:total:AVERAGE: Avg\\: %5.1lf %S", "GPRINT:total:MAX: Max\\: %5.1lf %S\\n", "LINE2:reading#0022FF:Reading", "GPRINT:reading:LAST: Current\\: %5.1lf %S", "GPRINT:reading:MIN: Min\\: %5.1lf %S", "GPRINT:reading:AVERAGE: Avg\\: %5.1lf %S", "GPRINT:reading:MAX: Max\\: %5.1lf %S\\n", "LINE2:writing#FF0000:Writing", "GPRINT:writing:LAST: Current\\: %5.1lf %S", "GPRINT:writing:MIN: Min\\: %5.1lf %S", "GPRINT:writing:AVERAGE: Avg\\: %5.1lf %S", "GPRINT:writing:MAX: Max\\: %5.1lf %S\\n", "LINE2:waiting#00AAAA:Waiting", "GPRINT:waiting:LAST: Current\\: %5.1lf %S", "GPRINT:waiting:MIN: Min\\: %5.1lf %S", "GPRINT:waiting:AVERAGE: Avg\\: %5.1lf %S", "GPRINT:waiting:MAX: Max\\: %5.1lf %S\\n", "HRULE:0#000000"; if ($ERROR = RRDs::error) { print "$0: unable to generate $period graph: $ERROR\n"; } }
Some settings that can be adjusted:
- my $rrd = ‘/opt/rrd’;
Roundrobin database file will be placed in /opt/rrd as nginx.rrd
- my $img = ‘/var/www/html/rrd’;
All image generated by the script will be placed in /var/www/html/rrd
Ie:
connections-day.png
connections-week.png
requests-month.png
requests-year.png
connections-month.png
connections-year.png
requests-day.png
requests-week.png
- my $URL = “http://www.example.com/nginx_status”;
my $URL should be adjusted according to your nginx configuration, $URL value required by LWP::UserAgent grab statistic values from nginx.
Run the script periodically using crontab
* * * * * root /path/to/rrd_nginx.pl
Some example graph results:
You can find original article here:
http://kovyrin.net/2006/04/29/monitoring-nginx-with-rrdtool/