2019-01-25 17:28:29 +00:00
#!/usr/bin/env bash
# usage
usage() {
USAGE=$(cat <<EOF
Usage: docker_check [CONFIG_FILE (absolute path)]
2022-07-10 16:29:44 +00:00
If no CONFIG_FILE is given, HOME/.docker_check.conf or /etc/docker_check.conf is used. This fallback option
2019-01-25 17:28:29 +00:00
has to exist or the script will exit.
Configuration can be done in any file and any pre-defined variable can be overwritten.
The following are optional or have reasonable defaults:
DOCKER_CHECK_LIST_FILE="HOME/.docker_check.list" // the list file (output current running to file: docker ps --format '{{.Names}}' >> $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/<scriptname>'.
EOF
)
echo "$USAGE";
}
set -e;
HOSTNAME=$(hostname)
DOCKER_CHECK_LIST_FILE="$HOME/.docker_check.list"
2022-07-10 16:29:44 +00:00
DOCKER_CHECK_GLOBAL_LIST_FILE="/etc/docker_check.list"
2019-01-25 17:28:29 +00:00
DOCKER_CHECK_NOTIFY_LEVELS=("UNKNOWN" "WARNING" "CRITICAL")
DOCKER_CHECK_MAIL_ENABLED=false
DOCKER_CHECK_MAIL_ADDRESS=""
CONTAINERS=()
# check for config file
2022-07-10 16:29:44 +00:00
apply_config() {
local config=$1;
if [[ ! -f "$config" ]]; then
echo "No config file specified";
echo "";
usage;
exit 1;
fi
set -a;
2022-07-10 18:47:46 +00:00
# shellcheck disable=SC1090
2022-07-10 16:29:44 +00:00
source "$config";
set +a;
}
2019-01-25 17:28:29 +00:00
source_config() {
2022-07-10 16:29:44 +00:00
local config=$1;
local configFallback=$2;
local configGlobalFallback=$3;
if [[ -f "$config" ]]; then
apply_config "$config";
2022-07-10 16:33:00 +00:00
return;
2022-07-10 16:29:44 +00:00
fi
if [[ -f "$configFallback" ]]; then
apply_config "$configFallback";
2022-07-10 16:33:00 +00:00
return;
2022-07-10 16:29:44 +00:00
fi
if [[ -f "$configGlobalFallback" ]]; then
apply_config "$configGlobalFallback";
2022-07-10 16:33:00 +00:00
return;
2022-07-10 16:29:44 +00:00
fi
2019-01-25 17:28:29 +00:00
}
2022-07-10 16:29:44 +00:00
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
2019-01-25 17:28:29 +00:00
2022-07-10 16:29:44 +00:00
if [[ ! -f $listFileToUse ]]; then
echo "$listFileToUse doesn't exist. Add a file which holds one systemd service or timer per line.";
2019-01-25 17:28:29 +00:00
echo "";
usage;
exit 1;
fi
2022-07-10 16:29:44 +00:00
echo "Scanning $listFileToUse for containers...";
2019-01-25 17:28:29 +00:00
while IFS='' read -r line || [[ -n "$line" ]]; do
CONTAINERS+=("$line")
echo "-> Found $line";
2022-07-10 16:29:44 +00:00
done < "$listFileToUse"
2019-01-25 17:28:29 +00:00
# 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;
2022-07-10 18:47:46 +00:00
# shellcheck disable=SC2155
2019-01-25 17:28:29 +00:00
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
2022-07-10 18:47:46 +00:00
echo "$MESSAGE"|mailx -Ssendwait -s "$SUBJECT" "$DOCKER_CHECK_MAIL_ADDRESS";
2019-01-25 17:28:29 +00:00
fi
fi
}
# get status for a docker container
function checkContainer() {
local CONTAINER=$1;
2022-07-10 18:47:46 +00:00
# shellcheck disable=SC2268
2019-01-25 17:28:29 +00:00
if [ "x${CONTAINER}" == "x" ]; then
log "$CONTAINER" "UNKNOWN" "Container ID or Friendly Name Required"
return;
fi
2022-07-10 18:47:46 +00:00
# shellcheck disable=SC2268
2019-01-25 17:28:29 +00:00
if [ "x$(which docker)" == "x" ]; then
log "$CONTAINER" "UNKNOWN" "Missing docker binary"
return;
fi
docker info > /dev/null 2>&1
2022-07-10 18:47:46 +00:00
# shellcheck disable=SC2181
2019-01-25 17:28:29 +00:00
if [ $? -ne 0 ]; then
log "$CONTAINER" "UNKNOWN" "Unable to talk to the docker daemon"
return;
fi
2022-07-10 18:47:46 +00:00
RUNNING=$(docker inspect --format="{{.State.Running}}" "$CONTAINER" 2> /dev/null)
2019-01-25 17:28:29 +00:00
if [ $? -eq 1 ]; then
2022-07-10 18:47:46 +00:00
log "${CONTAINER}" "UNKNOWN" "$CONTAINER does not exist."
2019-01-25 17:28:29 +00:00
return;
fi
if [ "$RUNNING" == "false" ]; then
2022-07-10 18:47:46 +00:00
log "${CONTAINER}" "CRITICAL" "$CONTAINER is not running."
2019-01-25 17:28:29 +00:00
return;
fi
2022-07-10 18:47:46 +00:00
RESTARTING=$(docker inspect --format="{{.State.Restarting}}" "$CONTAINER")
2019-01-25 17:28:29 +00:00
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