github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/internal/trace/summary.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package trace 6 7 import ( 8 "github.com/shogo82148/std/time" 9 ) 10 11 // Summary is the analysis result produced by the summarizer. 12 type Summary struct { 13 Goroutines map[tracev2.GoID]*GoroutineSummary 14 Tasks map[tracev2.TaskID]*UserTaskSummary 15 } 16 17 // GoroutineSummary contains statistics and execution details of a single goroutine. 18 // (For v2 traces.) 19 type GoroutineSummary struct { 20 ID tracev2.GoID 21 Name string 22 PC uint64 23 CreationTime tracev2.Time 24 StartTime tracev2.Time 25 EndTime tracev2.Time 26 27 // List of regions in the goroutine, sorted based on the start time. 28 Regions []*UserRegionSummary 29 30 // Statistics of execution time during the goroutine execution. 31 GoroutineExecStats 32 33 // goroutineSummary is state used just for computing this structure. 34 // It's dropped before being returned to the caller. 35 // 36 // More specifically, if it's nil, it indicates that this summary has 37 // already been finalized. 38 *goroutineSummary 39 } 40 41 // UserTaskSummary represents a task in the trace. 42 type UserTaskSummary struct { 43 ID tracev2.TaskID 44 Name string 45 Parent *UserTaskSummary 46 Children []*UserTaskSummary 47 48 // Task begin event. An EventTaskBegin event or nil. 49 Start *tracev2.Event 50 51 // End end event. Normally EventTaskEnd event or nil. 52 End *tracev2.Event 53 54 // Logs is a list of tracev2.EventLog events associated with the task. 55 Logs []*tracev2.Event 56 57 // List of regions in the task, sorted based on the start time. 58 Regions []*UserRegionSummary 59 60 // Goroutines is the set of goroutines associated with this task. 61 Goroutines map[tracev2.GoID]*GoroutineSummary 62 } 63 64 // Complete returns true if we have complete information about the task 65 // from the trace: both a start and an end. 66 func (s *UserTaskSummary) Complete() bool 67 68 // Descendents returns a slice consisting of itself (always the first task returned), 69 // and the transitive closure of all of its children. 70 func (s *UserTaskSummary) Descendents() []*UserTaskSummary 71 72 // UserRegionSummary represents a region and goroutine execution stats 73 // while the region was active. (For v2 traces.) 74 type UserRegionSummary struct { 75 TaskID tracev2.TaskID 76 Name string 77 78 // Region start event. Normally EventRegionBegin event or nil, 79 // but can be a state transition event from NotExist or Undetermined 80 // if the region is a synthetic region representing task inheritance 81 // from the parent goroutine. 82 Start *tracev2.Event 83 84 // Region end event. Normally EventRegionEnd event or nil, 85 // but can be a state transition event to NotExist if the goroutine 86 // terminated without explicitly ending the region. 87 End *tracev2.Event 88 89 GoroutineExecStats 90 } 91 92 // GoroutineExecStats contains statistics about a goroutine's execution 93 // during a period of time. 94 type GoroutineExecStats struct { 95 // These stats are all non-overlapping. 96 ExecTime time.Duration 97 SchedWaitTime time.Duration 98 BlockTimeByReason map[string]time.Duration 99 SyscallTime time.Duration 100 SyscallBlockTime time.Duration 101 102 // TotalTime is the duration of the goroutine's presence in the trace. 103 // Necessarily overlaps with other stats. 104 TotalTime time.Duration 105 106 // Total time the goroutine spent in certain ranges; may overlap 107 // with other stats. 108 RangeTime map[string]time.Duration 109 } 110 111 func (s GoroutineExecStats) NonOverlappingStats() map[string]time.Duration 112 113 // UnknownTime returns whatever isn't accounted for in TotalTime. 114 func (s GoroutineExecStats) UnknownTime() time.Duration 115 116 // Summarizer constructs per-goroutine time statistics for v2 traces. 117 type Summarizer struct { 118 // gs contains the map of goroutine summaries we're building up to return to the caller. 119 gs map[tracev2.GoID]*GoroutineSummary 120 121 // tasks contains the map of task summaries we're building up to return to the caller. 122 tasks map[tracev2.TaskID]*UserTaskSummary 123 124 // syscallingP and syscallingG represent a binding between a P and G in a syscall. 125 // Used to correctly identify and clean up after syscalls (blocking or otherwise). 126 syscallingP map[tracev2.ProcID]tracev2.GoID 127 syscallingG map[tracev2.GoID]tracev2.ProcID 128 129 // rangesP is used for optimistic tracking of P-based ranges for goroutines. 130 // 131 // It's a best-effort mapping of an active range on a P to the goroutine we think 132 // is associated with it. 133 rangesP map[rangeP]tracev2.GoID 134 135 lastTs tracev2.Time 136 syncTs tracev2.Time 137 } 138 139 // NewSummarizer creates a new struct to build goroutine stats from a trace. 140 func NewSummarizer() *Summarizer 141 142 // Event feeds a single event into the stats summarizer. 143 func (s *Summarizer) Event(ev *tracev2.Event) 144 145 // Finalize indicates to the summarizer that we're done processing the trace. 146 // It cleans up any remaining state and returns the full summary. 147 func (s *Summarizer) Finalize() *Summary 148 149 // RelatedGoroutinesV2 finds a set of goroutines related to goroutine goid for v2 traces. 150 // The association is based on whether they have synchronized with each other in the Go 151 // scheduler (one has unblocked another). 152 func RelatedGoroutinesV2(events []tracev2.Event, goid tracev2.GoID) map[tracev2.GoID]struct{}