Add scripts/system_health_report.sh
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Generate a concise system health report for Linux servers.
|
||||
#
|
||||
# This script is useful for incident triage, routine maintenance, and
|
||||
# collecting baseline information before deployments or infrastructure changes.
|
||||
#
|
||||
# Usage:
|
||||
# bash system_health_report.sh
|
||||
# bash system_health_report.sh --output /tmp/health-report.txt
|
||||
# bash system_health_report.sh --service nginx --service docker
|
||||
#
|
||||
# Options:
|
||||
# --output FILE Write the report to FILE instead of stdout.
|
||||
# --service NAME Include systemd status for a service. Can be repeated.
|
||||
# --help Show this help message.
|
||||
|
||||
set -Eeuo pipefail
|
||||
|
||||
output_file=""
|
||||
services=()
|
||||
|
||||
usage() {
|
||||
sed -n '2,18p' "$0" | sed 's/^# \{0,1\}//'
|
||||
}
|
||||
|
||||
require_command() {
|
||||
local command_name="$1"
|
||||
if ! command -v "$command_name" >/dev/null 2>&1; then
|
||||
printf 'ERROR: required command not found: %s\n' "$command_name" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
section() {
|
||||
printf '\n## %s\n' "$1"
|
||||
}
|
||||
|
||||
collect_report() {
|
||||
section "Host"
|
||||
printf 'Hostname: %s\n' "$(hostname -f 2>/dev/null || hostname)"
|
||||
printf 'Kernel: %s\n' "$(uname -srmo)"
|
||||
printf 'Uptime: %s\n' "$(uptime -p 2>/dev/null || uptime)"
|
||||
printf 'Date: %s\n' "$(date -Is)"
|
||||
|
||||
section "CPU"
|
||||
if command -v lscpu >/dev/null 2>&1; then
|
||||
lscpu | awk -F: '/Model name|CPU\(s\)|Thread|Core|Socket/ {gsub(/^[ \t]+/, "", $2); print $1 ": " $2}'
|
||||
else
|
||||
grep -m1 'model name' /proc/cpuinfo || true
|
||||
fi
|
||||
printf 'Load average: %s\n' "$(awk '{print $1, $2, $3}' /proc/loadavg)"
|
||||
|
||||
section "Memory"
|
||||
free -h
|
||||
|
||||
section "Disk"
|
||||
df -hT -x tmpfs -x devtmpfs
|
||||
|
||||
section "Network"
|
||||
ip -brief address 2>/dev/null || hostname -I || true
|
||||
|
||||
section "Top Processes By Memory"
|
||||
ps -eo pid,ppid,comm,%mem,%cpu --sort=-%mem | head -n 11
|
||||
|
||||
if [[ "${#services[@]}" -gt 0 ]]; then
|
||||
section "Service Status"
|
||||
for service in "${services[@]}"; do
|
||||
printf '\nService: %s\n' "$service"
|
||||
systemctl is-active "$service" 2>/dev/null || true
|
||||
systemctl --no-pager --lines=5 status "$service" 2>/dev/null || true
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--output)
|
||||
output_file="${2:-}"
|
||||
[[ -n "$output_file" ]] || { printf 'ERROR: --output requires a file path.\n' >&2; exit 1; }
|
||||
shift 2
|
||||
;;
|
||||
--service)
|
||||
[[ -n "${2:-}" ]] || { printf 'ERROR: --service requires a service name.\n' >&2; exit 1; }
|
||||
services+=("$2")
|
||||
shift 2
|
||||
;;
|
||||
--help|-h)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
printf 'ERROR: unknown option: %s\n' "$1" >&2
|
||||
usage >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
require_command free
|
||||
require_command df
|
||||
require_command ps
|
||||
|
||||
if [[ -n "$output_file" ]]; then
|
||||
collect_report > "$output_file"
|
||||
printf 'Health report written to %s\n' "$output_file"
|
||||
else
|
||||
collect_report
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user