Пакет trace
Обзор
Пакет trace содержит средства, позволяющие программам создавать трассировки для трассировщика выполнения Go.
Трассировка активности среды выполнения
Трассировка выполнения фиксирует широкий спектр событий, таких как создание, блокировка и разблокировка горутин, вход в системный вызов, выход из него и блокировка, события, связанные со сборкой мусора, изменения размера кучи, запуск и остановка процессора и т. д. Если активно профилирование ЦП, трассировщик выполнения также пытается включить в трассировку соответствующие образцы. Для большинства событий фиксируются точная временная метка с точностью до наносекунды и трассировка стека. Созданную трассировку можно анализировать с помощью `go tool trace`.
Поддержка трассировки тестов и бенчмарков, созданных с помощью стандартного пакета testing, встроена в `go test`. Например, следующая команда запускает тест в текущем каталоге и записывает файл трассировки (trace.out).
go test -trace=trace.out
Пакет runtime/trace предоставляет API для добавления аналогичной поддержки трассировки в автономную программу. См. пример, демонстрирующий использование этого API для включения трассировки.
Также доступен стандартный HTTP-интерфейс для работы с данными трассировки. Добавьте следующую строку, чтобы зарегистрировать обработчик по адресу /debug/pprof/trace для загрузки текущей трассировки:
import _ "net/http/pprof"
Дополнительные сведения обо всех конечных точках отладки, регистрируемых при этом импорте, см. в пакете net/http/pprof.
Пользовательские аннотации
Пакет trace предоставляет API пользовательских аннотаций, с помощью которых можно регистрировать интересные события во время выполнения.
Существует три типа пользовательских аннотаций: сообщения журнала, области и задачи.
Log добавляет в трассировку выполнения сообщение с временной меткой и дополнительной информацией, например категорией сообщения и сведениями о том, какая горутина вызвала Log. Трассировщик выполнения предоставляет интерфейсы для фильтрации и группировки горутин по категории журнала и сообщению, переданному в Log.
Область предназначена для регистрации временного интервала выполнения горутины. По определению, область начинается и заканчивается в одной и той же горутине. Области можно вкладывать друг в друга, чтобы представить подынтервалы. Например, следующий код записывает в трассировку выполнения четыре области, чтобы отслеживать длительность последовательных этапов приготовления капучино.
trace.WithRegion(ctx, "makeCappuccino", func() {
// orderID allows to identify a specific order
// among many cappuccino order region records.
trace.Log(ctx, "orderID", orderID)
trace.WithRegion(ctx, "steamMilk", steamMilk)
trace.WithRegion(ctx, "extractCoffee", extractCoffee)
trace.WithRegion(ctx, "mixMilkCoffee", mixMilkCoffee)
})
Задача — это компонент более высокого уровня, помогающий отслеживать логические операции, такие как запрос RPC, HTTP-запрос или интересная локальная операция, для которой могут потребоваться совместные действия нескольких горутин. Поскольку в задачах могут участвовать несколько горутин, они отслеживаются с помощью объекта context.Context. NewTask создает новую задачу и помещает ее в возвращаемый объект context.Context. Сообщения журнала и области связываются с задачей, если она есть в контексте, переданном в Log и WithRegion.
Например, предположим, что мы решили вспенивать молоко, готовить кофе и смешивать молоко с кофе в отдельных горутинах. С помощью задачи инструмент трассировки может определить горутины, участвовавшие в приготовлении конкретного заказа на капучино.
ctx, task := trace.NewTask(ctx, "makeCappuccino")
trace.Log(ctx, "orderID", orderID)
milk := make(chan bool)
espresso := make(chan bool)
go func() {
trace.WithRegion(ctx, "steamMilk", steamMilk)
milk <- true
}()
go func() {
trace.WithRegion(ctx, "extractCoffee", extractCoffee)
espresso <- true
}()
go func() {
defer task.End() // When assemble is done, the order is complete.
<-espresso
<-milk
trace.WithRegion(ctx, "mixMilkCoffee", mixMilkCoffee)
}()
Инструмент трассировки вычисляет задержку задачи, измеряя время между созданием задачи и ее завершением, и предоставляет распределения задержек для каждого типа задачи, обнаруженного в трассировке.
Пример
Пример демонстрирует использование пакета trace для трассировки выполнения программы Go. Результат трассировки будет записан в файл trace.out
Код:
package trace_test
import (
"fmt"
"log"
"os"
"runtime/trace"
)
// Example demonstrates the use of the trace package to trace
// the execution of a Go program. The trace output will be
// written to the file trace.out
func Example() {
f, err := os.Create("trace.out")
if err != nil {
log.Fatalf("failed to create trace output file: %v", err)
}
defer func() {
if err := f.Close(); err != nil {
log.Fatalf("failed to close trace file: %v", err)
}
}()
if err := trace.Start(f); err != nil {
log.Fatalf("failed to start trace: %v", err)
}
defer trace.Stop()
// your program here
RunMyProgram()
}
func RunMyProgram() {
fmt.Printf("this function will be traced")
}
Указатель
Примеры
Файлы пакета
annotation.go batch.go encoding.go flightrecorder.go recorder.go subscribe.go trace.go
func IsEnabled 1.11
func IsEnabled() bool
IsEnabled сообщает, включена ли трассировка. Эта информация носит только рекомендательный характер. К моменту возврата этой функции состояние трассировки могло измениться.
func Log 1.11
func Log(ctx context.Context, category, message string)
Log добавляет одиночное событие с указанными категорией и сообщением. Категория может быть пустой; предполагается, что в системе будет лишь несколько уникальных категорий.
func Logf 1.11
func Logf(ctx context.Context, category, format string, args ...any)
Logf похожа на Log, но значение форматируется с использованием указанной строки формата.
func Start 1.5
func Start(w io.Writer) error
Start включает трассировку для текущей программы. Во время трассировки данные буферизуются и записываются в w. Start возвращает ошибку, если трассировка уже включена.
func Stop 1.5
func Stop()
Stop останавливает текущую трассировку, если она выполняется. Stop возвращается только после завершения всех операций записи трассировки.
func WithRegion 1.11
func WithRegion(ctx context.Context, regionType string, fn func())
WithRegion начинает область, связанную с вызывающей ее горутиной, запускает fn, а затем завершает область. Если в контексте есть задача, область связывается с ней. В противном случае область связывается с фоновой задачей.
regionType используется для классификации областей, поэтому уникальных типов областей должно быть немного.
type FlightRecorder 1.25
FlightRecorder представляет собой отдельного потребителя трассировки выполнения Go. Он отслеживает скользящее окно данных трассировки, создаваемых средой выполнения, которое всегда содержит самые свежие данные.
В каждый момент времени может быть активен не более чем один flight recorder, однако запись трассировки может выполняться одновременно с потребителем трассировки, использующим trace.Start. В будущем это ограничение, допускающее только один flight recorder, может быть снято.
type FlightRecorder struct {
// contains filtered or unexported fields
}
func NewFlightRecorder 1.25
func NewFlightRecorder(cfg FlightRecorderConfig) *FlightRecorder
NewFlightRecorder создает новый flight recorder на основе предоставленной конфигурации.
func (*FlightRecorder) Enabled 1.25
func (fr *FlightRecorder) Enabled() bool
Enabled возвращает true, если flight recorder активен. В частности, метод вернет true, если Start завершился без ошибки и Stop еще не был вызван. Метод можно безопасно вызывать одновременно из нескольких горутин.
func (*FlightRecorder) Start 1.25
func (fr *FlightRecorder) Start() error
Start активирует flight recorder и начинает запись данных трассировки. В каждый момент времени может быть активен только один вызов trace.Start. Кроме того, в настоящее время в программе может быть активен только один flight recorder. Возвращает ошибку, если flight recorder не удается запустить или он уже запущен.
func (*FlightRecorder) Stop 1.25
func (fr *FlightRecorder) Stop()
Stop завершает запись данных трассировки. Метод блокируется до завершения всех выполняющихся одновременно вызовов WriteTo.
func (*FlightRecorder) WriteTo 1.25
func (fr *FlightRecorder) WriteTo(w io.Writer) (n int64, err error)
WriteTo создает снимок скользящего окна, отслеживаемого flight recorder. Предполагается, что снимок содержит данные, актуальные на момент вызова WriteTo, однако это не гарантируется. Одновременно выполнять WriteTo может только одна горутина. Возвращается ошибка, если не удалось выполнить запись в w, если другой вызов WriteTo уже выполняется или если flight recorder не активен.
type FlightRecorderConfig 1.25
type FlightRecorderConfig struct {
// MinAge is a lower bound on the age of an event in the flight recorder's window.
//
// The flight recorder will strive to promptly discard events older than the minimum age,
// but older events may appear in the window snapshot. The age setting will always be
// overridden by MaxBytes.
//
// If this is 0, the minimum age is implementation defined, but can be assumed to be on the order
// of seconds.
MinAge time.Duration
// MaxBytes is an upper bound on the size of the window in bytes.
//
// This setting takes precedence over MinAge.
// However, it does not make any guarantees on the size of the data WriteTo will write,
// nor does it guarantee memory overheads will always stay below MaxBytes. Treat it
// as a hint.
//
// If this is 0, the maximum size is implementation defined.
MaxBytes uint64
}
type Region 1.11
Region — это область кода, интервал времени выполнения которой отслеживается в трассировке.
type Region struct {
// contains filtered or unexported fields
}
func StartRegion 1.11
func StartRegion(ctx context.Context, regionType string) *Region
StartRegion начинает область и возвращает ее. Метод Region.End возвращенного Region должен быть вызван из той же горутины, в которой была начата область. В каждой горутине области должны быть вложенными. То есть области, начатые после этой области, должны завершиться до того, как можно будет завершить эту область. Рекомендуется использовать следующий шаблон:
defer trace.StartRegion(ctx, "myTracedRegion").End()
func (*Region) End 1.11
func (r *Region) End()
End отмечает завершение отслеживаемой области кода.
type Task 1.11
Task — это тип данных для трассировки определенной пользователем логической операции.
type Task struct {
// contains filtered or unexported fields
}
func NewTask 1.11
func NewTask(pctx context.Context, taskType string) (ctx context.Context, task *Task)
NewTask создает экземпляр задачи типа taskType и возвращает его вместе с Context, содержащим эту задачу. Если входной контекст содержит задачу, новая задача становится ее подзадачей.
taskType используется для классификации экземпляров задач. Инструменты анализа, такие как трассировщик выполнения Go, могут предполагать, что в системе существует ограниченное число уникальных типов задач.
Метод Task.End возвращенного Task используется для отметки завершения задачи. Инструмент трассировки измеряет задержку задачи как время между ее созданием и вызовом метода End, а также предоставляет распределение задержек для каждого типа задач. Если метод End вызывается несколько раз, при измерении задержки учитывается только первый вызов.
ctx, task := trace.NewTask(ctx, "awesomeTask")
trace.WithRegion(ctx, "preparation", prepWork)
// preparation of the task
go func() { // continue processing the task in a separate goroutine.
defer task.End()
trace.WithRegion(ctx, "remainingWork", remainingWork)
}()
func (*Task) End 1.11
func (t *Task) End()
End отмечает завершение операции, представленной Task.
© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/runtime/trace/