go tool trace — трейсер виконання¶
go tool trace — це інструмент перегляду трейсів виконання (execution traces), що виробляються трейсером Go runtime (пакет runtime/trace). Трейс — це бінарний журнал низькорівневих подій runtime із наносекундними мітками часу та стеками викликів.
Трейсер проти профайлера¶
Трейсер — це не профайлер. З офіційної сторінки діагностики:
"However, it is not great for identifying hot spots such as analyzing the cause of excessive memory or CPU usage. Use profiling tools instead first to address them."
pprofвідповідає на питання «де моя програма витрачає CPU або виділяє пам'ять?» через статистичні вибірки.go tool traceвідповідає на питання «як взаємодіють мої горутини з плином часу?» — планування, блокування, паузи GC, системні виклики, суперечка за ресурси, паралелізм. Це погляд на часову шкалу.
Що записує трейсер¶
Відповідно до документації пакету runtime/trace:
- Створення, блокування та розблокування горутин
- Події входу / виходу / блокування системних викликів (syscall)
- Події GC
- Зміни розміру купи (heap)
- Події запуску/зупинки процесора (P)
- Зразки CPU-профілювання (коли активні)
- Необов'язкові анотації користувача:
- Tasks — логічні операції, що охоплюють кілька горутин
- Regions — часові інтервали всередині однієї горутини; можуть бути вкладеними
- Logs — повідомлення з мітками часу та категоріями
Як отримати трейс¶
Існують три поширені способи.
A. З коду¶
Оберніть навантаження, яке хочете трейсувати, у trace.Start та trace.Stop:
package main
import (
"log"
"os"
"runtime/trace"
)
func main() {
f, err := os.Create("trace.out")
if err != nil {
log.Fatal(err)
}
defer f.Close()
if err := trace.Start(f); err != nil {
log.Fatal(err)
}
defer trace.Stop()
// ... навантаження для трейсування ...
}
B. З тестів¶
Найпростіший шлях — без змін у коді:
C. З працюючого сервера¶
Імпортуйте net/http/pprof, і сервер відкриє /debug/pprof/trace?seconds=5, що стримить 5-секундний трейс:
Далі:
Перегляд трейсу¶
Це запускає локальний вебсервер та відкриває браузер. Інтерфейс пропонує кілька представлень:
- View trace — часова шкала. Горутини по осі Y, час по осі X, події з кольоровим кодуванням. Можна наближати до окремих переходів стану горутини.
- Goroutine analysis — розбивка за горутинами: скільки часу витрачено в різних станах (виконання, блокування системним викликом, блокування примітивом синхронізації, блокування планувальником тощо).
- Network / sync / syscall / scheduler blocking profiles — розбивки у стилі flame-graph: чому горутини очікували.
- User-defined tasks/regions — з'являється, коли ваш код використовував
trace.NewTaskабоtrace.WithRegion.
Коли варто використовувати¶
- Ви підозрюєте суперечку горутин або низький паралелізм.
- Хвостова затримка (tail latency) є поганою, і ви хочете побачити паузи GC на часовій шкалі.
- Ви додали конкурентність, але пропускна здатність не зросла, і хочете перевірити, чи горутини справді виконуються паралельно.
- Запит іноді займає значно більше часу, ніж зазвичай, і ви хочете бачити, що його заблокувало.
Якщо «цей код у середньому повільний», спочатку звертайтесь до go tool pprof.