diff --git a/check_docker_io b/check_docker_io new file mode 100755 index 0000000000000000000000000000000000000000..f85571dcdfc0714a740e96df01b8d8cccc34d8f1 --- /dev/null +++ b/check_docker_io @@ -0,0 +1,153 @@ +#!/bin/bash +# ====================================================================== +# +# Check DOCKER IO DATA +# +# requirements: +# - docker +# - sudo permissions on docker command +# - jq +# - bc +# +# ---------------------------------------------------------------------- +# 2024-02-22 v0.1 <axel.hahn@unibe.ch> init +# ====================================================================== + + +. $(dirname $0)/inc_pluginfunctions +. $(dirname $0)/inc_dockerfunctions.sh + +self_APPVERSION=0.1 + +typeset -i iRead +typeset -i iTrans +typeset -i iSpeedRead +typeset -i iSpeedTrans + +# ---------------------------------------------------------------------- +# FUNCTIONS +# ---------------------------------------------------------------------- + + +# show help +function _showHelp(){ + local _self=$( basename $0 ) + cat <<EOH +$( ph.showImlHelpHeader ) + +Show IO data of all docker containers + +USAGE: + $_self [OPTIONS] + +OPTIONS: + + General: + -h, --help this help + + 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. + + netio sum of netio of all containers IN and OUT + +EXAMPLES: + $_self -m netio + Show netio of all docker containers + +EOH +} + +# get a list of all running container names +function getContainerNames(){ + sudo -n --preserve-env docker ps --format '{"Names": "{{.Names}}" }' | cut -f 4 -d '"' +} + +# get process id if a given single container +# param string name of container +function getPidOfContainer(){ + sudo -n --preserve-env docker inspect -f '{{ .State.Pid }}' "$1" +} + + +# ---------------------------------------------------------------------- +# 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="??" + +case "$sMode" in + "netio") sLabel="Docker Network I/O of all containers: %s MB/s IN .. %s MB/s OUT";; + *) ph.setStatus critical + echo "ERROR: mode [$sMode] is unknown. Use -h to get help." + ph.exit +esac + +ph.require "docker" +ph.require "jq" +ph.require "bc" + +# --- get data +out=$( + for CONTAINER_NAME in $( getContainerNames ) + do + CONTAINER_PID=$(getPidOfContainer $CONTAINER_NAME ) + + case "$sMode" in + "netio") + data=$( grep ":" "/proc/$CONTAINER_PID/net/dev" | grep -vE "(lo|bond.*|ppp.*):") + iRead=$( echo "$data" | awk '{ sum+=$2} END { print sum;}' ) + iTrans=$( echo "$data" | awk '{ sum+=$3} END { print sum;}' ) + iSpeedRead=$( ph.perfdeltaspeed "netio-container-$CONTAINER_NAME-rx" $iRead) + iSpeedTrans=$(ph.perfdeltaspeed "netio-container-$CONTAINER_NAME-tx" $iTrans) + + printf "%-20s %10s %10s %15s %15s\n" "${CONTAINER_NAME}" "$iRead" "$iTrans" "$iSpeedRead B/s" "$iSpeedTrans B/s" + + ;; + esac + done +) + +# --- calc total values over all containers: +iRead=$( echo "$out" | awk '{ sum+=$2} END { print sum;}' ) +iTrans=$( echo "$out" | awk '{ sum+=$3} END { print sum;}' ) + +iSpeedRead=$( ph.perfdeltaspeed "netio-containers-rx" $iRead) +iSpeedTrans=$(ph.perfdeltaspeed "netio-containers-tx" $iTrans) + +ph.perfadd "rx" "$iSpeedRead" +ph.perfadd "tx" "$iSpeedTrans" + +# --- output +sLabel=$( printf "$sLabel" "$(ph.toUnit $iSpeedRead M 2 )" "$(ph.toUnit $iSpeedTrans M 2 )" ) + +ph.status "$sLabel" +echo "$out" +ph.exit + + +# 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 + + +# ---------------------------------------------------------------------- diff --git a/inc_pluginfunctions b/inc_pluginfunctions index 55b1b19dafb370ce2931f14c2f491e0c614cf3da..c7a7dcf9e5111c879202fd1c216211cc3db0a5ff 100644 --- a/inc_pluginfunctions +++ b/inc_pluginfunctions @@ -320,6 +320,12 @@ function ph.toUnit(){ local _value=$1 local _unit=$2 local _digits=${3:-0} + local _dots + + if [ "$_value" -eq "0" ]; then + echo "0" + return 0 + fi local _multiply; _multiply=$( ph._getExp "$_value" ) local _divisor; _divisor=$( ph._getExp "$_unit" ) @@ -327,7 +333,6 @@ function ph.toUnit(){ local _bc _bc="bc" - local _dots test $_digits -gt 0 && _dots=$( yes "." 2>/dev/null | head -$_digits | tr -d "\n" ) test $_digits -gt 0 && _bc+=" -l | grep -o '.*\\.${_dots}'"