#!/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; }