#!/bin/bash

set -euo pipefail

# Logs load, memory usage (by process) and disk usage (in / subdirectories),
# then writes to stdout as a single JSON dict. Repeats every 5min. Script
# written by GPT4 and then tweaked.

while true; do
    # Function to retrieve memory usage as JSON string in MB
    get_memory_usage() {
      free -m | awk 'NR==2 {printf "\"total\": \"%sMB\", \"used\": \"%sMB\", \"free\": \"%sMB\"", $2, $3, $4}'
    }

    # Function to retrieve uptime and load as JSON string
    get_uptime_and_load() {
      uptime | awk '{
        gsub(",", "", $3); gsub(",", "", $4); gsub(",", "", $5);
        printf "\"uptime\": \"%s hours\", \"load_avg\": [\"%s\", \"%s\", \"%s\"]", $3, $10, $11, $12
      }'
    }

    # Function to retrieve processes information as JSON string
    get_processes_info() {
      ps -e -o comm,pid,rss | awk 'NR>1 {
        if (NR>2) printf ", ";
        # rss from ps is in KB, so we convert it to MB here
        memory_mb = $3 / 1024;
        printf "{\"name\": \"%s\", \"pid\": \"%s\", \"memory_mb\": \"%.2fMB\"}", $1, $2, memory_mb
      }'
    }

    # Function to retrieve disk usage as JSON string
    get_disk_usage() {
      du -sh /* 2>/dev/null | awk '{
        if (NR>1) printf ", ";
        printf "\"%s\": \"%s\"", $2, $1
      }'
    }

    # Combining all the JSON parts into a single line output for GCP
    echo "{ \"message\": \"Server stats for HOSTNAME=$HOSTNAME on $(date)\", \"severity\": \"INFO\", \"memory_usage\": {$(get_memory_usage)}, \"uptime_and_load\": {$(get_uptime_and_load)}, \"processes\": [$(get_processes_info)], \"disk_usage\": {$(get_disk_usage)} }"

    sleep 300
done

