517 lines
22 KiB
Bash
Executable File
517 lines
22 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# System Information Collector
|
|
# Comprehensive discovery of hardware, OS, network, and storage configuration
|
|
# Part of the Current State Discovery Framework
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
DISCOVERY_DIR="${SCRIPT_DIR}/results"
|
|
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
|
REPORT_FILE="${DISCOVERY_DIR}/system_discovery_${TIMESTAMP}.json"
|
|
|
|
# Create discovery directory
|
|
mkdir -p "$DISCOVERY_DIR"
|
|
|
|
main() {
|
|
echo "🔍 Starting system information collection..."
|
|
|
|
# Initialize JSON report
|
|
cat > "$REPORT_FILE" << 'EOF'
|
|
{
|
|
"discovery_metadata": {
|
|
"timestamp": "",
|
|
"hostname": "",
|
|
"discovery_version": "1.0"
|
|
},
|
|
"hardware": {},
|
|
"operating_system": {},
|
|
"network": {},
|
|
"storage": {},
|
|
"performance": {}
|
|
}
|
|
EOF
|
|
|
|
collect_metadata
|
|
collect_hardware_info
|
|
collect_os_info
|
|
collect_network_info
|
|
collect_storage_info
|
|
collect_performance_baseline
|
|
|
|
echo "✅ System discovery complete: $REPORT_FILE"
|
|
generate_summary
|
|
}
|
|
|
|
collect_metadata() {
|
|
echo "📋 Collecting metadata..."
|
|
|
|
jq --arg timestamp "$(date -Iseconds)" \
|
|
--arg hostname "$(hostname)" \
|
|
'.discovery_metadata.timestamp = $timestamp | .discovery_metadata.hostname = $hostname' \
|
|
"$REPORT_FILE" > "${REPORT_FILE}.tmp" && mv "${REPORT_FILE}.tmp" "$REPORT_FILE"
|
|
}
|
|
|
|
collect_hardware_info() {
|
|
echo "🖥️ Collecting hardware information..."
|
|
|
|
local cpu_info memory_info gpu_info storage_devices
|
|
|
|
# CPU Information
|
|
cpu_info=$(cat << 'EOF'
|
|
{
|
|
"model": "",
|
|
"cores": 0,
|
|
"threads": 0,
|
|
"architecture": "",
|
|
"flags": []
|
|
}
|
|
EOF
|
|
)
|
|
|
|
if [[ -f /proc/cpuinfo ]]; then
|
|
local cpu_model=$(grep "model name" /proc/cpuinfo | head -1 | cut -d: -f2 | xargs)
|
|
local cpu_cores=$(grep "cpu cores" /proc/cpuinfo | head -1 | cut -d: -f2 | xargs)
|
|
local cpu_threads=$(grep "processor" /proc/cpuinfo | wc -l)
|
|
local cpu_arch=$(uname -m)
|
|
local cpu_flags=$(grep "flags" /proc/cpuinfo | head -1 | cut -d: -f2 | xargs | tr ' ' '\n' | jq -R . | jq -s .)
|
|
|
|
cpu_info=$(echo "$cpu_info" | jq --arg model "$cpu_model" \
|
|
--argjson cores "${cpu_cores:-1}" \
|
|
--argjson threads "$cpu_threads" \
|
|
--arg arch "$cpu_arch" \
|
|
--argjson flags "$cpu_flags" \
|
|
'.model = $model | .cores = $cores | .threads = $threads | .architecture = $arch | .flags = $flags')
|
|
fi
|
|
|
|
# Memory Information
|
|
memory_info=$(cat << 'EOF'
|
|
{
|
|
"total_gb": 0,
|
|
"available_gb": 0,
|
|
"swap_gb": 0,
|
|
"details": {}
|
|
}
|
|
EOF
|
|
)
|
|
|
|
if [[ -f /proc/meminfo ]]; then
|
|
local mem_total=$(grep "MemTotal" /proc/meminfo | awk '{print int($2/1024/1024)}')
|
|
local mem_available=$(grep "MemAvailable" /proc/meminfo | awk '{print int($2/1024/1024)}')
|
|
local swap_total=$(grep "SwapTotal" /proc/meminfo | awk '{print int($2/1024/1024)}')
|
|
local mem_details=$(grep -E "(MemTotal|MemAvailable|MemFree|Buffers|Cached|SwapTotal)" /proc/meminfo |
|
|
awk '{print "\"" tolower($1) "\":" int($2)}' | tr '\n' ',' | sed 's/,$//' | sed 's/://g')
|
|
|
|
memory_info=$(echo "$memory_info" | jq --argjson total "$mem_total" \
|
|
--argjson available "$mem_available" \
|
|
--argjson swap "$swap_total" \
|
|
--argjson details "{$mem_details}" \
|
|
'.total_gb = $total | .available_gb = $available | .swap_gb = $swap | .details = $details')
|
|
fi
|
|
|
|
# GPU Information
|
|
gpu_info='[]'
|
|
|
|
# Check for NVIDIA GPUs
|
|
if command -v nvidia-smi &>/dev/null; then
|
|
local nvidia_gpus=$(nvidia-smi --query-gpu=name,memory.total --format=csv,noheader,nounits 2>/dev/null |
|
|
awk -F',' '{print "{\"name\":\"" $1 "\",\"memory_mb\":" $2 ",\"vendor\":\"NVIDIA\"}"}' |
|
|
jq -s .)
|
|
gpu_info=$(echo "$gpu_info" | jq ". + $nvidia_gpus")
|
|
fi
|
|
|
|
# Check for AMD/Intel GPUs via lspci
|
|
local other_gpus=$(lspci | grep -i vga |
|
|
awk '{print "{\"name\":\"" substr($0, index($0,$5)) "\",\"vendor\":\"" $4 "\",\"detected_via\":\"lspci\"}"}' |
|
|
jq -s .)
|
|
gpu_info=$(echo "$gpu_info" | jq ". + $other_gpus")
|
|
|
|
# Storage Devices
|
|
storage_devices='[]'
|
|
|
|
if command -v lsblk &>/dev/null; then
|
|
# Get block devices with detailed info
|
|
while IFS= read -r line; do
|
|
if [[ "$line" =~ ^([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]*)[[:space:]]+([^[:space:]]*) ]]; then
|
|
local device="${BASH_REMATCH[1]}"
|
|
local size="${BASH_REMATCH[2]}"
|
|
local type="${BASH_REMATCH[3]}"
|
|
local mountpoint="${BASH_REMATCH[4]}"
|
|
local fstype="${BASH_REMATCH[5]}"
|
|
|
|
# Check if it's rotational (HDD vs SSD)
|
|
local rotational="unknown"
|
|
if [[ -f "/sys/block/$device/queue/rotational" ]]; then
|
|
if [[ $(cat "/sys/block/$device/queue/rotational" 2>/dev/null) == "0" ]]; then
|
|
rotational="ssd"
|
|
else
|
|
rotational="hdd"
|
|
fi
|
|
fi
|
|
|
|
local device_info=$(jq -n --arg name "$device" \
|
|
--arg size "$size" \
|
|
--arg type "$type" \
|
|
--arg mount "$mountpoint" \
|
|
--arg fs "$fstype" \
|
|
--arg rotation "$rotational" \
|
|
'{name: $name, size: $size, type: $type, mountpoint: $mount, filesystem: $fs, storage_type: $rotation}')
|
|
|
|
storage_devices=$(echo "$storage_devices" | jq ". + [$device_info]")
|
|
fi
|
|
done < <(lsblk -o NAME,SIZE,TYPE,MOUNTPOINT,FSTYPE --noheadings | grep -E "^[a-z]")
|
|
fi
|
|
|
|
# Combine hardware info
|
|
local hardware_data=$(jq -n --argjson cpu "$cpu_info" \
|
|
--argjson memory "$memory_info" \
|
|
--argjson gpu "$gpu_info" \
|
|
--argjson storage "$storage_devices" \
|
|
'{cpu: $cpu, memory: $memory, gpu: $gpu, storage: $storage}')
|
|
|
|
jq --argjson hardware "$hardware_data" '.hardware = $hardware' "$REPORT_FILE" > "${REPORT_FILE}.tmp" && mv "${REPORT_FILE}.tmp" "$REPORT_FILE"
|
|
}
|
|
|
|
collect_os_info() {
|
|
echo "🐧 Collecting operating system information..."
|
|
|
|
local os_info=$(cat << 'EOF'
|
|
{
|
|
"distribution": "",
|
|
"version": "",
|
|
"kernel": "",
|
|
"architecture": "",
|
|
"installed_packages": [],
|
|
"running_services": [],
|
|
"firewall_status": ""
|
|
}
|
|
EOF
|
|
)
|
|
|
|
# OS Distribution and Version
|
|
local distro="Unknown"
|
|
local version="Unknown"
|
|
|
|
if [[ -f /etc/os-release ]]; then
|
|
distro=$(grep "^NAME=" /etc/os-release | cut -d'"' -f2)
|
|
version=$(grep "^VERSION=" /etc/os-release | cut -d'"' -f2)
|
|
fi
|
|
|
|
local kernel=$(uname -r)
|
|
local arch=$(uname -m)
|
|
|
|
# Installed packages (limit to essential packages to avoid huge lists)
|
|
local packages='[]'
|
|
if command -v dpkg &>/dev/null; then
|
|
packages=$(dpkg -l | grep "^ii" | awk '{print $2}' | grep -E "(docker|nginx|apache|mysql|postgresql|redis|nodejs|python)" | jq -R . | jq -s .)
|
|
elif command -v rpm &>/dev/null; then
|
|
packages=$(rpm -qa | grep -E "(docker|nginx|apache|mysql|postgresql|redis|nodejs|python)" | jq -R . | jq -s .)
|
|
fi
|
|
|
|
# Running services
|
|
local services='[]'
|
|
if command -v systemctl &>/dev/null; then
|
|
services=$(systemctl list-units --type=service --state=active --no-pager --no-legend |
|
|
awk '{print $1}' | sed 's/.service$//' | head -20 | jq -R . | jq -s .)
|
|
fi
|
|
|
|
# Firewall status
|
|
local firewall_status="unknown"
|
|
if command -v ufw &>/dev/null; then
|
|
if ufw status | grep -q "Status: active"; then
|
|
firewall_status="ufw_active"
|
|
else
|
|
firewall_status="ufw_inactive"
|
|
fi
|
|
elif command -v firewall-cmd &>/dev/null; then
|
|
if firewall-cmd --state 2>/dev/null | grep -q "running"; then
|
|
firewall_status="firewalld_active"
|
|
else
|
|
firewall_status="firewalld_inactive"
|
|
fi
|
|
fi
|
|
|
|
os_info=$(echo "$os_info" | jq --arg distro "$distro" \
|
|
--arg version "$version" \
|
|
--arg kernel "$kernel" \
|
|
--arg arch "$arch" \
|
|
--argjson packages "$packages" \
|
|
--argjson services "$services" \
|
|
--arg firewall "$firewall_status" \
|
|
'.distribution = $distro | .version = $version | .kernel = $kernel | .architecture = $arch | .installed_packages = $packages | .running_services = $services | .firewall_status = $firewall')
|
|
|
|
jq --argjson os "$os_info" '.operating_system = $os' "$REPORT_FILE" > "${REPORT_FILE}.tmp" && mv "${REPORT_FILE}.tmp" "$REPORT_FILE"
|
|
}
|
|
|
|
collect_network_info() {
|
|
echo "🌐 Collecting network configuration..."
|
|
|
|
local network_info=$(cat << 'EOF'
|
|
{
|
|
"interfaces": [],
|
|
"routing": [],
|
|
"dns_config": {},
|
|
"open_ports": [],
|
|
"docker_networks": []
|
|
}
|
|
EOF
|
|
)
|
|
|
|
# Network interfaces
|
|
local interfaces='[]'
|
|
if command -v ip &>/dev/null; then
|
|
while IFS= read -r line; do
|
|
if [[ "$line" =~ ^[0-9]+:[[:space:]]+([^:]+): ]]; then
|
|
local iface="${BASH_REMATCH[1]}"
|
|
local ip_addr=$(ip addr show "$iface" 2>/dev/null | grep "inet " | head -1 | awk '{print $2}' || echo "")
|
|
local state=$(ip link show "$iface" 2>/dev/null | head -1 | grep -o "state [A-Z]*" | cut -d' ' -f2 || echo "UNKNOWN")
|
|
|
|
local iface_info=$(jq -n --arg name "$iface" --arg ip "$ip_addr" --arg state "$state" \
|
|
'{name: $name, ip_address: $ip, state: $state}')
|
|
interfaces=$(echo "$interfaces" | jq ". + [$iface_info]")
|
|
fi
|
|
done < <(ip link show)
|
|
fi
|
|
|
|
# Routing table
|
|
local routing='[]'
|
|
if command -v ip &>/dev/null; then
|
|
while IFS= read -r line; do
|
|
local route_info=$(echo "$line" | jq -R .)
|
|
routing=$(echo "$routing" | jq ". + [$route_info]")
|
|
done < <(ip route show | head -10)
|
|
fi
|
|
|
|
# DNS configuration
|
|
local dns_config='{}'
|
|
if [[ -f /etc/resolv.conf ]]; then
|
|
local nameservers=$(grep "nameserver" /etc/resolv.conf | awk '{print $2}' | jq -R . | jq -s .)
|
|
local domain=$(grep "domain\|search" /etc/resolv.conf | head -1 | awk '{print $2}' || echo "")
|
|
dns_config=$(jq -n --argjson nameservers "$nameservers" --arg domain "$domain" \
|
|
'{nameservers: $nameservers, domain: $domain}')
|
|
fi
|
|
|
|
# Open ports
|
|
local open_ports='[]'
|
|
if command -v ss &>/dev/null; then
|
|
while IFS= read -r line; do
|
|
local port_info=$(echo "$line" | jq -R .)
|
|
open_ports=$(echo "$open_ports" | jq ". + [$port_info]")
|
|
done < <(ss -tuln | grep LISTEN | head -20)
|
|
elif command -v netstat &>/dev/null; then
|
|
while IFS= read -r line; do
|
|
local port_info=$(echo "$line" | jq -R .)
|
|
open_ports=$(echo "$open_ports" | jq ". + [$port_info]")
|
|
done < <(netstat -tuln | grep LISTEN | head -20)
|
|
fi
|
|
|
|
# Docker networks
|
|
local docker_networks='[]'
|
|
if command -v docker &>/dev/null && docker info &>/dev/null; then
|
|
while IFS= read -r line; do
|
|
local network_info=$(echo "$line" | jq -R . | jq 'split(" ") | {name: .[0], id: .[1], driver: .[2], scope: .[3]}')
|
|
docker_networks=$(echo "$docker_networks" | jq ". + [$network_info]")
|
|
done < <(docker network ls --format "{{.Name}} {{.ID}} {{.Driver}} {{.Scope}}" 2>/dev/null || echo "")
|
|
fi
|
|
|
|
network_info=$(echo "$network_info" | jq --argjson interfaces "$interfaces" \
|
|
--argjson routing "$routing" \
|
|
--argjson dns "$dns_config" \
|
|
--argjson ports "$open_ports" \
|
|
--argjson docker_nets "$docker_networks" \
|
|
'.interfaces = $interfaces | .routing = $routing | .dns_config = $dns | .open_ports = $ports | .docker_networks = $docker_nets')
|
|
|
|
jq --argjson network "$network_info" '.network = $network' "$REPORT_FILE" > "${REPORT_FILE}.tmp" && mv "${REPORT_FILE}.tmp" "$REPORT_FILE"
|
|
}
|
|
|
|
collect_storage_info() {
|
|
echo "💾 Collecting storage information..."
|
|
|
|
local storage_info=$(cat << 'EOF'
|
|
{
|
|
"filesystems": [],
|
|
"disk_usage": [],
|
|
"mount_points": [],
|
|
"docker_volumes": []
|
|
}
|
|
EOF
|
|
)
|
|
|
|
# Filesystem information
|
|
local filesystems='[]'
|
|
while IFS= read -r line; do
|
|
local fs_info=$(echo "$line" | awk '{print "{\"filesystem\":\"" $1 "\",\"size\":\"" $2 "\",\"used\":\"" $3 "\",\"available\":\"" $4 "\",\"use_percent\":\"" $5 "\",\"mount\":\"" $6 "\"}"}' | jq .)
|
|
filesystems=$(echo "$filesystems" | jq ". + [$fs_info]")
|
|
done < <(df -h | grep -E "^/dev")
|
|
|
|
# Disk usage for important directories
|
|
local disk_usage='[]'
|
|
local important_dirs=("/home" "/var" "/opt" "/usr" "/etc")
|
|
for dir in "${important_dirs[@]}"; do
|
|
if [[ -d "$dir" ]]; then
|
|
local usage=$(du -sh "$dir" 2>/dev/null | awk '{print $1}' || echo "unknown")
|
|
local usage_info=$(jq -n --arg dir "$dir" --arg size "$usage" '{directory: $dir, size: $size}')
|
|
disk_usage=$(echo "$disk_usage" | jq ". + [$usage_info]")
|
|
fi
|
|
done
|
|
|
|
# Mount points with options
|
|
local mount_points='[]'
|
|
while IFS= read -r line; do
|
|
if [[ "$line" =~ ^([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]+) ]]; then
|
|
local device="${BASH_REMATCH[1]}"
|
|
local mount="${BASH_REMATCH[2]}"
|
|
local fstype="${BASH_REMATCH[3]}"
|
|
local options="${BASH_REMATCH[4]}"
|
|
|
|
local mount_info=$(jq -n --arg device "$device" --arg mount "$mount" --arg fstype "$fstype" --arg opts "$options" \
|
|
'{device: $device, mountpoint: $mount, filesystem: $fstype, options: $opts}')
|
|
mount_points=$(echo "$mount_points" | jq ". + [$mount_info]")
|
|
fi
|
|
done < <(cat /proc/mounts | grep -E "^/dev")
|
|
|
|
# Docker volumes
|
|
local docker_volumes='[]'
|
|
if command -v docker &>/dev/null && docker info &>/dev/null; then
|
|
while IFS= read -r line; do
|
|
local vol_name=$(echo "$line" | awk '{print $1}')
|
|
local vol_driver=$(echo "$line" | awk '{print $2}')
|
|
local vol_mountpoint=$(docker volume inspect "$vol_name" --format '{{.Mountpoint}}' 2>/dev/null || echo "unknown")
|
|
local vol_size=$(du -sh "$vol_mountpoint" 2>/dev/null | awk '{print $1}' || echo "unknown")
|
|
|
|
local vol_info=$(jq -n --arg name "$vol_name" --arg driver "$vol_driver" --arg mount "$vol_mountpoint" --arg size "$vol_size" \
|
|
'{name: $name, driver: $driver, mountpoint: $mount, size: $size}')
|
|
docker_volumes=$(echo "$docker_volumes" | jq ". + [$vol_info]")
|
|
done < <(docker volume ls --format "{{.Name}} {{.Driver}}" 2>/dev/null || echo "")
|
|
fi
|
|
|
|
storage_info=$(echo "$storage_info" | jq --argjson filesystems "$filesystems" \
|
|
--argjson disk_usage "$disk_usage" \
|
|
--argjson mount_points "$mount_points" \
|
|
--argjson docker_volumes "$docker_volumes" \
|
|
'.filesystems = $filesystems | .disk_usage = $disk_usage | .mount_points = $mount_points | .docker_volumes = $docker_volumes')
|
|
|
|
jq --argjson storage "$storage_info" '.storage = $storage' "$REPORT_FILE" > "${REPORT_FILE}.tmp" && mv "${REPORT_FILE}.tmp" "$REPORT_FILE"
|
|
}
|
|
|
|
collect_performance_baseline() {
|
|
echo "📊 Collecting performance baseline..."
|
|
|
|
local performance_info=$(cat << 'EOF'
|
|
{
|
|
"load_average": {},
|
|
"cpu_usage": {},
|
|
"memory_usage": {},
|
|
"disk_io": {},
|
|
"network_stats": {}
|
|
}
|
|
EOF
|
|
)
|
|
|
|
# Load average
|
|
local load_avg='{}'
|
|
if [[ -f /proc/loadavg ]]; then
|
|
local load_data=$(cat /proc/loadavg)
|
|
local load_1min=$(echo "$load_data" | awk '{print $1}')
|
|
local load_5min=$(echo "$load_data" | awk '{print $2}')
|
|
local load_15min=$(echo "$load_data" | awk '{print $3}')
|
|
load_avg=$(jq -n --arg l1 "$load_1min" --arg l5 "$load_5min" --arg l15 "$load_15min" \
|
|
'{one_minute: $l1, five_minute: $l5, fifteen_minute: $l15}')
|
|
fi
|
|
|
|
# CPU usage snapshot
|
|
local cpu_usage='{}'
|
|
if [[ -f /proc/stat ]]; then
|
|
local cpu_line=$(grep "^cpu " /proc/stat)
|
|
cpu_usage=$(echo "$cpu_line" | awk '{print "{\"user\":" $2 ",\"nice\":" $3 ",\"system\":" $4 ",\"idle\":" $5 ",\"iowait\":" $6 "}"}' | jq .)
|
|
fi
|
|
|
|
# Memory usage
|
|
local memory_usage='{}'
|
|
if [[ -f /proc/meminfo ]]; then
|
|
local mem_total=$(grep "MemTotal" /proc/meminfo | awk '{print $2}')
|
|
local mem_free=$(grep "MemFree" /proc/meminfo | awk '{print $2}')
|
|
local mem_available=$(grep "MemAvailable" /proc/meminfo | awk '{print $2}')
|
|
local mem_used=$((mem_total - mem_free))
|
|
memory_usage=$(jq -n --argjson total "$mem_total" --argjson free "$mem_free" --argjson available "$mem_available" --argjson used "$mem_used" \
|
|
'{total_kb: $total, free_kb: $free, available_kb: $available, used_kb: $used}')
|
|
fi
|
|
|
|
# Disk I/O stats
|
|
local disk_io='[]'
|
|
if [[ -f /proc/diskstats ]]; then
|
|
while IFS= read -r line; do
|
|
if [[ "$line" =~ ^[[:space:]]*[0-9]+[[:space:]]+[0-9]+[[:space:]]+([a-z]+)[[:space:]]+([0-9]+)[[:space:]]+[0-9]+[[:space:]]+([0-9]+)[[:space:]]+[0-9]+[[:space:]]+([0-9]+)[[:space:]]+[0-9]+[[:space:]]+([0-9]+) ]]; then
|
|
local device="${BASH_REMATCH[1]}"
|
|
local reads="${BASH_REMATCH[2]}"
|
|
local read_sectors="${BASH_REMATCH[3]}"
|
|
local writes="${BASH_REMATCH[4]}"
|
|
local write_sectors="${BASH_REMATCH[5]}"
|
|
|
|
# Only include main devices, not partitions
|
|
if [[ ! "$device" =~ [0-9]+$ ]]; then
|
|
local io_info=$(jq -n --arg dev "$device" --arg reads "$reads" --arg read_sectors "$read_sectors" --arg writes "$writes" --arg write_sectors "$write_sectors" \
|
|
'{device: $dev, reads: $reads, read_sectors: $read_sectors, writes: $writes, write_sectors: $write_sectors}')
|
|
disk_io=$(echo "$disk_io" | jq ". + [$io_info]")
|
|
fi
|
|
fi
|
|
done < <(cat /proc/diskstats)
|
|
fi
|
|
|
|
# Network stats
|
|
local network_stats='[]'
|
|
if [[ -f /proc/net/dev ]]; then
|
|
while IFS= read -r line; do
|
|
if [[ "$line" =~ ^[[:space:]]*([^:]+):[[:space:]]*([0-9]+)[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+([0-9]+) ]]; then
|
|
local interface="${BASH_REMATCH[1]}"
|
|
local rx_bytes="${BASH_REMATCH[2]}"
|
|
local tx_bytes="${BASH_REMATCH[3]}"
|
|
|
|
# Skip loopback
|
|
if [[ "$interface" != "lo" ]]; then
|
|
local net_info=$(jq -n --arg iface "$interface" --arg rx "$rx_bytes" --arg tx "$tx_bytes" \
|
|
'{interface: $iface, rx_bytes: $rx, tx_bytes: $tx}')
|
|
network_stats=$(echo "$network_stats" | jq ". + [$net_info]")
|
|
fi
|
|
fi
|
|
done < <(tail -n +3 /proc/net/dev)
|
|
fi
|
|
|
|
performance_info=$(echo "$performance_info" | jq --argjson load "$load_avg" \
|
|
--argjson cpu "$cpu_usage" \
|
|
--argjson memory "$memory_usage" \
|
|
--argjson disk_io "$disk_io" \
|
|
--argjson network "$network_stats" \
|
|
'.load_average = $load | .cpu_usage = $cpu | .memory_usage = $memory | .disk_io = $disk_io | .network_stats = $network')
|
|
|
|
jq --argjson performance "$performance_info" '.performance = $performance' "$REPORT_FILE" > "${REPORT_FILE}.tmp" && mv "${REPORT_FILE}.tmp" "$REPORT_FILE"
|
|
}
|
|
|
|
generate_summary() {
|
|
echo ""
|
|
echo "📋 SYSTEM DISCOVERY SUMMARY"
|
|
echo "=========================="
|
|
|
|
# Extract key information for summary
|
|
local hostname=$(jq -r '.discovery_metadata.hostname' "$REPORT_FILE")
|
|
local cpu_model=$(jq -r '.hardware.cpu.model' "$REPORT_FILE")
|
|
local memory_gb=$(jq -r '.hardware.memory.total_gb' "$REPORT_FILE")
|
|
local os_distro=$(jq -r '.operating_system.distribution' "$REPORT_FILE")
|
|
local storage_count=$(jq '.hardware.storage | length' "$REPORT_FILE")
|
|
local network_interfaces=$(jq '.network.interfaces | length' "$REPORT_FILE")
|
|
local docker_containers=$(jq '.network.docker_networks | length' "$REPORT_FILE")
|
|
|
|
echo "Hostname: $hostname"
|
|
echo "CPU: $cpu_model"
|
|
echo "Memory: ${memory_gb}GB"
|
|
echo "OS: $os_distro"
|
|
echo "Storage Devices: $storage_count"
|
|
echo "Network Interfaces: $network_interfaces"
|
|
echo "Docker Networks: $docker_containers"
|
|
echo ""
|
|
echo "Full report: $REPORT_FILE"
|
|
echo "Next: Run service_inventory_collector.sh"
|
|
}
|
|
|
|
# Execute main function
|
|
main "$@" |