91 lines
2.9 KiB
Perl
Executable File
91 lines
2.9 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
|
|
use strict;
|
|
use warnings;
|
|
use JSON;
|
|
use Getopt::Long;
|
|
use File::Which;
|
|
use Date::Parse;
|
|
|
|
my $docker = which('docker');
|
|
my $json = {};
|
|
my $pretty = 0;
|
|
my ($global, $container, $network, $volume) = undef;
|
|
|
|
GetOptions(
|
|
'global' => \$global,
|
|
'container=s' => \$container,
|
|
'network=s' => \$network,
|
|
'volume=s' => \$volume,
|
|
'pretty' => \$pretty
|
|
);
|
|
|
|
# Sanitize args
|
|
if (defined $container and not $container =~ m/^[a-zA-Z0-9\-_]+/){
|
|
die "Invalid container ID $container\n";
|
|
} elsif (defined $network and not $network =~ m/^[a-zA-Z0-9\-_]+/){
|
|
die "Invalid network ID\n";
|
|
} elsif (defined $volume and not $volume =~ m/^[a-zA-Z0-9\-_]+/){
|
|
die "Invalid volume name\n";
|
|
}
|
|
|
|
# Default formating
|
|
my $format = '{{ json . }}';
|
|
my $cmd;
|
|
if ($global){
|
|
$json->{info} = from_json(qx($docker info --format '$format'));
|
|
} elsif (defined $container) {
|
|
$json->{inspect} = from_json(qx($docker container inspect $container --format '$format'));
|
|
$json->{stats} = from_json(qx($docker container stats $container --format '$format' --no-stream));
|
|
# Remove percent sign so Zabbix can get raw value
|
|
foreach my $stat (qw(MemPerc CPUPerc)){
|
|
$json->{stats}->{$stat} =~ s/%$//;
|
|
}
|
|
# Extract mem usage vs mem limit, net in vs net out and blk read vs blk write
|
|
($json->{stats}->{MemCurrent}, $json->{stats}->{MemLimit}) = split(/\s*\/\s*/, $json->{stats}->{MemUsage});
|
|
($json->{stats}->{NetIOIn}, $json->{stats}->{NetIOOut}) = split(/\s*\/\s*/, $json->{stats}->{NetIO});
|
|
($json->{stats}->{BlockIORead}, $json->{stats}->{BlockIOWrite}) = split(/\s*\/\s*/, $json->{stats}->{BlockIO});
|
|
# Convert into Bytes
|
|
foreach my $stat (qw(MemCurrent MemLimit NetIOIn NetIOOut BlockIORead BlockIOWrite)){
|
|
$json->{stats}->{$stat} = convert_unit($json->{stats}->{$stat});
|
|
}
|
|
# Compute a useful Uptime from the StartedAt value
|
|
if ($json->{inspect}->{State}->{Running}){
|
|
$json->{stats}->{Uptime} = int(time() - str2time($json->{inspect}->{State}->{StartedAt}));
|
|
} else {
|
|
$json->{stats}->{Uptime} = 0;
|
|
}
|
|
} elsif (defined $network){
|
|
$json->{inspect} = from_json(qx($docker network inspect $network --format '$format'));
|
|
} elsif (defined $volume){
|
|
$json->{inspect} = from_json(qx($docker volume inspect $volume --format '$format'));
|
|
}
|
|
|
|
print to_json($json, { pretty => $pretty }) . "\n";
|
|
|
|
|
|
sub convert_unit {
|
|
my $val = shift;
|
|
my $suffix_multiplier = {
|
|
ki => 1024,
|
|
Ki => 1024,
|
|
Mi => 1024 * 1024,
|
|
Gi => 1024 * 1024 * 1024,
|
|
Ti => 1024 * 1024 * 1024 * 1024,
|
|
Pi => 1024 * 1024 * 1024 * 1024 * 1024,
|
|
k => 1000,
|
|
K => 1000,
|
|
M => 1000 * 1000,
|
|
G => 1000 * 1000 * 1000,
|
|
T => 1000 * 1000 * 1000 * 1000,
|
|
P => 1000 * 1000 * 1000 * 1000 * 1000
|
|
};
|
|
if ($val =~ m/^(\d+(\.\d+)?)(Ki|Mi|Gi|Ti|Pi|K|M|G|T|P)?B/){
|
|
$val = int($1 * $suffix_multiplier->{$3}) if (defined $3 and defined $suffix_multiplier->{$3});
|
|
# Remove the Bytes suffix if remaining
|
|
$val =~ s/B$//;
|
|
}
|
|
return $val;
|
|
}
|
|
|