#!/bin/bash # ====================================================================== # # Check DOCKER INFOS # # requirements: # - docker # - sudo permissions on docker command # - jq # - bc # # ---------------------------------------------------------------------- # Cli docs: # https://docs.docker.com/engine/reference/commandline/docker/ # ---------------------------------------------------------------------- # 2024-01-26 v1.0 <axel.hahn@unibe.ch> init # 2024-01-29 v1.1 <axel.hahn@unibe.ch> fix help; detect reason for no output # ====================================================================== . $(dirname $0)/inc_pluginfunctions . $(dirname $0)/inc_dockerfunctions.sh self_APPVERSION=1.1 # ---------------------------------------------------------------------- # FUNCTIONS # ---------------------------------------------------------------------- # show help function _showHelp(){ local _self=$( basename $0 ) cat <<EOH $( ph.showImlHelpHeader ) Show resources of running docker instances. This check provides performance data except on mode "all". USAGE: $_self [OPTIONS] OPTIONS: General: -h, --help this help -d, --debug Debug; Flag: show docker env values. Connect to docker: -p, --path Custom directory for docker binary -t, --target Custom docker target; value for DOCKER_HOST Needed only if Docker does not run on a unix socket or multiple users run a rootless docker daemon. mode: -m, --mode MODE Mode what kind of information to show. The output of container list is sorted by the maximum value first. all default; This view is unsorted. This check has no performance data. cpu CPU usage total of all containers mem Memory max usage of most consuming container memtotal sum of memory usage netio sum of netio of all containers IN and OUT blockio sum of blockio of all containers IN and OUT EXAMPLES: $_self Show stats of all containers $_self -p /usr/bin Show stats of all containers. The docker binary will be searched in given path first - then in all other dirs of \$PATH $_self -d Show stats of all containers and json with docker env infos. $_self -m cpu Show cpu usage total of all containers. The container list is sorted by cpu usage. The most consuming container is on top. EOH } # ---------------------------------------------------------------------- # MAIN # ---------------------------------------------------------------------- bOptDebug=0 sMode="all" while [[ "$#" -gt 0 ]]; do case $1 in -h|--help) _showHelp; exit 0;; -d|--debug) bOptDebug=1; shift;; -p|--path) PATH="$2:$PATH"; shift; shift;; -m|--mode) sMode="$2"; shift; shift;; -t|--target) export DOCKER_HOST="$2"; shift; shift;; *) echo "ERROR: Unknown parameter: $1"; _showHelp; exit 1; esac; done sLabel="Docker stats" case "$sMode" in "cpu") sLabel="Docker CPU usage total of all containers: %s percent"; sUnit="1"; sumkey="CPUPerc"; sColumns=".Container, .${sumkey}, .Name" ;; "mem") sLabel="Docker Memory max usage in most consuming container: %s percent"; sUnit="1"; maxkey="MemPerc"; sColumns=".Container, .${maxkey}, .MemUsage, .Name" ;; "netio") sLabel="Docker Network I/O of all containers: %s MB IN .. %s MB OUT"; sUnit="M"; sumkey="NetIO"; f2=1; sColumns=".Container, .${sumkey}, .Name" ;; "memtotal") sLabel="Docker Memory usage of all containers: %s MB"; sUnit="M"; sumkey="MemUsage"; f2=0; sColumns=".Container, .${sumkey}, .Name" ;; "blockio") sLabel="Docker Block I/O of all containers: %s MB IN .. %s MB OUT"; sUnit="M"; sumkey="BlockIO"; f2=1; sColumns=".Container, .${sumkey}, .Name" ;; "all") ;; *) ph.setStatus critical echo "ERROR: mode [$sMode] is unknown. Use -h to get help." ph.exit esac test -z "$sColumns" && sColumns=".Container, .CPUPerc, .MemUsage, .MemPerc, .NetIO, .PIDs, .Name" ph.require "docker" ph.require "jq" ph.require "bc" _detectDockerenv # --- get stats data data=$( sudo -n --preserve-env docker stats --no-stream --format '{{ json . }}' ) _detectDockererror "$data" # --- checks to detect maximum if [ -n "${maxkey}" ]; then iMax=0 sMax=$( echo "$data" | tr -d '%' | jq -r ".${maxkey}" | sort -hr | head -1 | sed "s#^\.#0#" ) iMax=$( ph.toUnit "$sMax" "1" 0 ) ph.perfadd "${sMode}-max" "$iMax" "" "" 0 "100" sLabel=$( printf "${sLabel}" ${sMax} ) fi # --- checks with sum of a value if [ -n "${sumkey}" ]; then sum=0 # split 2 value field - get the 1st one. example: "81.1kB / 1.66MB" --> "81.1k" for myval in $( echo "$data" | tr -d '%' | jq -r ".${sumkey}" | cut -f 1 -d " " | tr -d "B" ) do valuniq=$( ph.toUnit "$myval" "" ) sum=$( bc <<< "$valuniq + ${sum}" ) done test "$sUnit" = "1" && sumhr=$( ph.toUnit "$sum" "1" 0 ) test "$sUnit" = "M" && sumhr=$( ph.toUnit "$sum" "M" 3 ) # --- checks with IN and OUT if [ "$f2" = "1" ]; then sum2=0 # split 2 value field - get the 2nd one. example: "81.1kB / 1.66MB" --> "1.66M" for myval in $( echo "$data" | tr -d '%' | jq -r ".${sumkey}" | cut -f 3 -d " " | tr -d "B" ) do valuniq=$( ph.toUnit "$myval" "" ) sum2=$( bc <<< "$valuniq + ${sum2}" ) done ph.perfadd "${sMode}-1" "$sum" "" "" ph.perfadd "${sMode}-2" "$sum2" "" "" sum2hr=$( ph.toUnit "$sum2" "M" 3 ) sLabel=$( printf "${sLabel}" ${sumhr} ${sum2hr} ) else ph.perfadd "${sMode}-sum" "$sum" "" "" sLabel=$( printf "${sLabel}" ${sumhr} ) fi fi # --- output line="------------------------------------------------------------------------------------------" ph.status "$sLabel" if [ "$sMode" = "all" ]; then echo "ID CPU % MEM USAGE / LIMIT MEM % NET I/O PIDs Name" echo "$line" jq -r "[$sColumns] | @tsv" <<< "$data" fi if [ -n "${maxkey}" ]; then echo "ID ${maxkey}" echo "$line" jq -r "[$sColumns] | @tsv" <<< "$data" | sort -k +2 -h -r fi if [ -n "${sumkey}" ]; then echo "ID ${sumkey}" echo "$line" jq -r "[$sColumns] | @tsv" <<< "$data" | sort -k +2 -h -r fi echo # if -d was given then show debug infos too test $bOptDebug -eq 1 && ( echo; echo "DEBUG: full docker system infos as json"; echo "$data" | jq ; _debugInfos) ph.exit # ----------------------------------------------------------------------