feat(skills): add self-improving and system-monitor skills
self-improving: adapted from ClawHub's top skill (pskoett/self-improving-agent). Logs errors, corrections, and learnings to skills/self-improving/data/. Promotes important patterns to MEMORY.md for cross-session persistence. system-monitor: health check for Armbian STB/server. Monitors CPU temp, RAM, disk, load, and network connectivity. health_alert.sh sends ntfy push only when thresholds are breached. Reuses ntfy config from reminder skill for zero extra setup.
This commit is contained in:
parent
a1c8d3c321
commit
7fc6cbea8f
7 changed files with 658 additions and 0 deletions
223
workspace/skills/self-improving/SKILL.md
Normal file
223
workspace/skills/self-improving/SKILL.md
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
---
|
||||
name: self-improving
|
||||
description: Catat kesalahan, koreksi, dan pelajaran agar agent terus belajar dari pengalaman. Otomatis aktif saat terjadi error atau user mengoreksi.
|
||||
metadata: {"nanobot":{"emoji":"🧠"}}
|
||||
---
|
||||
|
||||
# Self-Improving Agent
|
||||
|
||||
Skill ini membuat agent belajar dari kesalahan dan koreksi. Setiap error, koreksi user, atau knowledge gap dicatat ke file log, dan pelajaran penting dipromosikan ke MEMORY.md agar persisten lintas sesi.
|
||||
|
||||
> Diadaptasi dari [self-improving-agent di ClawHub](https://clawhub.ai/pskoett/self-improving-agent) untuk PicoClaw.
|
||||
|
||||
## When to use (trigger phrases)
|
||||
|
||||
Skill ini aktif **otomatis** saat agent mendeteksi situasi berikut:
|
||||
|
||||
**Kesalahan:**
|
||||
- Command gagal (non-zero exit code)
|
||||
- Error, exception, atau stack trace
|
||||
- Timeout atau connection failure
|
||||
|
||||
**Koreksi user:**
|
||||
- "Bukan, yang bener..."
|
||||
- "Salah, seharusnya..."
|
||||
- "Actually, it should be..."
|
||||
|
||||
**Knowledge gap:**
|
||||
- User kasih info yang agent belum tahu
|
||||
- Dokumentasi ternyata outdated
|
||||
- Perilaku API berbeda dari yang agent kira
|
||||
|
||||
**Feature request:**
|
||||
- "Bisa gak kamu..."
|
||||
- "Bagaimana kalau..."
|
||||
- "I wish you could..."
|
||||
|
||||
## Storage
|
||||
|
||||
Semua log disimpan di `skills/self-improving/data/`:
|
||||
|
||||
```
|
||||
skills/self-improving/data/
|
||||
├── LEARNINGS.md # Koreksi, knowledge gaps, best practices
|
||||
├── ERRORS.md # Command failures, exceptions
|
||||
└── FEATURE_REQUESTS.md # User-requested capabilities
|
||||
```
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Situasi | Aksi |
|
||||
|---------|------|
|
||||
| Command/operasi gagal | Catat ke `ERRORS.md` |
|
||||
| User mengoreksi agent | Catat ke `LEARNINGS.md` (kategori: `correction`) |
|
||||
| User minta fitur baru | Catat ke `FEATURE_REQUESTS.md` |
|
||||
| API/tool eksternal gagal | Catat ke `ERRORS.md` dengan detail integrasi |
|
||||
| Pengetahuan agent outdated | Catat ke `LEARNINGS.md` (kategori: `knowledge_gap`) |
|
||||
| Ditemukan cara yang lebih baik | Catat ke `LEARNINGS.md` (kategori: `best_practice`) |
|
||||
| Pelajaran bisa diterapkan luas | Promote ke `MEMORY.md` |
|
||||
|
||||
## Format Log
|
||||
|
||||
### Learning Entry
|
||||
|
||||
Append ke `skills/self-improving/data/LEARNINGS.md`:
|
||||
|
||||
```markdown
|
||||
## [LRN-YYYYMMDD-XXX] category
|
||||
|
||||
**Logged**: ISO-8601 timestamp
|
||||
**Priority**: low | medium | high | critical
|
||||
**Status**: pending
|
||||
|
||||
### Summary
|
||||
Satu baris ringkasan pelajaran
|
||||
|
||||
### Details
|
||||
Konteks lengkap: apa yang terjadi, apa yang salah, apa yang benar
|
||||
|
||||
### Suggested Action
|
||||
Fix atau improvement spesifik
|
||||
|
||||
### Metadata
|
||||
- Source: conversation | error | user_feedback
|
||||
- Related Files: path/to/file
|
||||
- Tags: tag1, tag2
|
||||
---
|
||||
```
|
||||
|
||||
### Error Entry
|
||||
|
||||
Append ke `skills/self-improving/data/ERRORS.md`:
|
||||
|
||||
```markdown
|
||||
## [ERR-YYYYMMDD-XXX] skill_or_command_name
|
||||
|
||||
**Logged**: ISO-8601 timestamp
|
||||
**Priority**: high
|
||||
**Status**: pending
|
||||
|
||||
### Summary
|
||||
Ringkasan singkat apa yang gagal
|
||||
|
||||
### Error
|
||||
```
|
||||
Pesan error atau output aktual
|
||||
```
|
||||
|
||||
### Context
|
||||
- Command yang dijalankan
|
||||
- Parameter yang dipakai
|
||||
- Detail environment jika relevan
|
||||
|
||||
### Suggested Fix
|
||||
Jika teridentifikasi, apa yang bisa memperbaiki ini
|
||||
|
||||
### Metadata
|
||||
- Reproducible: yes | no | unknown
|
||||
- Related Files: path/to/file
|
||||
---
|
||||
```
|
||||
|
||||
### Feature Request Entry
|
||||
|
||||
Append ke `skills/self-improving/data/FEATURE_REQUESTS.md`:
|
||||
|
||||
```markdown
|
||||
## [FEAT-YYYYMMDD-XXX] capability_name
|
||||
|
||||
**Logged**: ISO-8601 timestamp
|
||||
**Priority**: medium
|
||||
**Status**: pending
|
||||
|
||||
### Requested Capability
|
||||
Apa yang user ingin lakukan
|
||||
|
||||
### User Context
|
||||
Kenapa mereka butuh ini, masalah apa yang ingin dipecahkan
|
||||
|
||||
### Suggested Implementation
|
||||
Bagaimana ini bisa dibangun
|
||||
|
||||
### Metadata
|
||||
- Frequency: first_time | recurring
|
||||
---
|
||||
```
|
||||
|
||||
## ID Format
|
||||
|
||||
Format: `TYPE-YYYYMMDD-XXX`
|
||||
|
||||
- TYPE: `LRN` (learning), `ERR` (error), `FEAT` (feature)
|
||||
- YYYYMMDD: Tanggal saat ini
|
||||
- XXX: Nomor urut (001, 002, dst)
|
||||
|
||||
## Resolve Entry
|
||||
|
||||
Saat issue sudah diperbaiki, update entry:
|
||||
|
||||
1. Ubah `**Status**: pending` → `**Status**: resolved`
|
||||
2. Tambah blok resolusi:
|
||||
|
||||
```markdown
|
||||
### Resolution
|
||||
- **Resolved**: 2026-02-24T12:00:00Z
|
||||
- **Notes**: Penjelasan singkat apa yang dilakukan
|
||||
```
|
||||
|
||||
## Promote ke MEMORY.md
|
||||
|
||||
Saat pelajaran applicable secara luas (bukan one-off fix), promosikan ke `MEMORY.md`:
|
||||
|
||||
### Kapan Promote
|
||||
|
||||
- Pelajaran berlaku untuk banyak skill/fitur
|
||||
- Pengetahuan penting yang harus diingat lintas sesi
|
||||
- Mencegah kesalahan berulang
|
||||
- Mendokumentasikan konvensi khusus user
|
||||
|
||||
### Cara Promote
|
||||
|
||||
1. **Ringkas** pelajaran jadi rule singkat
|
||||
2. **Tambahkan** ke section yang tepat di `MEMORY.md`
|
||||
3. **Update** entry original: ubah `**Status**` → `promoted`
|
||||
|
||||
### Contoh
|
||||
|
||||
**Learning entry (verbose):**
|
||||
> PicoClaw exec tool memblokir pattern `${}` dan `> /dev/null`. Command cron harus ditulis sederhana tanpa shell metacharacters.
|
||||
|
||||
**Di MEMORY.md (ringkas):**
|
||||
```markdown
|
||||
## PicoClaw Safety Guard
|
||||
- Exec tool memblokir: `${}`, `$()`, `> /dev/null`, `source *.sh`, `sudo`, `eval`
|
||||
- Command cron harus ditulis sederhana: `bash scripts/file.sh "arg"`
|
||||
```
|
||||
|
||||
## Recurring Pattern
|
||||
|
||||
Jika mencatat pelajaran yang mirip dengan entry yang sudah ada:
|
||||
|
||||
1. **Cari dulu**: apakah sudah ada entry serupa
|
||||
2. **Link**: tambah `See Also: ERR-YYYYMMDD-XXX` di Metadata
|
||||
3. **Naikkan priority** jika issue terus berulang
|
||||
4. **Promote** jika sudah 3x berulang → masukkan ke `MEMORY.md`
|
||||
|
||||
## Periodic Review
|
||||
|
||||
Review `skills/self-improving/data/` di saat-saat natural:
|
||||
|
||||
- Sebelum mulai task besar baru
|
||||
- Setelah menyelesaikan fitur
|
||||
- Saat bekerja di area yang pernah ada masalah
|
||||
- Mingguan selama development aktif
|
||||
|
||||
## Rules
|
||||
|
||||
1. **Log segera** — konteks paling segar tepat setelah masalah terjadi
|
||||
2. **Spesifik** — agent di sesi berikutnya harus bisa memahami dengan cepat
|
||||
3. **Sertakan langkah reproduksi** — terutama untuk error
|
||||
4. **Sarankan fix konkret** — bukan sekadar "perlu investigasi"
|
||||
5. **Promote agresif** — jika ragu, masukkan ke MEMORY.md
|
||||
6. **Jangan log hal sepele** — hanya yang non-obvious dan bermanfaat
|
||||
7. **Hindari menyimpan data sensitif** — jangan log API key, password, atau data pribadi
|
||||
5
workspace/skills/self-improving/data/ERRORS.md
Normal file
5
workspace/skills/self-improving/data/ERRORS.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Errors
|
||||
|
||||
Log command failures dan exceptions di sini.
|
||||
|
||||
---
|
||||
5
workspace/skills/self-improving/data/FEATURE_REQUESTS.md
Normal file
5
workspace/skills/self-improving/data/FEATURE_REQUESTS.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Feature Requests
|
||||
|
||||
Log permintaan fitur dari user di sini.
|
||||
|
||||
---
|
||||
5
workspace/skills/self-improving/data/LEARNINGS.md
Normal file
5
workspace/skills/self-improving/data/LEARNINGS.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Learnings
|
||||
|
||||
Log koreksi, knowledge gaps, dan best practices di sini.
|
||||
|
||||
---
|
||||
119
workspace/skills/system-monitor/SKILL.md
Normal file
119
workspace/skills/system-monitor/SKILL.md
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
---
|
||||
name: system-monitor
|
||||
description: Monitor kesehatan sistem — CPU, RAM, disk, suhu, dan uptime. Kirim alert via ntfy jika ada masalah.
|
||||
metadata: {"nanobot":{"emoji":"📊"}}
|
||||
---
|
||||
|
||||
# System Monitor
|
||||
|
||||
Monitor kesehatan STB/server: CPU, RAM, disk, suhu, dan uptime. Bisa dijalankan manual atau dijadwalkan via cron tool.
|
||||
|
||||
## When to use (trigger phrases)
|
||||
|
||||
- "cek sistem" / "system status"
|
||||
- "health check" / "kesehatan server"
|
||||
- "berapa suhu CPU?" / "CPU temperature"
|
||||
- "disk penuh?" / "free disk space"
|
||||
- "RAM usage" / "memory usage"
|
||||
- "uptime" / "sudah jalan berapa lama?"
|
||||
- "monitor sistem setiap jam"
|
||||
|
||||
## Perintah Manual
|
||||
|
||||
### Health check lengkap (via exec tool)
|
||||
|
||||
```bash
|
||||
bash skills/system-monitor/scripts/health_check.sh
|
||||
```
|
||||
|
||||
Output berupa ringkasan singkat yang mudah dibaca:
|
||||
|
||||
```
|
||||
🖥️ SYSTEM HEALTH REPORT
|
||||
========================
|
||||
📅 2026-02-24 12:00 WIB
|
||||
⏱️ Uptime: 3 days, 2:15
|
||||
🔥 CPU Temp: 52°C ✅
|
||||
💻 CPU Load: 0.85 (1 core)
|
||||
🧠 RAM: 412MB / 1024MB (40%) ✅
|
||||
💾 Disk: 4.2GB / 14.5GB (29%) ✅
|
||||
🌐 Network: ✅ connected
|
||||
========================
|
||||
Status: ALL OK ✅
|
||||
```
|
||||
|
||||
### Cek komponen spesifik (via exec tool)
|
||||
|
||||
```bash
|
||||
bash skills/system-monitor/scripts/health_check.sh --cpu
|
||||
bash skills/system-monitor/scripts/health_check.sh --memory
|
||||
bash skills/system-monitor/scripts/health_check.sh --disk
|
||||
bash skills/system-monitor/scripts/health_check.sh --temp
|
||||
bash skills/system-monitor/scripts/health_check.sh --network
|
||||
```
|
||||
|
||||
## Jadwal Otomatis (via cron tool)
|
||||
|
||||
### Health report harian pagi
|
||||
|
||||
```json
|
||||
{"action": "add", "message": "📊 System Health Report", "command": "bash skills/system-monitor/scripts/health_check.sh", "cron_expr": "0 7 * * *"}
|
||||
```
|
||||
|
||||
### Monitor suhu tiap 6 jam
|
||||
|
||||
```json
|
||||
{"action": "add", "message": "🌡️ Temp check", "command": "bash skills/system-monitor/scripts/health_check.sh --temp", "every_seconds": 21600}
|
||||
```
|
||||
|
||||
### Health check + ntfy alert (pakai reminder skill)
|
||||
|
||||
Jika ingin health report dikirim ke HP juga via ntfy, buat 2 job:
|
||||
|
||||
**Job 1 — Report ke Telegram:**
|
||||
```json
|
||||
{"action": "add", "message": "📊 Daily health", "command": "bash skills/system-monitor/scripts/health_check.sh", "cron_expr": "0 7 * * *"}
|
||||
```
|
||||
|
||||
**Job 2 — Alert ke ntfy (hanya jika ada masalah):**
|
||||
```json
|
||||
{"action": "add", "message": "ntfy: health alert", "command": "bash skills/system-monitor/scripts/health_alert.sh", "every_seconds": 3600}
|
||||
```
|
||||
|
||||
Script `health_alert.sh` hanya mengirim notifikasi jika ada warning/critical.
|
||||
|
||||
## Threshold (Default)
|
||||
|
||||
| Metrik | Warning | Critical |
|
||||
|--------|---------|----------|
|
||||
| CPU Temp | > 70°C | > 80°C |
|
||||
| RAM Usage | > 80% | > 90% |
|
||||
| Disk Usage | > 80% | > 90% |
|
||||
| CPU Load (1-min) | > 2.0 | > 4.0 |
|
||||
|
||||
Threshold bisa dikustomisasi di `skills/system-monitor/data/config`.
|
||||
|
||||
## Custom Config
|
||||
|
||||
Buat `skills/system-monitor/data/config` jika ingin override default:
|
||||
|
||||
```bash
|
||||
mkdir -p skills/system-monitor/data
|
||||
cat > skills/system-monitor/data/config << 'ENDCONF'
|
||||
TEMP_WARN=65
|
||||
TEMP_CRIT=75
|
||||
RAM_WARN=85
|
||||
RAM_CRIT=95
|
||||
DISK_WARN=85
|
||||
DISK_CRIT=95
|
||||
LOAD_WARN=3.0
|
||||
LOAD_CRIT=5.0
|
||||
ENDCONF
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
1. **Prefer script** — selalu gunakan `health_check.sh`, jangan `top` atau `htop` (bisa hang).
|
||||
2. **Jangan pakai `-f` flag** — streaming command tidak cocok untuk exec tool.
|
||||
3. **Alert cukup summary** — jangan dump output panjang, cukup status singkat.
|
||||
4. **Kombinasikan dengan ntfy** — gunakan `health_alert.sh` untuk push notification saat ada masalah.
|
||||
112
workspace/skills/system-monitor/scripts/health_alert.sh
Executable file
112
workspace/skills/system-monitor/scripts/health_alert.sh
Executable file
|
|
@ -0,0 +1,112 @@
|
|||
#!/bin/bash
|
||||
# health_alert.sh — Send ntfy alert ONLY if system has warning/critical issues
|
||||
# Does nothing if everything is OK (silent success).
|
||||
# Designed to be called from cron every hour.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
CONF_FILE="$SKILL_DIR/data/config"
|
||||
|
||||
# Defaults
|
||||
TEMP_WARN=70
|
||||
TEMP_CRIT=80
|
||||
RAM_WARN=80
|
||||
RAM_CRIT=90
|
||||
DISK_WARN=80
|
||||
DISK_CRIT=90
|
||||
|
||||
if [ -f "$CONF_FILE" ]; then
|
||||
. "$CONF_FILE"
|
||||
fi
|
||||
|
||||
# Detect issues
|
||||
alerts=""
|
||||
priority="default"
|
||||
tags="computer"
|
||||
|
||||
# Check CPU temp
|
||||
if [ -f /sys/class/thermal/thermal_zone0/temp ]; then
|
||||
raw=$(cat /sys/class/thermal/thermal_zone0/temp)
|
||||
temp=$((raw / 1000))
|
||||
if [ "$temp" -ge "$TEMP_CRIT" ]; then
|
||||
alerts="$alerts 🔥 CPU: ${temp}°C CRITICAL!"
|
||||
priority="urgent"
|
||||
tags="fire,$tags"
|
||||
elif [ "$temp" -ge "$TEMP_WARN" ]; then
|
||||
alerts="$alerts 🔥 CPU: ${temp}°C warning"
|
||||
priority="high"
|
||||
tags="warning,$tags"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check RAM
|
||||
mem_info=$(free -m 2>/dev/null | grep Mem)
|
||||
if [ -n "$mem_info" ]; then
|
||||
total=$(echo "$mem_info" | awk '{print $2}')
|
||||
used=$(echo "$mem_info" | awk '{print $3}')
|
||||
if [ "$total" -gt 0 ]; then
|
||||
pct=$((used * 100 / total))
|
||||
if [ "$pct" -ge "$RAM_CRIT" ]; then
|
||||
alerts="$alerts 🧠 RAM: ${pct}% CRITICAL!"
|
||||
priority="urgent"
|
||||
elif [ "$pct" -ge "$RAM_WARN" ]; then
|
||||
alerts="$alerts 🧠 RAM: ${pct}% warning"
|
||||
[ "$priority" = "default" ] && priority="high"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check disk
|
||||
disk_pct=$(df / 2>/dev/null | tail -1 | awk '{print $5}' | tr -d '%')
|
||||
if [ -n "$disk_pct" ]; then
|
||||
if [ "$disk_pct" -ge "$DISK_CRIT" ]; then
|
||||
alerts="$alerts 💾 Disk: ${disk_pct}% CRITICAL!"
|
||||
priority="urgent"
|
||||
elif [ "$disk_pct" -ge "$DISK_WARN" ]; then
|
||||
alerts="$alerts 💾 Disk: ${disk_pct}% warning"
|
||||
[ "$priority" = "default" ] && priority="high"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check network
|
||||
if ! ping -c 1 -W 3 8.8.8.8 > /dev/null 2>&1; then
|
||||
alerts="$alerts 🌐 Network: disconnected!"
|
||||
[ "$priority" = "default" ] && priority="high"
|
||||
fi
|
||||
|
||||
# Exit silently if no issues
|
||||
if [ -z "$alerts" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Find ntfy config (check reminder skill's config)
|
||||
NTFY_TOPIC=""
|
||||
REMINDER_CONF="$SKILL_DIR/../reminder/data/ntfy.conf"
|
||||
if [ -f "$REMINDER_CONF" ]; then
|
||||
. "$REMINDER_CONF"
|
||||
fi
|
||||
|
||||
# Also check own config
|
||||
OWN_NTFY="$SKILL_DIR/data/ntfy.conf"
|
||||
if [ -f "$OWN_NTFY" ]; then
|
||||
. "$OWN_NTFY"
|
||||
fi
|
||||
|
||||
if [ -z "$NTFY_TOPIC" ]; then
|
||||
# No ntfy configured — just print to stdout (goes to Telegram via cron)
|
||||
echo "⚠️ SYSTEM ALERT:$alerts"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Send via ntfy
|
||||
HOSTNAME_STR=$(hostname 2>/dev/null || echo "STB")
|
||||
eval curl -sf \
|
||||
-H "\"Title: System Alert - $HOSTNAME_STR\"" \
|
||||
-H "\"Priority: $priority\"" \
|
||||
-H "\"Tags: $tags\"" \
|
||||
-d "\"$alerts\"" \
|
||||
"\"$NTFY_TOPIC\"" || true
|
||||
|
||||
echo "⚠️ SYSTEM ALERT (sent to ntfy):$alerts"
|
||||
189
workspace/skills/system-monitor/scripts/health_check.sh
Executable file
189
workspace/skills/system-monitor/scripts/health_check.sh
Executable file
|
|
@ -0,0 +1,189 @@
|
|||
#!/bin/bash
|
||||
# health_check.sh — System health check for PicoClaw STB/server
|
||||
# Usage:
|
||||
# bash skills/system-monitor/scripts/health_check.sh # Full report
|
||||
# bash skills/system-monitor/scripts/health_check.sh --cpu # CPU only
|
||||
# bash skills/system-monitor/scripts/health_check.sh --memory # RAM only
|
||||
# bash skills/system-monitor/scripts/health_check.sh --disk # Disk only
|
||||
# bash skills/system-monitor/scripts/health_check.sh --temp # Temperature only
|
||||
# bash skills/system-monitor/scripts/health_check.sh --network # Network only
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Load config if exists
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
SKILL_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
CONF_FILE="$SKILL_DIR/data/config"
|
||||
|
||||
# Defaults
|
||||
TEMP_WARN=70
|
||||
TEMP_CRIT=80
|
||||
RAM_WARN=80
|
||||
RAM_CRIT=90
|
||||
DISK_WARN=80
|
||||
DISK_CRIT=90
|
||||
LOAD_WARN=2.0
|
||||
LOAD_CRIT=4.0
|
||||
|
||||
if [ -f "$CONF_FILE" ]; then
|
||||
. "$CONF_FILE"
|
||||
fi
|
||||
|
||||
# Helper: status icon
|
||||
status_icon() {
|
||||
local val=$1 warn=$2 crit=$3
|
||||
if [ "$(echo "$val >= $crit" | bc -l 2>/dev/null || echo 0)" = "1" ]; then
|
||||
echo "🔴"
|
||||
elif [ "$(echo "$val >= $warn" | bc -l 2>/dev/null || echo 0)" = "1" ]; then
|
||||
echo "🟡"
|
||||
else
|
||||
echo "✅"
|
||||
fi
|
||||
}
|
||||
|
||||
# Components
|
||||
get_uptime() {
|
||||
uptime_str=$(uptime -p 2>/dev/null || uptime | sed 's/.*up /up /' | sed 's/,.*load.*//')
|
||||
echo "$uptime_str"
|
||||
}
|
||||
|
||||
get_cpu_temp() {
|
||||
temp=""
|
||||
if [ -f /sys/class/thermal/thermal_zone0/temp ]; then
|
||||
raw=$(cat /sys/class/thermal/thermal_zone0/temp)
|
||||
temp=$(echo "$raw / 1000" | bc 2>/dev/null || echo "$((raw / 1000))")
|
||||
fi
|
||||
if [ -z "$temp" ]; then
|
||||
echo "N/A"
|
||||
return
|
||||
fi
|
||||
icon=$(status_icon "$temp" "$TEMP_WARN" "$TEMP_CRIT")
|
||||
echo "${temp}°C $icon"
|
||||
}
|
||||
|
||||
get_cpu_load() {
|
||||
load=$(cat /proc/loadavg 2>/dev/null | awk '{print $1}')
|
||||
if [ -z "$load" ]; then
|
||||
load=$(uptime | grep -oP 'load average: \K[^,]+' 2>/dev/null || echo "N/A")
|
||||
fi
|
||||
cores=$(nproc 2>/dev/null || echo 1)
|
||||
if [ "$load" != "N/A" ]; then
|
||||
icon=$(status_icon "$load" "$LOAD_WARN" "$LOAD_CRIT")
|
||||
echo "$load ($cores core) $icon"
|
||||
else
|
||||
echo "N/A"
|
||||
fi
|
||||
}
|
||||
|
||||
get_memory() {
|
||||
mem_info=$(free -m 2>/dev/null | grep Mem)
|
||||
if [ -z "$mem_info" ]; then
|
||||
echo "N/A"
|
||||
return
|
||||
fi
|
||||
total=$(echo "$mem_info" | awk '{print $2}')
|
||||
used=$(echo "$mem_info" | awk '{print $3}')
|
||||
if [ "$total" -gt 0 ]; then
|
||||
pct=$((used * 100 / total))
|
||||
else
|
||||
pct=0
|
||||
fi
|
||||
icon=$(status_icon "$pct" "$RAM_WARN" "$RAM_CRIT")
|
||||
echo "${used}MB / ${total}MB (${pct}%) $icon"
|
||||
}
|
||||
|
||||
get_disk() {
|
||||
disk_info=$(df -h / 2>/dev/null | tail -1)
|
||||
if [ -z "$disk_info" ]; then
|
||||
echo "N/A"
|
||||
return
|
||||
fi
|
||||
used=$(echo "$disk_info" | awk '{print $3}')
|
||||
total=$(echo "$disk_info" | awk '{print $2}')
|
||||
pct_raw=$(echo "$disk_info" | awk '{print $5}' | tr -d '%')
|
||||
icon=$(status_icon "$pct_raw" "$DISK_WARN" "$DISK_CRIT")
|
||||
echo "${used} / ${total} (${pct_raw}%) $icon"
|
||||
}
|
||||
|
||||
get_network() {
|
||||
if ping -c 1 -W 3 8.8.8.8 > /dev/null 2>&1; then
|
||||
echo "✅ connected"
|
||||
else
|
||||
echo "🔴 disconnected"
|
||||
fi
|
||||
}
|
||||
|
||||
# Get overall status
|
||||
get_overall_status() {
|
||||
local has_warning=false has_critical=false
|
||||
|
||||
# Check temp
|
||||
if [ -f /sys/class/thermal/thermal_zone0/temp ]; then
|
||||
raw=$(cat /sys/class/thermal/thermal_zone0/temp)
|
||||
temp=$((raw / 1000))
|
||||
[ "$temp" -ge "$TEMP_CRIT" ] && has_critical=true
|
||||
[ "$temp" -ge "$TEMP_WARN" ] && has_warning=true
|
||||
fi
|
||||
|
||||
# Check RAM
|
||||
mem_info=$(free -m 2>/dev/null | grep Mem)
|
||||
if [ -n "$mem_info" ]; then
|
||||
total=$(echo "$mem_info" | awk '{print $2}')
|
||||
used=$(echo "$mem_info" | awk '{print $3}')
|
||||
if [ "$total" -gt 0 ]; then
|
||||
pct=$((used * 100 / total))
|
||||
[ "$pct" -ge "$RAM_CRIT" ] && has_critical=true
|
||||
[ "$pct" -ge "$RAM_WARN" ] && has_warning=true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check disk
|
||||
disk_pct=$(df / 2>/dev/null | tail -1 | awk '{print $5}' | tr -d '%')
|
||||
if [ -n "$disk_pct" ]; then
|
||||
[ "$disk_pct" -ge "$DISK_CRIT" ] && has_critical=true
|
||||
[ "$disk_pct" -ge "$DISK_WARN" ] && has_warning=true
|
||||
fi
|
||||
|
||||
if [ "$has_critical" = true ]; then
|
||||
echo "CRITICAL 🔴"
|
||||
elif [ "$has_warning" = true ]; then
|
||||
echo "WARNING 🟡"
|
||||
else
|
||||
echo "ALL OK ✅"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main
|
||||
MODE="${1:-full}"
|
||||
DATE_STR=$(date '+%Y-%m-%d %H:%M %Z' 2>/dev/null || date)
|
||||
|
||||
case "$MODE" in
|
||||
--cpu)
|
||||
echo "💻 CPU Load: $(get_cpu_load)"
|
||||
;;
|
||||
--temp)
|
||||
echo "🔥 CPU Temp: $(get_cpu_temp)"
|
||||
;;
|
||||
--memory)
|
||||
echo "🧠 RAM: $(get_memory)"
|
||||
;;
|
||||
--disk)
|
||||
echo "💾 Disk: $(get_disk)"
|
||||
;;
|
||||
--network)
|
||||
echo "🌐 Network: $(get_network)"
|
||||
;;
|
||||
*)
|
||||
echo "🖥️ SYSTEM HEALTH REPORT"
|
||||
echo "========================"
|
||||
echo "📅 $DATE_STR"
|
||||
echo "⏱️ Uptime: $(get_uptime)"
|
||||
echo "🔥 CPU Temp: $(get_cpu_temp)"
|
||||
echo "💻 CPU Load: $(get_cpu_load)"
|
||||
echo "🧠 RAM: $(get_memory)"
|
||||
echo "💾 Disk: $(get_disk)"
|
||||
echo "🌐 Network: $(get_network)"
|
||||
echo "========================"
|
||||
echo "Status: $(get_overall_status)"
|
||||
;;
|
||||
esac
|
||||
Loading…
Add table
Reference in a new issue