Skip to content

Instantly share code, notes, and snippets.

@robn
Created October 30, 2014 06:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save robn/df7f20f03f073399379b to your computer and use it in GitHub Desktop.
Save robn/df7f20f03f073399379b to your computer and use it in GitHub Desktop.
Consul two-stage check prototype
#!/usr/bin/env perl
use 5.014;
use warnings;
use strict;
use Consul;
use Sys::Hostname;
use Try::Tiny;
my ($service, $interval) = @ARGV;
unless ($service && $interval) {
say "usage: check.pl <service> <interval>";
exit 2;
}
my $node = hostname;
exit do_check($node, $service, $interval, sub { connect_check("127.0.0.1", 22) });
sub do_check {
my ($node, $service, $interval, $check_cb) = @_;
my $now = time;
say "Running check for $node/$service, interval $interval, now ".scalar localtime $now;
my $kv = Consul->new->kv;
my $kvpath = "fm/checks/$node/$service";
my $mark = try {
$kv->get("$kvpath/mark");
}
catch {
if (m/^404/) {
say "$kvpath/mark not found, assuming marked up";
return;
}
say "Couldn't get mark $kvpath/mark: $_";
return 2;
};
return $mark if defined $mark && !ref $mark;
if ($mark && $mark->value eq "down") {
say "$node/$service marked down";
return 2;
}
my $lastrun = try {
$kv->get("$kvpath/lastrun");
}
catch {
if (m/^404/) {
# never run before
return; # from try
}
say "Couldn't get last run time $kvpath/lastrun $_";
return 2;
};
return $lastrun if defined $lastrun && !ref $lastrun;
if ($lastrun && ($lastrun->value + $interval) > $now) {
my $lastresult = try {
$kv->get("$kvpath/lastresult");
}
catch {
if (m/^404/) {
# never run before
return; # from try
}
say "Couldn't get last result $kvpath/lastresult: $_";
return 2;
};
return $lastresult if defined $lastresult && !ref $lastresult;
if ($lastresult) {
say "Cached result, last run was ".($now-$lastrun->value)."s ago";
return $lastresult->value;
}
}
my $rc = try {
$check_cb->();
}
catch {
say "Check callback died: $_";
2;
};
try {
$kv->put("$kvpath/lastrun", $now);
}
catch {
say "Couldn't save last run time $kvpath/lastrun $_";
};
try {
$kv->put("$kvpath/lastresult", $rc);
}
catch {
say "Couldn't save last result $kvpath/lastresult $_";
};
return $rc;
}
sub connect_check {
my ($ip, $port) = @_;
use IO::Socket::INET;
my $s = IO::Socket::INET->new(
PeerAddr => $ip,
PeerPort => $port,
Proto => 'tcp',
Timeout => 2,
);
unless ($s) {
say "Connect to port $ip:$port failed: $!";
return 2;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment