Monitoring statystyk serwera Nginx za pomocą rrdtool

rrdtool to system statystyk dla serwerów i w dość prosty sposób możemy wykorzystać go do generowania wykresów obrazujących ruch na naszym serwerze Nginx. Instalujemy rrdtool, a w przypadku kompilacji musimy dodać wsparcie dla Perla (Gentoo USE: perl), a Nginx musi być skompilowany z flagą —-with-http_stub_status_module (Gentoo USE: status). Niniejszy artykuł jest tłumaczeniem wpisu z bloga Alexea N. Kovyrina

Konfiguracja Nginx

Wystarczy dodać dla danego bloku serwer lokację:
location /nginx_status {
            stub_status on;
            access_log   off;
            allow JAKIES.IP;
            deny all;
        }
Gdzie JAKIES.IP to IP admina, który ma mieć dostęp do statystyk :nice:. Teraz wystarczy uruchomić serwer i skierować się na http://strona.pl/nginx_status by zobaczyć coś w stylu:
Active connections: 1492
server accepts handled requests
 2124355 2124355 8278635
Reading: 6 Writing: 405 Waiting: 1081

Generowanie graficznych wykresów

Zapisz poniższy kod perla w pliku .pl:
#!/usr/bin/perl
use RRDs;
use LWP::UserAgent;

# katalog na bazę rrdtool
my $rrd = '/home/piotr/nginx';
# katalog na wykresy
my $img = '/home/piotr/nginx';
# URL statusu nginxa
my $URL = "http://localhost/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(/
/, $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
";

# 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
"; 
  }

  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
",
		
		"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
",
		
		"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
",
		
		"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
",

		"HRULE:0#000000";
  if ($ERROR = RRDs::error) { 
    print "$0: unable to generate $period graph: $ERROR
"; 
  }
}
Modyfikując przy tym ścieżki:
# katalog na bazę rrdtool
my $rrd = '/home/piotr/nginx';
# katalog na wykresy
my $img = '/home/piotr/nginx';
# URL statusu nginxa
my $URL = "http://localhost/nginx_status";
Następnie nadaj prawa wykonywalności:
chmod +x plik.pl
I wykonaj go by wygenerować wykresy:
./plik.pl
Na serwerze można dodać operację tą do crona. Efekt będzie tego typu:
connections-day
RkBlog
Comment article
Comment article RkBlog main page Search RSS Contact