Зачем ещё один монитор процессов?
htop прекрасен. Но я хотела сделать инструмент, заточенный под
конкретную задачу: следить за своими dev-серверами и ботами, которые крутятся
в фоне. Плюс это отличный повод поиграть с bubbletea —
TUI-фреймворком от Charm.
Структура проекта
catwatch/
├── main.go
├── model.go # bubbletea Model
├── procs.go # сбор данных через gopsutil
└── ui.go # рендеринг таблицы
Инициализация модуля
go mod init github.com/molly/catwatch
go get github.com/charmbracelet/bubbletea
go get github.com/charmbracelet/lipgloss
go get github.com/shirou/gopsutil/v3
Сбор данных о процессах
package main
import (
"sort"
"github.com/shirou/gopsutil/v3/process"
)
type ProcInfo struct {
PID int32
Name string
CPU float64
Mem float32
}
func fetchProcs() []ProcInfo {
procs, _ := process.Processes()
var out []ProcInfo
for _, p := range procs {
name, _ := p.Name()
cpu, _ := p.CPUPercent()
mem, _ := p.MemoryPercent()
out = append(out, ProcInfo{PID: p.Pid, Name: name, CPU: cpu, Mem: mem})
}
// сортируем по CPU убыванию
sort.Slice(out, func(i, j int) bool {
return out[i].CPU > out[j].CPU
})
if len(out) > 20 {
return out[:20] // показываем топ-20
}
return out
}
Модель bubbletea
package main
import (
"time"
tea "github.com/charmbracelet/bubbletea"
)
type tickMsg struct{}
type model struct { procs []ProcInfo }
func tick() tea.Cmd {
return tea.Tick(2*time.Second, func(_ time.Time) tea.Msg {
return tickMsg{}
})
}
func (m model) Init() tea.Cmd { return tick() }
func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
switch msg.(type) {
case tea.KeyMsg:
return m, tea.Quit
case tickMsg:
m.procs = fetchProcs()
return m, tick()
}
return m, nil
}
Model → Update → View.
Если вы раньше работали с React, это покажется знакомым — только без виртуального DOM
и с настоящей скоростью.
Запуск и результат
go build -o catwatch .
./catwatch
В итоге получается интерактивная таблица, которая обновляется каждые 2 секунды, подсвечивает процессы с высокой нагрузкой и реагирует на нажатие любой клавиши для выхода. Весит бинарник около 8 МБ и не требует никакого рантайма.
Проект открытый, код лежит на GitHub. Фичи, которые планирую добавить: фильтрацию по имени, kill по PID и экспорт в CSV.