Package trace

import "internal/trace"
Overview
Index

Overview ▾

Index ▾

Constants
Variables
func GoroutineStats(events []*Event) map[uint64]*GDesc
func IsSystemGoroutine(entryFn string) bool
func MutatorUtilization(events []*Event, flags UtilFlags) [][]MutatorUtil
func MutatorUtilizationV2(events []tracev2.Event, flags UtilFlags) [][]MutatorUtil
func Print(events []*Event)
func PrintEvent(ev *Event)
func ReadVersion(r io.Reader) (ver int, off int, err error)
func RelatedGoroutines(events []*Event, goid uint64) map[uint64]bool
func RelatedGoroutinesV2(events []tracev2.Event, goid tracev2.GoID) map[tracev2.GoID]struct{}
type Event
    func (ev *Event) String() string
type Frame
type GDesc
type GExecutionStat
type GoroutineExecStats
    func (s GoroutineExecStats) NonOverlappingStats() map[string]time.Duration
    func (s GoroutineExecStats) UnknownTime() time.Duration
type GoroutineSummary
type MMUCurve
    func NewMMUCurve(utils [][]MutatorUtil) *MMUCurve
    func (c *MMUCurve) Examples(window time.Duration, n int) (worst []UtilWindow)
    func (c *MMUCurve) MMU(window time.Duration) (mmu float64)
    func (c *MMUCurve) MUD(window time.Duration, quantiles []float64) []float64
type MutatorUtil
type ParseResult
    func Parse(r io.Reader, bin string) (ParseResult, error)
type Summarizer
    func NewSummarizer() *Summarizer
    func (s *Summarizer) Event(ev *tracev2.Event)
    func (s *Summarizer) Finalize() *Summary
type Summary
type UserRegionDesc
type UserRegionSummary
type UserTaskSummary
    func (s *UserTaskSummary) Complete() bool
    func (s *UserTaskSummary) Descendents() []*UserTaskSummary
type UtilFlags
type UtilWindow
type Writer
    func NewWriter() *Writer
    func (w *Writer) Emit(typ byte, args ...uint64)

Package files

gc.go goroutines.go mud.go order.go parser.go summary.go writer.go

Constants

const (
    // Special P identifiers:
    FakeP    = 1000000 + iota
    TimerP   // depicts timer unblocks
    NetpollP // depicts network unblocks
    SyscallP // depicts returns from syscalls
    GCP      // depicts GC state
    ProfileP // depicts recording of CPU profile samples
)

Event types in the trace. Verbatim copy from src/runtime/trace.go with the "trace" prefix removed.

const (
    EvNone              = 0  // unused
    EvBatch             = 1  // start of per-P batch of events [pid, timestamp]
    EvFrequency         = 2  // contains tracer timer frequency [frequency (ticks per second)]
    EvStack             = 3  // stack [stack id, number of PCs, array of {PC, func string ID, file string ID, line}]
    EvGomaxprocs        = 4  // current value of GOMAXPROCS [timestamp, GOMAXPROCS, stack id]
    EvProcStart         = 5  // start of P [timestamp, thread id]
    EvProcStop          = 6  // stop of P [timestamp]
    EvGCStart           = 7  // GC start [timestamp, seq, stack id]
    EvGCDone            = 8  // GC done [timestamp]
    EvSTWStart          = 9  // GC mark termination start [timestamp, kind]
    EvSTWDone           = 10 // GC mark termination done [timestamp]
    EvGCSweepStart      = 11 // GC sweep start [timestamp, stack id]
    EvGCSweepDone       = 12 // GC sweep done [timestamp, swept, reclaimed]
    EvGoCreate          = 13 // goroutine creation [timestamp, new goroutine id, new stack id, stack id]
    EvGoStart           = 14 // goroutine starts running [timestamp, goroutine id, seq]
    EvGoEnd             = 15 // goroutine ends [timestamp]
    EvGoStop            = 16 // goroutine stops (like in select{}) [timestamp, stack]
    EvGoSched           = 17 // goroutine calls Gosched [timestamp, stack]
    EvGoPreempt         = 18 // goroutine is preempted [timestamp, stack]
    EvGoSleep           = 19 // goroutine calls Sleep [timestamp, stack]
    EvGoBlock           = 20 // goroutine blocks [timestamp, stack]
    EvGoUnblock         = 21 // goroutine is unblocked [timestamp, goroutine id, seq, stack]
    EvGoBlockSend       = 22 // goroutine blocks on chan send [timestamp, stack]
    EvGoBlockRecv       = 23 // goroutine blocks on chan recv [timestamp, stack]
    EvGoBlockSelect     = 24 // goroutine blocks on select [timestamp, stack]
    EvGoBlockSync       = 25 // goroutine blocks on Mutex/RWMutex [timestamp, stack]
    EvGoBlockCond       = 26 // goroutine blocks on Cond [timestamp, stack]
    EvGoBlockNet        = 27 // goroutine blocks on network [timestamp, stack]
    EvGoSysCall         = 28 // syscall enter [timestamp, stack]
    EvGoSysExit         = 29 // syscall exit [timestamp, goroutine id, seq, real timestamp]
    EvGoSysBlock        = 30 // syscall blocks [timestamp]
    EvGoWaiting         = 31 // denotes that goroutine is blocked when tracing starts [timestamp, goroutine id]
    EvGoInSyscall       = 32 // denotes that goroutine is in syscall when tracing starts [timestamp, goroutine id]
    EvHeapAlloc         = 33 // gcController.heapLive change [timestamp, heap live bytes]
    EvHeapGoal          = 34 // gcController.heapGoal change [timestamp, heap goal bytes]
    EvTimerGoroutine    = 35 // denotes timer goroutine [timer goroutine id]
    EvFutileWakeup      = 36 // denotes that the previous wakeup of this goroutine was futile [timestamp]
    EvString            = 37 // string dictionary entry [ID, length, string]
    EvGoStartLocal      = 38 // goroutine starts running on the same P as the last event [timestamp, goroutine id]
    EvGoUnblockLocal    = 39 // goroutine is unblocked on the same P as the last event [timestamp, goroutine id, stack]
    EvGoSysExitLocal    = 40 // syscall exit on the same P as the last event [timestamp, goroutine id, real timestamp]
    EvGoStartLabel      = 41 // goroutine starts running with label [timestamp, goroutine id, seq, label string id]
    EvGoBlockGC         = 42 // goroutine blocks on GC assist [timestamp, stack]
    EvGCMarkAssistStart = 43 // GC mark assist start [timestamp, stack]
    EvGCMarkAssistDone  = 44 // GC mark assist done [timestamp]
    EvUserTaskCreate    = 45 // trace.NewTask [timestamp, internal task id, internal parent id, name string, stack]
    EvUserTaskEnd       = 46 // end of task [timestamp, internal task id, stack]
    EvUserRegion        = 47 // trace.WithRegion [timestamp, internal task id, mode(0:start, 1:end), name string, stack]
    EvUserLog           = 48 // trace.Log [timestamp, internal id, key string id, stack, value string]
    EvCPUSample         = 49 // CPU profiling sample [timestamp, real timestamp, real P id (-1 when absent), goroutine id, stack]
    EvCount             = 50
)

Variables

BreakTimestampsForTesting causes the parser to randomly alter timestamps (for testing of broken cputicks).

var BreakTimestampsForTesting bool

ErrTimeOrder is returned by Parse when the trace contains time stamps that do not respect actual event ordering.

var ErrTimeOrder = fmt.Errorf("time stamps out of order")
var EventDescriptions = [EvCount]struct {
    Name       string
    minVersion int
    Stack      bool
    Args       []string
    SArgs      []string // string arguments
}{
    EvNone:              {"None", 1005, false, []string{}, nil},
    EvBatch:             {"Batch", 1005, false, []string{"p", "ticks"}, nil},
    EvFrequency:         {"Frequency", 1005, false, []string{"freq"}, nil},
    EvStack:             {"Stack", 1005, false, []string{"id", "siz"}, nil},
    EvGomaxprocs:        {"Gomaxprocs", 1005, true, []string{"procs"}, nil},
    EvProcStart:         {"ProcStart", 1005, false, []string{"thread"}, nil},
    EvProcStop:          {"ProcStop", 1005, false, []string{}, nil},
    EvGCStart:           {"GCStart", 1005, true, []string{"seq"}, nil},
    EvGCDone:            {"GCDone", 1005, false, []string{}, nil},
    EvSTWStart:          {"STWStart", 1005, false, []string{"kindid"}, []string{"kind"}},
    EvSTWDone:           {"STWDone", 1005, false, []string{}, nil},
    EvGCSweepStart:      {"GCSweepStart", 1005, true, []string{}, nil},
    EvGCSweepDone:       {"GCSweepDone", 1005, false, []string{"swept", "reclaimed"}, nil},
    EvGoCreate:          {"GoCreate", 1005, true, []string{"g", "stack"}, nil},
    EvGoStart:           {"GoStart", 1005, false, []string{"g", "seq"}, nil},
    EvGoEnd:             {"GoEnd", 1005, false, []string{}, nil},
    EvGoStop:            {"GoStop", 1005, true, []string{}, nil},
    EvGoSched:           {"GoSched", 1005, true, []string{}, nil},
    EvGoPreempt:         {"GoPreempt", 1005, true, []string{}, nil},
    EvGoSleep:           {"GoSleep", 1005, true, []string{}, nil},
    EvGoBlock:           {"GoBlock", 1005, true, []string{}, nil},
    EvGoUnblock:         {"GoUnblock", 1005, true, []string{"g", "seq"}, nil},
    EvGoBlockSend:       {"GoBlockSend", 1005, true, []string{}, nil},
    EvGoBlockRecv:       {"GoBlockRecv", 1005, true, []string{}, nil},
    EvGoBlockSelect:     {"GoBlockSelect", 1005, true, []string{}, nil},
    EvGoBlockSync:       {"GoBlockSync", 1005, true, []string{}, nil},
    EvGoBlockCond:       {"GoBlockCond", 1005, true, []string{}, nil},
    EvGoBlockNet:        {"GoBlockNet", 1005, true, []string{}, nil},
    EvGoSysCall:         {"GoSysCall", 1005, true, []string{}, nil},
    EvGoSysExit:         {"GoSysExit", 1005, false, []string{"g", "seq", "ts"}, nil},
    EvGoSysBlock:        {"GoSysBlock", 1005, false, []string{}, nil},
    EvGoWaiting:         {"GoWaiting", 1005, false, []string{"g"}, nil},
    EvGoInSyscall:       {"GoInSyscall", 1005, false, []string{"g"}, nil},
    EvHeapAlloc:         {"HeapAlloc", 1005, false, []string{"mem"}, nil},
    EvHeapGoal:          {"HeapGoal", 1005, false, []string{"mem"}, nil},
    EvTimerGoroutine:    {"TimerGoroutine", 1005, false, []string{"g"}, nil},
    EvFutileWakeup:      {"FutileWakeup", 1005, false, []string{}, nil},
    EvString:            {"String", 1007, false, []string{}, nil},
    EvGoStartLocal:      {"GoStartLocal", 1007, false, []string{"g"}, nil},
    EvGoUnblockLocal:    {"GoUnblockLocal", 1007, true, []string{"g"}, nil},
    EvGoSysExitLocal:    {"GoSysExitLocal", 1007, false, []string{"g", "ts"}, nil},
    EvGoStartLabel:      {"GoStartLabel", 1008, false, []string{"g", "seq", "labelid"}, []string{"label"}},
    EvGoBlockGC:         {"GoBlockGC", 1008, true, []string{}, nil},
    EvGCMarkAssistStart: {"GCMarkAssistStart", 1009, true, []string{}, nil},
    EvGCMarkAssistDone:  {"GCMarkAssistDone", 1009, false, []string{}, nil},
    EvUserTaskCreate:    {"UserTaskCreate", 1011, true, []string{"taskid", "pid", "typeid"}, []string{"name"}},
    EvUserTaskEnd:       {"UserTaskEnd", 1011, true, []string{"taskid"}, nil},
    EvUserRegion:        {"UserRegion", 1011, true, []string{"taskid", "mode", "typeid"}, []string{"name"}},
    EvUserLog:           {"UserLog", 1011, true, []string{"id", "keyid"}, []string{"category", "message"}},
    EvCPUSample:         {"CPUSample", 1019, true, []string{"ts", "p", "g"}, nil},
}

func GoroutineStats

func GoroutineStats(events []*Event) map[uint64]*GDesc

GoroutineStats generates statistics for all goroutines in the trace.

func IsSystemGoroutine

func IsSystemGoroutine(entryFn string) bool

func MutatorUtilization

func MutatorUtilization(events []*Event, flags UtilFlags) [][]MutatorUtil

MutatorUtilization returns a set of mutator utilization functions for the given trace. Each function will always end with 0 utilization. The bounds of each function are implicit in the first and last event; outside of these bounds each function is undefined.

If the UtilPerProc flag is not given, this always returns a single utilization function. Otherwise, it returns one function per P.

func MutatorUtilizationV2

func MutatorUtilizationV2(events []tracev2.Event, flags UtilFlags) [][]MutatorUtil

MutatorUtilizationV2 returns a set of mutator utilization functions for the given v2 trace, passed as an io.Reader. Each function will always end with 0 utilization. The bounds of each function are implicit in the first and last event; outside of these bounds each function is undefined.

If the UtilPerProc flag is not given, this always returns a single utilization function. Otherwise, it returns one function per P.

func Print

func Print(events []*Event)

Print dumps events to stdout. For debugging.

func PrintEvent

func PrintEvent(ev *Event)

PrintEvent dumps the event to stdout. For debugging.

func ReadVersion

func ReadVersion(r io.Reader) (ver int, off int, err error)

func RelatedGoroutines

func RelatedGoroutines(events []*Event, goid uint64) map[uint64]bool

RelatedGoroutines finds a set of goroutines related to goroutine goid.

func RelatedGoroutinesV2

func RelatedGoroutinesV2(events []tracev2.Event, goid tracev2.GoID) map[tracev2.GoID]struct{}

RelatedGoroutinesV2 finds a set of goroutines related to goroutine goid for v2 traces. The association is based on whether they have synchronized with each other in the Go scheduler (one has unblocked another).

type Event

Event describes one event in the trace.

type Event struct {
    Off  int  // offset in input file (for debugging and error reporting)
    Type byte // one of Ev*

    Ts    int64     // timestamp in nanoseconds
    P     int       // P on which the event happened (can be one of TimerP, NetpollP, SyscallP)
    G     uint64    // G on which the event happened
    StkID uint64    // unique stack ID
    Stk   []*Frame  // stack trace (can be empty)
    Args  [3]uint64 // event-type-specific arguments
    SArgs []string  // event-type-specific string args
    // linked event (can be nil), depends on event type:
    // for GCStart: the GCStop
    // for GCSTWStart: the GCSTWDone
    // for GCSweepStart: the GCSweepDone
    // for GoCreate: first GoStart of the created goroutine
    // for GoStart/GoStartLabel: the associated GoEnd, GoBlock or other blocking event
    // for GoSched/GoPreempt: the next GoStart
    // for GoBlock and other blocking events: the unblock event
    // for GoUnblock: the associated GoStart
    // for blocking GoSysCall: the associated GoSysExit
    // for GoSysExit: the next GoStart
    // for GCMarkAssistStart: the associated GCMarkAssistDone
    // for UserTaskCreate: the UserTaskEnd
    // for UserRegion: if the start region, the corresponding UserRegion end event
    Link *Event
    // contains filtered or unexported fields
}

func (*Event) String

func (ev *Event) String() string

type Frame

Frame is a frame in stack traces.

type Frame struct {
    PC   uint64
    Fn   string
    File string
    Line int
}

type GDesc

GDesc contains statistics and execution details of a single goroutine.

type GDesc struct {
    ID           uint64
    Name         string
    PC           uint64
    CreationTime int64
    StartTime    int64
    EndTime      int64

    // List of regions in the goroutine, sorted based on the start time.
    Regions []*UserRegionDesc

    // Statistics of execution time during the goroutine execution.
    GExecutionStat
    // contains filtered or unexported fields
}

type GExecutionStat

GExecutionStat contains statistics about a goroutine's execution during a period of time.

type GExecutionStat struct {
    ExecTime      int64
    SchedWaitTime int64
    IOTime        int64
    BlockTime     int64
    SyscallTime   int64
    GCTime        int64
    SweepTime     int64
    TotalTime     int64
}

type GoroutineExecStats

GoroutineExecStats contains statistics about a goroutine's execution during a period of time.

type GoroutineExecStats struct {
    // These stats are all non-overlapping.
    ExecTime          time.Duration
    SchedWaitTime     time.Duration
    BlockTimeByReason map[string]time.Duration
    SyscallTime       time.Duration
    SyscallBlockTime  time.Duration

    // TotalTime is the duration of the goroutine's presence in the trace.
    // Necessarily overlaps with other stats.
    TotalTime time.Duration

    // Total time the goroutine spent in certain ranges; may overlap
    // with other stats.
    RangeTime map[string]time.Duration
}

func (GoroutineExecStats) NonOverlappingStats

func (s GoroutineExecStats) NonOverlappingStats() map[string]time.Duration

func (GoroutineExecStats) UnknownTime

func (s GoroutineExecStats) UnknownTime() time.Duration

UnknownTime returns whatever isn't accounted for in TotalTime.

type GoroutineSummary

GoroutineSummary contains statistics and execution details of a single goroutine. (For v2 traces.)

type GoroutineSummary struct {
    ID           tracev2.GoID
    Name         string       // A non-unique human-friendly identifier for the goroutine.
    PC           uint64       // The first PC we saw for the entry function of the goroutine
    CreationTime tracev2.Time // Timestamp of the first appearance in the trace.
    StartTime    tracev2.Time // Timestamp of the first time it started running. 0 if the goroutine never ran.
    EndTime      tracev2.Time // Timestamp of when the goroutine exited. 0 if the goroutine never exited.

    // List of regions in the goroutine, sorted based on the start time.
    Regions []*UserRegionSummary

    // Statistics of execution time during the goroutine execution.
    GoroutineExecStats
    // contains filtered or unexported fields
}

type MMUCurve

An MMUCurve is the minimum mutator utilization curve across multiple window sizes.

type MMUCurve struct {
    // contains filtered or unexported fields
}

func NewMMUCurve

func NewMMUCurve(utils [][]MutatorUtil) *MMUCurve

NewMMUCurve returns an MMU curve for the given mutator utilization function.

func (*MMUCurve) Examples

func (c *MMUCurve) Examples(window time.Duration, n int) (worst []UtilWindow)

Examples returns n specific examples of the lowest mutator utilization for the given window size. The returned windows will be disjoint (otherwise there would be a huge number of mostly-overlapping windows at the single lowest point). There are no guarantees on which set of disjoint windows this returns.

func (*MMUCurve) MMU

func (c *MMUCurve) MMU(window time.Duration) (mmu float64)

MMU returns the minimum mutator utilization for the given time window. This is the minimum utilization for all windows of this duration across the execution. The returned value is in the range [0, 1].

func (*MMUCurve) MUD

func (c *MMUCurve) MUD(window time.Duration, quantiles []float64) []float64

MUD returns mutator utilization distribution quantiles for the given window size.

The mutator utilization distribution is the distribution of mean mutator utilization across all windows of the given window size in the trace.

The minimum mutator utilization is the minimum (0th percentile) of this distribution. (However, if only the minimum is desired, it's more efficient to use the MMU method.)

type MutatorUtil

MutatorUtil is a change in mutator utilization at a particular time. Mutator utilization functions are represented as a time-ordered []MutatorUtil.

type MutatorUtil struct {
    Time int64
    // Util is the mean mutator utilization starting at Time. This
    // is in the range [0, 1].
    Util float64
}

type ParseResult

ParseResult is the result of Parse.

type ParseResult struct {
    // Events is the sorted list of Events in the trace.
    Events []*Event
    // Stacks is the stack traces keyed by stack IDs from the trace.
    Stacks map[uint64][]*Frame
}

func Parse

func Parse(r io.Reader, bin string) (ParseResult, error)

Parse parses, post-processes and verifies the trace.

type Summarizer

Summarizer constructs per-goroutine time statistics for v2 traces.

type Summarizer struct {
    // contains filtered or unexported fields
}

func NewSummarizer

func NewSummarizer() *Summarizer

NewSummarizer creates a new struct to build goroutine stats from a trace.

func (*Summarizer) Event

func (s *Summarizer) Event(ev *tracev2.Event)

Event feeds a single event into the stats summarizer.

func (*Summarizer) Finalize

func (s *Summarizer) Finalize() *Summary

Finalize indicates to the summarizer that we're done processing the trace. It cleans up any remaining state and returns the full summary.

type Summary

Summary is the analysis result produced by the summarizer.

type Summary struct {
    Goroutines map[tracev2.GoID]*GoroutineSummary
    Tasks      map[tracev2.TaskID]*UserTaskSummary
}

type UserRegionDesc

UserRegionDesc represents a region and goroutine execution stats while the region was active.

type UserRegionDesc struct {
    TaskID uint64
    Name   string

    // Region start event. Normally EvUserRegion start event or nil,
    // but can be EvGoCreate event if the region is a synthetic
    // region representing task inheritance from the parent goroutine.
    Start *Event

    // Region end event. Normally EvUserRegion end event or nil,
    // but can be EvGoStop or EvGoEnd event if the goroutine
    // terminated without explicitly ending the region.
    End *Event

    GExecutionStat
}

type UserRegionSummary

UserRegionSummary represents a region and goroutine execution stats while the region was active. (For v2 traces.)

type UserRegionSummary struct {
    TaskID tracev2.TaskID
    Name   string

    // Region start event. Normally EventRegionBegin event or nil,
    // but can be a state transition event from NotExist or Undetermined
    // if the region is a synthetic region representing task inheritance
    // from the parent goroutine.
    Start *tracev2.Event

    // Region end event. Normally EventRegionEnd event or nil,
    // but can be a state transition event to NotExist if the goroutine
    // terminated without explicitly ending the region.
    End *tracev2.Event

    GoroutineExecStats
}

type UserTaskSummary

UserTaskSummary represents a task in the trace.

type UserTaskSummary struct {
    ID       tracev2.TaskID
    Name     string
    Parent   *UserTaskSummary // nil if the parent is unknown.
    Children []*UserTaskSummary

    // Task begin event. An EventTaskBegin event or nil.
    Start *tracev2.Event

    // End end event. Normally EventTaskEnd event or nil.
    End *tracev2.Event

    // Logs is a list of tracev2.EventLog events associated with the task.
    Logs []*tracev2.Event

    // List of regions in the task, sorted based on the start time.
    Regions []*UserRegionSummary

    // Goroutines is the set of goroutines associated with this task.
    Goroutines map[tracev2.GoID]*GoroutineSummary
}

func (*UserTaskSummary) Complete

func (s *UserTaskSummary) Complete() bool

Complete returns true if we have complete information about the task from the trace: both a start and an end.

func (*UserTaskSummary) Descendents

func (s *UserTaskSummary) Descendents() []*UserTaskSummary

Descendents returns a slice consisting of itself (always the first task returned), and the transitive closure of all of its children.

type UtilFlags

UtilFlags controls the behavior of MutatorUtilization.

type UtilFlags int
const (
    // UtilSTW means utilization should account for STW events.
    // This includes non-GC STW events, which are typically user-requested.
    UtilSTW UtilFlags = 1 << iota
    // UtilBackground means utilization should account for
    // background mark workers.
    UtilBackground
    // UtilAssist means utilization should account for mark
    // assists.
    UtilAssist
    // UtilSweep means utilization should account for sweeping.
    UtilSweep

    // UtilPerProc means each P should be given a separate
    // utilization function. Otherwise, there is a single function
    // and each P is given a fraction of the utilization.
    UtilPerProc
)

type UtilWindow

UtilWindow is a specific window at Time.

type UtilWindow struct {
    Time int64
    // MutatorUtil is the mean mutator utilization in this window.
    MutatorUtil float64
}

type Writer

Writer is a test trace writer.

type Writer struct {
    bytes.Buffer
}

func NewWriter

func NewWriter() *Writer

func (*Writer) Emit

func (w *Writer) Emit(typ byte, args ...uint64)

Emit writes an event record to the trace. See Event types for valid types and required arguments.