Skip to content

Latest commit

 

History

History
400 lines (268 loc) · 17.1 KB

File metadata and controls

400 lines (268 loc) · 17.1 KB

gcscope - Go Garbage Collector Visualizer

gcscope demo

Read this in other languages: English

gcscope - терминальный TUI-инструмент для наблюдения за работой сборщика мусора Go в реальном времени. Он показывает GC-циклы, STW-паузы, динамику динамику кучи (live/goal) и сигналы GC pacer прямо в терминале. Источники данных: gctrace, gcpacertrace и runtime/metrics (режимы run и attach).

Типичные сценарии, где он помогает:

  • заметить всплески STW-пауз под нагрузкой
  • увидеть, стал ли GC срабатывать чаще или реже после изменений в коде
  • понять, как heap live приближается к heap goal и когда pacing становится агрессивнее
  • сравнить два запуска по snapshot-файлам (diff)

Содержание

Как устроено

У gcscope есть два источника данных:

  • run — основной режим: запускает ваш бинарник, добавляет в GODEBUG значения gctrace=1,gcpacertrace=1 и разбирает stderr целевого процесса.
  • attach — дополнительный режим: опрашивает HTTP-эндпоинт, который отдаёт runtime/metrics в JSON-формате, понятном gcscope через pkg/reporter.

Для режима run менять код приложения не нужно. Для режима attach нужно добавить в сервис небольшой HTTP-эндпоинт.

Установка

Выберите один из вариантов ниже.

Установка через Go

Установить gcscope в GOBIN:

go install github.com/timur-developer/gcscope/cmd/gcscope@latest

После этого можно запускать как обычную команду (из любой папки):

gcscope lab churn
gcscope run ./path/to/your-binary -- --your-flag value
gcscope attach http://127.0.0.1:8080/gcscope/metrics
gcscope diff ./a.json ./b.json

Встроенная справка:

gcscope --help
gcscope run --help

Готовые бинарники (Releases)

Скачайте готовый бинарник со страницы GitHub Releases (Assets), выберите архив под вашу OS/arch и распакуйте.

Запуск из распакованной папки:

Windows (PowerShell):

.\gcscope.exe lab churn

macOS / Linux:

chmod +x ./gcscope
./gcscope lab churn

Чтобы запускать gcscope из любой папки, переместите бинарник в директорию из PATH (или добавьте папку с бинарником в PATH).

Запуск из исходников (без установки)

go run ./cmd/gcscope lab churn

Быстрый старт (1 минута)

gcscope launch

Требования: Go 1.22+ и достаточно большое окно терминала.

1) Попробовать на демо

Из исходников (без установки):

go run ./cmd/gcscope lab churn

Или через Makefile:

make lab-churn

Справка внутри приложения доступна по ? / h / f1.

2) Запустить gcscope на своём бинарнике

  1. Соберите ваше приложение в бинарник:
go build -o ./myapp ./cmd/myapp
  1. Запустите под наблюдением:
go run ./cmd/gcscope run ./myapp -- --your-flag value

Разделитель -- нужен, чтобы отделить аргументы gcscope от аргументов вашей программы.

  1. В UI:
  • ? - открыть справку со всеми хоткеями
  • space - пауза/продолжить
  • в паузе left/right (и home/end) листают историю
  • s сохраняет snapshot-файл в tmp/snapshots (по умолчанию)

Если хотите использовать gcscope как обычный CLI (однажды установить и дальше запускать gcscope ...), см. раздел Установка.

Режимы и команды

run (запуск вашего бинарника под наблюдением)

Запускает ваш бинарник и в реальном времени показывает события GC:

gcscope run ./path/to/your-binary

Этот режим предназначен для того, чтобы посмотреть, как сборщик мусора Go ведет себя именно в вашем проекте во время реального запуска.

run работает с уже собранным бинарником (а не с .go файлом), поэтому сначала соберите приложение, а затем передайте путь к исполняемому файлу в gcscope.

Нужны флаги gcscope или нужно передать аргументы вашей программе? См. раздел Настройки.

Из исходников:

go run ./cmd/gcscope run ./path/to/your-binary

Через Makefile:

make run TARGET=./path/to/your-binary

lab (встроенные демо-нагрузки)

lab запускает встроенную нагрузку, чтобы можно было быстро посмотреть работу приложения и разобраться с хоткеями.

gcscope lab alloc
gcscope lab churn
gcscope lab idle
gcscope lab spike

Что примерно означает каждый пресет:

  • alloc: ровные небольшие/средние аллокации с частичным удержанием (heap live плавно растет, GC срабатывает стабильно)
  • churn: повторяющиеся крупные всплески с коротким удержанием (частые GC, удобно смотреть STW/pacer под нагрузкой)
  • idle: почти бездействие, но иногда небольшие всплески (редкие GC-события, поведение при низкой активности)
  • spike: лёгкая фоновая нагрузка и периодические тяжёлые всплески (хорошо видно скачки в heap/STW показателях)

attach (подключение к runtime/metrics HTTP endpoint)

Подключение к уже работающему сервису, который отдает runtime/metrics в JSON-формате gcscope.

  1. Добавьте pkg/reporter в сервис:
package main

import (
	"log"
	"net/http"

	"github.com/timur-developer/gcscope/pkg/reporter"
)

func main() {
	rep := reporter.New()

	mux := http.NewServeMux()
	mux.Handle(rep.Path(), rep.Handler())

	log.Fatal(http.ListenAndServe(":8080", mux))
}
  1. Подключитесь:
gcscope attach http://127.0.0.1:8080/gcscope/metrics

Важные нюансы attach режима:

  • данные берутся из runtime/metrics, поэтому они отличаются от run режима
  • env переменные (GOGC, GOMEMLIMIT, GODEBUG) недоступны, UI покажет n/a

diff (сравнение двух snapshot-файлов)

Сравнение двух snapshot-файлов:

gcscope diff ./a.json ./b.json

Что выводит diff:

  • краткую сводку по snapshot A и B (gc_cycles_total, heap_live_mb, stw_p50/p99/max_us)
  • разницу (B-A) для heap_live_mb и STW метрик окна

Что показывает UI (метрики и панели)

gcscope UI overview

gcscope хранит скользящее окно последних GC событий (--window-size, по умолчанию: 200) и показывает как значения по циклам, так и агрегаты по окну.

Current Values

  • GC cycles total: текущий номер GC цикла
  • last STW (us): STW пауза последнего цикла (sweep term + mark term, в микросекундах)
  • heap live (MB) / heap goal (MB): live heap и целевой размер кучи
  • heap: live/goal: компактный индикатор соотношения live/goal

Information (агрегаты по окну)

  • max STW (us): максимальная STW-пауза в текущем окне
  • gc: частота GC в GCs/min и/или средний интервал между GC
  • stw: количество и процент «плохих» STW-пауз по заданным порогам, а также количество forced GC
  • time since last GC, uptime
  • stw thresholds: пороги warn / bad (см. настройки)
  • состояние snapshot и директория snapshot
  • контекст env-окружения (GOGC, GOMEMLIMIT, GODEBUG) в run/lab (в attach недоступен)

Графики

  • Heap live over time (MB): heap live во времени
  • STW p50/p99/max over time (us): p50/p99/max STW по окну
  • STW per cycle: bar chart по циклам; подписи можно переключать на STW или heap live (l)

Cycle Details (детали выбранного цикла)

  • GC #, time since start, forced
  • STW total (us) + разбивка: sweep term / mark term (фазы GC)
  • heap (MB): start/end и live/goal
  • gc cpu (%)
  • pacer сигналы (если доступны): assist ratio, assist workers, pages swept

Хоткеи

gcscope features

Полный список горячих клавиш всегда доступен в Help (? / h / f1).

База:

  • ? / h / f1 показать/скрыть Help
  • q / ctrl+c выход
  • space пауза/продолжить обновления
  • left / right листать историю (в паузе)
  • home / end в начало/конец истории (в паузе)
  • s сохранить snapshot

Интерфейс:

  • g переключить layout (spaced/tight)
  • l режим подписей STW bar chart (GC+STW -> GC+Heap -> GC-only)

Графики:

  • z выбрать активный график (Heap/STW). Zoom/pan применяется к активному графику.
  • + / - Y-zoom активного графика
  • 0 сброс Y zoom/pan активного графика
  • shift+up / shift+down Y-pan активного графика
  • [ / ] X-zoom (масштаб по времени): all -> 1h -> 15m -> 5m -> 1m (и обратно)
  • r полный сброс focus, zoom/pan и time span

Настройки

Глобальные флаги (и env-оверрайды):

  • --window-size (GCSCOPE_WINDOW_SIZE) количество событий в памяти (default: 200)
  • --snapshot-path (GCSCOPE_SNAPSHOT_PATH) директория snapshots (default: tmp/snapshots)
  • --exit-snapshot (GCSCOPE_EXIT_SNAPSHOT) snapshot на выходе (default: true)
  • --no-alt-screen (GCSCOPE_NO_ALT_SCREEN) отключить alt screen buffer
  • --stw-warn-us (GCSCOPE_STW_WARN_US) порог warn для STW (default: 200)
  • --stw-bad-us (GCSCOPE_STW_BAD_US) порог bad для STW (default: 1000)

Режимные env:

  • GCSCOPE_RUN_TARGET
  • GCSCOPE_ATTACH_URL, GCSCOPE_POLL_INTERVAL
  • GCSCOPE_LAB_PRESET
  • GCSCOPE_DIFF_A, GCSCOPE_DIFF_B

Любой флаг можно задавать и через соответствующую переменную окружения GCSCOPE_*, перечисленную выше.

Флаги и передача аргументов

Глобальные флаги (например, --window-size, --stw-bad-us) пишутся до подкоманды, потому что они относятся ко всем режимам.

В режиме run разделитель -- отделяет аргументы gcscope от аргументов вашей программы. Все, что после --, передается вашему бинарнику как есть.

Шаблон:

gcscope [глобальные флаги] run <target-binary> -- [аргументы вашей программы...]

Пример:

gcscope --window-size 500 --stw-bad-us 2000 run ./path/to/your-binary -- --your-flag value

Snapshots

Snapshot - это JSON-файл, который фиксирует состояние "последних N GC-событий" (то же окно, которое использует UI). Его удобно сохранять для сравнения запусков, обмена и фиксации регрессий.

По умолчанию snapshot-файлы пишутся в tmp/snapshots.

  • ручной snapshot: s
  • snapshot при выходе включен по умолчанию; пропускается, если в течение 5 секунд перед выходом snapshot был сделан вручную

Что внутри snapshot:

  • текущие значения (gc_cycles_total, last_stw_us, heap_live_mb, heap_goal_mb)
  • агрегаты окна (stw_p50_us, stw_p99_us, stw_max_us)
  • список событий GC в окне (включая распарсенные pacer-поля, если они были доступны)

Makefile: список команд и зачем они нужны

make help выводит список целей. Основные:

  • make ci: прогоняет линтер, тесты и сборку
  • make lint: запускает golangci-lint
  • make test: запускает go test ./...
  • make build: go build ./... (быстрая проверка, что все собирается)
  • make install: устанавливает gcscope в вашу Go bin директорию
  • make lab / make lab-churn и т.п.: запускает демо-нагрузки
  • make run TARGET=... ARGS="-- ...": запускает ваш бинарник под наблюдением
  • make attach URL=...: подключается к сервису (по умолчанию http://127.0.0.1:8080/gcscope/metrics)
  • make diff A=... B=...: сравнивает два snapshot-файла

Для мейнтейнеров:

  • make testbin: пересобирает встроенные lab-бинарники под все поддерживаемые OS/arch
  • make release-snapshot: локальная сборка релиза через GoReleaser (--snapshot --clean)

Notes / FAQ

  • В attach режиме нельзя узнать env параметры (GOGC, GOMEMLIMIT, GODEBUG), поэтому UI показывает n/a.
  • Если вы не видите обновлений, возможно, приложение пока не вызывало сборщик мусора (подождите, пока runtime его вызовет).
  • Если терминал ведет себя странно, попробуйте --no-alt-screen (или GCSCOPE_NO_ALT_SCREEN=true).
  • Очень маленькие STW значения могут отображаться как 0 из-за форматирования gctrace.

Разработка

make ci
make lint
make test
make build

Лицензия

MIT. См. LICENSE.