Created
March 8, 2013 08:55
-
-
Save fujiwara/5115109 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use strict; | |
use Data::Dumper; | |
package ZabbixAPI { | |
use Mouse; | |
use JSON; | |
use HTTP::Request::Common; | |
use WWW::Mechanize; | |
use Data::Dumper; | |
use Log::Minimal; | |
has ua => ( | |
is => "rw", | |
default => sub { | |
WWW::Mechanize->new( | |
ssl_opts => { | |
verify_hostname => 0, | |
SSL_verify_mode => "SSL_VERIFY_NONE", | |
}, | |
timeout => 180, | |
); | |
} | |
); | |
has auth => ( is => "rw", isa => "Str", ); | |
has id => ( is => "rw", isa => "Int", default => 1 ); | |
has url => ( is => "rw", isa => "Str", ); | |
has cookie => ( is => "rw", isa => "Str", ); | |
sub login { | |
my $self = shift; | |
my %params = @_; | |
$self->ua->get( $self->url ); | |
$self->ua->field( name => $params{user} ); | |
$self->ua->field( password => $params{password} ); | |
$self->ua->click("enter"); | |
my $r = { | |
method => "user.authenticate", | |
params => \%params, | |
auth => undef, | |
}; | |
$self->auth( $self->_request($r) ); | |
debugf "auth: %s", $self->auth; | |
$self->auth; | |
} | |
sub call { | |
my ($self, $method, $params) = @_; | |
my $r = { | |
method => $method, | |
params => $params, | |
auth => $self->auth, | |
}; | |
$self->_request($r); | |
} | |
sub _request { | |
my $self = shift; | |
my $r = shift; | |
$r->{id} = $self->{id}++; | |
$r->{jsonrpc} = "2.0"; | |
my $json = encode_json $r; | |
my $req = POST $self->url . "api_jsonrpc.php", | |
"Content-Type" => "application/json-rpc", | |
"Content-Length" => length($json), | |
"Content" => $json, | |
; | |
my $res = $self->ua->request($req); | |
decode_json($res->content)->{result}; | |
} | |
sub get { | |
my $self = shift; | |
my $url = shift; | |
$url = $self->url . $url | |
unless $url =~ m{^https?://}; | |
my $req = GET $url; | |
debugf $req->as_string; | |
$self->ua->request($req); | |
} | |
1; | |
}; | |
use Time::Piece; | |
use Path::Class qw/ file /; | |
use Log::Minimal; | |
use Imager; | |
use Try::Tiny; | |
use Config::Pit; | |
use Getopt::Long; | |
use Storable; | |
my ($weekly, $date); | |
GetOptions ( | |
"weekly" => \$weekly, | |
"date=s" => \$date, | |
); | |
my $host = shift || die "no host"; | |
my $graph = shift || die "no graph name"; | |
my $config = pit_get("zabbix", require => { | |
"user" => "username on zabbix", | |
"password" => "password on zabbix", | |
"url" => "zabbix url", | |
}); | |
my $api = ZabbixAPI->new( url => $config->{url} ); | |
infof "login to zabbix..."; | |
$api->login( | |
user => $config->{user}, | |
password => $config->{password}, | |
); | |
my $graph = $api->call( | |
"graph.get" => { | |
search => { name => $graph }, | |
filter => { host => $host }, | |
limit => 5, | |
} | |
); | |
my $period = 86400; | |
$period *= 7 if $weekly; | |
my $t = $date | |
? Time::Piece->strptime($date, "%Y%m%d")->epoch | |
: time; | |
my $now = localtime( $t - $period )->strftime("%Y%m%d000000"); | |
my $prev = localtime( $t - $period * 2 )->strftime("%Y%m%d000000"); | |
for my $g ( @$graph ) { | |
my $gid = $g->{graphid}; | |
my @file; | |
for my $stime ($now, $prev) { | |
my $url = "chart2.php?stime=$stime&period=$period&width=500&graphid=$gid"; | |
infof "graphid: %d, stime: %s", $gid, $stime; | |
my $res = $api->get($url); | |
my $file = "$gid-$stime.png"; | |
file($file)->openw->print($res->content); | |
push @file, $file; | |
} | |
try { | |
my $img = image_diff(@file); | |
my $file = "$gid-diff.png"; | |
$img->write( file => $file ); | |
infof "write to %s", $file; | |
system("open", $file); | |
} | |
catch { | |
my $e = $_; | |
warnf "error in processing image: %s", $e; | |
}; | |
} | |
sub image_diff { | |
my ($file1, $file2) = @_; | |
my $img1 = Imager->new; | |
$img1->read( file => $file1 ) | |
or die $img1->errstr; | |
my $img2 = Imager->new; | |
$img2->read( file => $file2 ) | |
or die $img2->errstr; | |
my $diff = $img1->difference( other => $img2, mindist => 32 ); | |
my $dpixels = 0; | |
for my $x ( 0 .. $diff->getwidth - 1 ) { | |
for my $y ( 0 .. $diff->getheight - 1 ) { | |
my $c = $diff->getpixel( x => $x, y => $y ); | |
$dpixels++ if ($c->rgba)[3] != 0; | |
} | |
} | |
my $total = $diff->getwidth * $diff->getheight; | |
infof "diff: %d pixels, %f %%\n", $dpixels, ($dpixels / $total * 100); | |
$diff; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment