Last active
June 8, 2022 21:07
-
-
Save thbkrkr/5d3c11a53669e18e1f46 to your computer and use it in GitHub Desktop.
Get containers info and stats using the Docker Remote API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash -eu | |
# | |
# @description Get containers info and stats using the Docker Remote API | |
# @deps curl, jq | |
# @usage docker-stats.sh host-42 101.0.0.42 | |
DOCKER_HOSTNAME=$1 | |
DOCKER_IP=$2 | |
DOCKER_PORT=2376 | |
CERT_DIR=~/.docker/machines/.client | |
VERBOSE=1 | |
[[ "$(which curl 2>/dev/null)" == "" ]] && echo "error: install curl (http://curl.haxx.se/download.html)" && exit 1 | |
[[ "$(which jq 2>/dev/null)" == "" ]] && echo "error: install jq (http://stedolan.github.io/jq/download/)" && exit 1 | |
api() { | |
local endpoint=$1 | |
local options=$2 | |
curl -sk $options \ | |
https://$DOCKER_IP:$DOCKER_PORT/$endpoint \ | |
--cert $CERT_DIR/cert.pem \ | |
--key $CERT_DIR/key.pem \ | |
--cacert $CERT_DIR/ca.pem | |
} | |
PREFIX=/tmp/docker-container-$(date +%s) | |
w_container_json() { | |
local id=$1 | |
log "GET containers/$id/json" | |
api containers/$id/json "" > $PREFIX-$id-json | |
name=$(r "$(cat $PREFIX-$id-json)" ".Name" | sed -e 's|"||' -e 's|/||') | |
echo "$name" > $PREFIX-$id-name | |
log "SET name $name" | |
} | |
w_container_stats() { | |
local id=$1 | |
log "GET /containers/$containerId/stats" | |
api containers/$id/stats "-m 2" | tail -1 > $PREFIX-$id-stats | |
} | |
wf() { | |
local id=$1 | |
local kind=$2 | |
cat $PREFIX-$id-$kind >> JSON | |
} | |
w() { | |
echo "$1" >> JSON | |
} | |
r() { | |
local json="$1" | |
local jqexpr="$2" | |
echo "$json" | jq -r "$jqexpr" | |
} | |
log() { | |
[[ $VERBOSE -eq 1 ]] && echo " [dstats] $1" || nothing=todo | |
} | |
################################ | |
> JSON | |
log "GET /containers/json" | |
containers="$(api containers/json "")" | |
total_containers=$(r "$containers" '. | length') | |
w '{ | |
"'$DOCKER_HOSTNAME'": { | |
"total_containers": '$total_containers', | |
"containers": [' | |
s=""; nb_proc=0 | |
while read containerId; do | |
w_container_json $containerId & | |
sleep 0.0$RANDOM | |
w_container_stats $containerId & | |
nb_proc=$(($nb_proc+2)) | |
if [ "$nb_proc" -ge $((total_containers*2)) ]; then | |
wait | |
nb_proc=0 | |
fi | |
s="," | |
done < <(r "$containers" '.[] | .Id') | |
wait | |
log "Write JSON" | |
s="" | |
while read containerId; do | |
name=$(cat $PREFIX-$containerId-name) | |
w $s' { | |
"'$name'": { | |
"info": ' | |
wf $containerId json | |
w ', | |
"stats": ' | |
wf $containerId stats | |
w ' | |
} | |
}' | |
s="," | |
done < <(r "$containers" '.[] | .Id') | |
w ' ] | |
} | |
}' | |
rm -f $PREFIX* | |
cat JSON | jq . >/dev/null 2>&1 \ | |
&& log "Successful" || log "Error" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash -eu | |
# | |
# @description Get containers info and stats using the Docker Remote API | |
# @deps jq, curl or nc | |
# @usage docker-stats.sh host-42 101.0.0.42 | |
# | |
if [ -S /var/run/docker.sock ]; then | |
API=api_socket | |
else | |
API=api_http | |
fi | |
case $API in | |
api_http) | |
DOCKER_HOSTNAME=${1:-$(ls -1 /ops/machine/machines | head -1)} ;; | |
esac | |
api_http() { | |
declare endpoint=$1 options=${2:-""} | |
DOCKER_IP=$(docker-machine ip $DOCKER_HOSTNAME 2> /dev/null) | |
DOCKER_PORT=2376 | |
CERT_DIR=$MACHINE_STORAGE_PATH/machines/$DOCKER_HOSTNAME | |
curl -sk $options \ | |
--cert $CERT_DIR/cert.pem --key $CERT_DIR/key.pem --cacert $CERT_DIR/ca.pem \ | |
https://$DOCKER_IP:$DOCKER_PORT$endpoint | |
} | |
api_socket() { | |
declare endpoint=$1 options=${2:-""} | |
echo -ne "GET $endpoint HTTP/1.1\r\n\r\n" \ | |
| nc -U $options /var/run/docker.sock \ | |
| grep '^[{|\[]' | |
} | |
stats() { | |
( | |
while read container; do | |
local container_id=$(jq -r .Id <<< $container) | |
echo '{ | |
"container": '$container', | |
"stats": '$($API "/containers/$container_id/stats?stream=false" "-q 2")' | |
}' & | |
done < <($API /containers/json | jq -c '.[]' | sed "s|/||") | |
wait | |
) \ | |
| jq '{ | |
name:.container.Names[0], | |
image:.container.Image, | |
mem_usage:.stats.memory_stats.usage, | |
mem_limit:.stats.memory_stats.limit, | |
cpu_usage:.stats.precpu_stats.cpu_usage.total_usage, | |
cpu_usage:.stats.precpu_stats.system_cpu_usage, | |
rx_bytes:.stats.networks.eth0.rx_bytes, | |
tx_bytes:.stats.networks.eth0.tx_bytes | |
}' \ | |
| jq -s . | |
} | |
stats |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash -eu | |
metrics() { | |
declare cid=$1 | |
echo '{' | |
container_metric $cid memory memory.stat | |
echo "," | |
container_metric $cid cpuacct cpuacct.stat | |
echo "," | |
container_metric $cid blkio blkio.io_serviced | |
echo "," | |
container_metric $cid blkio blkio.io_service_bytes | |
echo "," | |
container_metric $cid blkio blkio.io_service_queued | |
echo "," | |
container_metric $cid blkio blkio.sectors | |
echo '}' | |
} | |
container_metric() { | |
declare cid=$1 metric_type=$2 metric_filename=$3 | |
local cgroup_path=/sys/fs/cgroup | |
local metric_file=$cgroup_path/$metric_type/docker/$cid/$metric_filename | |
local comma= | |
echo $metric_file | |
if [[ -f $metric_file ]]; then | |
while read metric; do | |
tpl="$comma\"$metric_filename.\1\":\"\2\"" | |
sed -r \ | |
"s|([A-Za-z_]*) ([0-9]*)|$tpl|" \ | |
<<< $metric | |
comma=',' | |
done < <(cat $metric_file) | |
fi | |
} | |
while read cid; do | |
metrics $cid | |
done < <(docker ps --no-trunc -q) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FROM alpine:3.7 | |
RUN apk --no-cache add bash jq netcat-openbsd bc | |
COPY docker-stats.sh /usr/local/bin/docker-stats.sh | |
ENTRYPOINT ["docker-stats.sh"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
build: | |
docker build -t krkr/docker-stats . | |
run: | |
@docker run --rm \ | |
-v /var/run/docker.sock:/var/run/docker.sock:ro \ | |
krkr/docker-stats | |
test: | |
./docker-stats-v$v.sh |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
another option (requires curl > 7.4 ) if not exposing the http docker api is to change api() method to use
curl --unix-socket /var/run/docker.sock $options
It is possible for container/stats to return an empty string so i made this change
w_container_stats() {
local id=$1
}