#!/usr/bin/env bash # usage usage() { USAGE=$(cat <> $HOME/.docker_check.list) DOCKER_CHECK_NOTIFY_LEVELS=("UNKNOWN" "WARNING" "CRITICAL") // when to notify/output/send mail. possible: "UNKNOWN" "WARNING" "CRITICAL" "INFO", should at least be () DOCKER_CHECK_MAIL_ENABLED=false // send email (address has to be set), values: false|true DOCKER_CHECK_MAIL_ADDRESS="" // mail.rc has to be configured You can copy this script to '/usr/local/bin' and use create a custom CONFIG_FILE as user. Examples can be found in '/usr/share/doc/'. EOF ) echo "$USAGE"; } set -e; HOSTNAME=$(hostname) DOCKER_CHECK_LIST_FILE="$HOME/.docker_check.list" DOCKER_CHECK_GLOBAL_LIST_FILE="/etc/docker_check.list" DOCKER_CHECK_NOTIFY_LEVELS=("UNKNOWN" "WARNING" "CRITICAL") DOCKER_CHECK_MAIL_ENABLED=false DOCKER_CHECK_MAIL_ADDRESS="" CONTAINERS=() # check for config file apply_config() { local config=$1; if [[ ! -f "$config" ]]; then echo "No config file specified"; echo ""; usage; exit 1; fi set -a; # shellcheck disable=SC1090 source "$config"; set +a; } source_config() { local config=$1; local configFallback=$2; local configGlobalFallback=$3; if [[ -f "$config" ]]; then apply_config "$config"; return; fi if [[ -f "$configFallback" ]]; then apply_config "$configFallback"; return; fi if [[ -f "$configGlobalFallback" ]]; then apply_config "$configGlobalFallback"; return; fi } source_config "$1" "$HOME/.docker_check.conf" "/etc/docker_check.conf" listFileToUse="" if [[ -f "$DOCKER_CHECK_LIST_FILE" ]]; then listFileToUse="$DOCKER_CHECK_LIST_FILE" else listFileToUse="$DOCKER_CHECK_GLOBAL_LIST_FILE" fi if [[ ! -f $listFileToUse ]]; then echo "$listFileToUse doesn't exist. Add a file which holds one systemd service or timer per line."; echo ""; usage; exit 1; fi echo "Scanning $listFileToUse for containers..."; while IFS='' read -r line || [[ -n "$line" ]]; do CONTAINERS+=("$line") echo "-> Found $line"; done < "$listFileToUse" # check if current status is in array of DOCKER_CHECK_NOTIFY_LEVELS function shouldLog() { local VALUE=$1; for i in "${DOCKER_CHECK_NOTIFY_LEVELS[@]}"; do if [ "$i" == "$VALUE" ] ; then echo true; return; fi done echo false; } # log and send mail if enabled function log() { local CONTAINER=$1; local STATUS=$2; local MESSAGE=$3; # shellcheck disable=SC2155 local SHOULD_LOG=$(shouldLog "$STATUS"); if [ "$SHOULD_LOG" = "true" ]; then local SUBJECT="[docker $HOSTNAME] $STATUS $CONTAINER"; echo "$SUBJECT: $MESSAGE"; if [ "$DOCKER_CHECK_MAIL_ENABLED" = true ]; then echo "$MESSAGE"|mailx -Ssendwait -s "$SUBJECT" "$DOCKER_CHECK_MAIL_ADDRESS"; fi fi } # get status for a docker container function checkContainer() { local CONTAINER=$1; # shellcheck disable=SC2268 if [ "x${CONTAINER}" == "x" ]; then log "$CONTAINER" "UNKNOWN" "Container ID or Friendly Name Required" return; fi # shellcheck disable=SC2268 if [ "x$(which docker)" == "x" ]; then log "$CONTAINER" "UNKNOWN" "Missing docker binary" return; fi docker info > /dev/null 2>&1 # shellcheck disable=SC2181 if [ $? -ne 0 ]; then log "$CONTAINER" "UNKNOWN" "Unable to talk to the docker daemon" return; fi RUNNING=$(docker inspect --format="{{.State.Running}}" "$CONTAINER" 2> /dev/null) if [ $? -eq 1 ]; then log "${CONTAINER}" "UNKNOWN" "$CONTAINER does not exist." return; fi if [ "$RUNNING" == "false" ]; then log "${CONTAINER}" "CRITICAL" "$CONTAINER is not running." return; fi RESTARTING=$(docker inspect --format="{{.State.Restarting}}" "$CONTAINER") if [ "$RESTARTING" == "true" ]; then log "$CONTAINER" "WARNING" "$CONTAINER state is restarting." return; fi #STARTED=$(docker inspect --format="{{.State.StartedAt}}" $CONTAINER) #NETWORK=$(docker inspect --format="{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" $CONTAINER) #log "$CONTAINER" "INFO" "$CONTAINER is running. IP: $NETWORK, StartedAt: $STARTED" log "$CONTAINER" "INFO" "$CONTAINER is running." return; } # execute check for defined containers for container in "${CONTAINERS[@]}"; do echo "Checking $container..."; checkContainer "$container" done