Collect RSS groups, top processes, and loadavg from inside each podman container (not host /proc), merge into performance.memory, show compact labels with cgroup limits and byte tooltips, and cover this in the test suite.
70 lines
2.2 KiB
Bash
Executable file
70 lines
2.2 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Snapshot loadavg + RSS groups inside a podman container (for landing stats).
|
|
# Usage: collect_container_resources.sh CONTAINER [OUT.json]
|
|
# Prints JSON to stdout (and writes OUT when given).
|
|
set -euo pipefail
|
|
|
|
CTR="${1:-}"
|
|
OUT="${2:-}"
|
|
if [ -z "$CTR" ]; then
|
|
echo "usage: $0 CONTAINER [OUT.json]" >&2
|
|
exit 2
|
|
fi
|
|
|
|
ADMIN_LOG="${ADMIN_LOG:-${HOME}/src/koopa/koopa-admin-log}"
|
|
MEM_SRC="${MEM_SNAPSHOT_SRC:-$ADMIN_LOG/scripts/taler-shared/mem-snapshot.sh}"
|
|
MEM_DST="${MEM_SNAPSHOT_DST:-/usr/local/lib/landing-mem-snapshot.sh}"
|
|
|
|
if ! podman inspect -f '{{.State.Running}}' "$CTR" 2>/dev/null | grep -qx true; then
|
|
echo "{\"ok\":false,\"error\":\"container not running: $CTR\"}"
|
|
exit 1
|
|
fi
|
|
|
|
if [ -f "$MEM_SRC" ]; then
|
|
podman exec "$CTR" mkdir -p "$(dirname "$MEM_DST")" 2>/dev/null || true
|
|
podman cp "$MEM_SRC" "${CTR}:${MEM_DST}"
|
|
fi
|
|
|
|
# Run emit inside container (needs /proc + cgroup of that container)
|
|
set +e
|
|
raw=$(podman exec "$CTR" bash -c '
|
|
set -e
|
|
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
|
if [ ! -f /usr/local/lib/landing-mem-snapshot.sh ]; then
|
|
echo "{\"ok\":false,\"error\":\"mem-snapshot helper missing\"}"
|
|
exit 1
|
|
fi
|
|
# shellcheck disable=SC1091
|
|
. /usr/local/lib/landing-mem-snapshot.sh
|
|
if ! declare -F mem_snapshot_emit >/dev/null 2>&1; then
|
|
# older helper without emit — synthesize
|
|
mem_snapshot_json
|
|
loadavg=""
|
|
[ -r /proc/loadavg ] && loadavg=$(awk "{print \$1\",\"\$2\",\"\$3}" /proc/loadavg)
|
|
printf "{\"ok\":true,\"source\":\"mem-snapshot-legacy\",\"loadavg\":%s,\"memory\":{%s}}\n" \
|
|
"\"$loadavg\"" "$MEM_JSON"
|
|
else
|
|
mem_snapshot_emit
|
|
fi
|
|
' 2>/tmp/landing-mem-err.$$)
|
|
ec=$?
|
|
set -e
|
|
|
|
if [ "$ec" -ne 0 ] || [ -z "$raw" ]; then
|
|
err=$(tr '\n' ' ' </tmp/landing-mem-err.$$ 2>/dev/null | head -c 200 || true)
|
|
rm -f /tmp/landing-mem-err.$$
|
|
printf '{"ok":false,"error":"podman exec failed: %s"}\n' "${err//\"/\'}"
|
|
exit 1
|
|
fi
|
|
rm -f /tmp/landing-mem-err.$$
|
|
|
|
# Validate JSON
|
|
if ! printf '%s' "$raw" | python3 -c 'import json,sys; json.load(sys.stdin)' 2>/dev/null; then
|
|
printf '{"ok":false,"error":"invalid json from container"}\n'
|
|
exit 1
|
|
fi
|
|
|
|
if [ -n "$OUT" ]; then
|
|
printf '%s\n' "$raw" >"$OUT"
|
|
fi
|
|
printf '%s\n' "$raw"
|