站点监控

在监控宝注册了站点监控服务,天天给我发email报告站点下线。无奈只好发了个tk询问原因,客服回复说网络一直木有问题。只要写个小的监控程序丢服务器跑着,看看是否是真的是服务器掉线。

找了一下perl的ping模块,最终选了Net::Ping,因为可以记录响应时间。使用Sqlite数据库保存数据,用highcharts绘制时间的折线图。

以下为相关代码:

alive.pl收集特定几个站点的ping响应时间,使用cron定时执行。

#!/usr/bin/perl

use strict;
use warnings;
use DBI;
use Net::Ping;

my $dbh = DBI->connect("dbi:SQLite:dbname=alive.db","","");
my $dbconn = $dbh->prepare("SELECT * FROM host");
$dbconn->execute();
my @domains;
while (my @row_ary = $dbconn->fetchrow_array) {
 my ($id, $domain) = @row_ary;
 push(@domains, $domain);
}

my $p = Net::Ping->new("icmp", 5);;
$p->hires();

foreach my $domain (@domains) {
 my ($ret, $rtt, $ip) = $p->ping($domain);
 my $timestamp = time();
 my $time = $rtt * 1000;
 $time = $time > 5000 ? -10 : $time;
 $dbh->do( "insert into alive values( $timestamp, '$domain', '$ip', $time )");
 if ($dbh->err()) {
 die "$DBI::errstr\n";
 }
 sleep(1);
}

$p->close();
$dbh->disconnect();

view.pl根据alive.pl收集到的数据进行绘图,得到时间曲线。

#!/usr/bin/perl

use strict;
use warnings;
use POSIX qw(tzset);
use Math::Round;
use Date::Calc qw(Mktime);
use CGI;
use DBI;
use JSON;

my $q = new CGI;
$ENV{TZ} = 'Asia/Shanghai';
tzset;
print $q->header("text/html; charset=UTF-8");
my $dbh = DBI->connect("dbi:SQLite:dbname=alive.db","","");
my $dbconn = $dbh->prepare("SELECT * FROM host");
my $ts = $q->param("timestamp");
my ($year,$mon,$day,$hour,$min);
if($ts) {
 ($year,$mon,$day,$hour,$min) = ($ts=~/(\d+)-(\d+)-(\d+) (\d+):(\d+)/);
 $ts = Mktime($year, $mon, $day, $hour, $min, 0);
}
else {
 $ts = time();
}
$dbconn->execute();
my @domains;
while (my @row_ary = $dbconn->fetchrow_array) {
 my ($id, $domain) = @row_ary;
 push(@domains, $domain);
}
my $series;
my $timestamp;
my $date;
foreach my $domain (@domains) {
 my $dbconn = $dbh->prepare("SELECT * FROM alive WHERE host='$domain' and timestamp < $ts ORDER BY timestamp DESC LIMIT 12");
 $dbconn->execute();
 my $data;
 my $x;
 $data->{'name'} = $domain;
 while (my @row_ary = $dbconn->fetchrow_array) {
 my ($timestamp, $host, $ip, $time) = @row_ary;
 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($timestamp);
 $mon++; $year += 1900;
 $date = "$year年$mon月$mday日" unless $date;
 push(@{$data->{'data'}}, nearest(.01,$time));
 push(@{$x}, "$hour:$min");
 }
 @{$data->{'data'}} = reverse @{$data->{'data'}};
 @{$x} = reverse @{$x};
 push(@{$series}, $data);
 $timestamp = $x;
}
$series = encode_json($series);
$timestamp = encode_json($timestamp);
print <<"EOF";
<html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <title>网络监控</title>
 <script src="meteora/meteora.js"></script>
 <script type="text/javascript" src="jquery.min.js"></script>
 <script src="highcharts.js"></script>
 <script src="exporting.js"></script>
 <script type="text/javascript">
\$(function () {
 var chart;
 \$(document).ready(function() {
 chart = new Highcharts.Chart({
 chart: {
 renderTo: 'container',
 type: 'line',
 marginRight: 130,
 marginBottom: 25
 },
 title: {
 text: '$date',
 x: -20 //center
 },
 xAxis: {
 categories: $timestamp
 },
 yAxis: {
 title: {
 text: 'Time (ms)'
 },
 plotLines: [{
 value: 0,
 width: 1,
 color: '#808080'
 }]
 },
 tooltip: {
 formatter: function() {
 return '<b>'+ this.series.name +'</b><br/>'+
 this.x +': '+ this.y +'ms';
 }
 },
 legend: {
 layout: 'vertical',
 align: 'right',
 verticalAlign: 'top',
 x: -10,
 y: 100,
 borderWidth: 0
 },
 series: $series
 });
 });
});

Meteora.uses('Meteora.Calendar');
Meteora.onStart(
 function () {
 new Calendar(
 'timestamp',
 {
 format: '%Y-%m-%d %H:%i',
 minYear: 2000,
 showHour: true,
 showMinute: true,
 showMeridiem: true
 });
 }
);

</script>
 </head>

<body>
 <div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>
 <form action="view.pl" method="post">
 <input id="timestamp" name="timestamp" type="text" />
 <input type="submit" value="查看" />
 </from>
 </body>

</html>
EOF

地址:http://lab.lemontv.me/alive/view.pl

Leave a Comment

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据