github.com/corona10/go@v0.0.0-20180224231303-7a218942be57/src/runtime/trace/trace.go (about) 1 // Copyright 2015 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 contains facilities for programs to generate trace 6 // for Go execution tracer. 7 // 8 // Tracing runtime activities 9 // 10 // The execution trace captures a wide range of execution events such as 11 // goroutine creation/blocking/unblocking, syscall enter/exit/block, 12 // GC-related events, changes of heap size, processor start/stop, etc. 13 // A precise nanosecond-precision timestamp and a stack trace is 14 // captured for most events. The generated trace can be interpreted 15 // using `go tool trace`. 16 // 17 // Support for tracing tests and benchmarks built with the standard 18 // testing package is built into `go test`. For example, the following 19 // command runs the test in the current directory and writes the trace 20 // file (trace.out). 21 // 22 // go test -trace=test.out 23 // 24 // This runtime/trace package provides APIs to add equivalent tracing 25 // support to a standalone program. See the Example that demonstrates 26 // how to use this API to enable tracing. 27 // 28 // There is also a standard HTTP interface to trace data. Adding the 29 // following line will install a handler under the /debug/pprof/trace URL 30 // to download a live trace: 31 // 32 // import _ "net/http/pprof" 33 // 34 // See the net/http/pprof package for more details about all of the 35 // debug endpoints installed by this import. 36 // 37 // User annotation 38 // 39 // Package trace provides user annotation APIs that can be used to 40 // log interesting events during execution. 41 // 42 // There are three types of user annotations: log messages, spans, 43 // and tasks. 44 // 45 // Log emits a timestamped message to the execution trace along with 46 // additional information such as the category of the message and 47 // which goroutine called Log. The execution tracer provides UIs to filter 48 // and group goroutines using the log category and the message supplied 49 // in Log. 50 // 51 // A span is for logging a time interval during a goroutine's execution. 52 // By definition, a span starts and ends in the same goroutine. 53 // Spans can be nested to represent subintervals. 54 // For example, the following code records four spans in the execution 55 // trace to trace the durations of sequential steps in a cappuccino making 56 // operation. 57 // 58 // trace.WithSpan(ctx, "makeCappuccino", func(ctx context.Context) { 59 // 60 // // orderID allows to identify a specific order 61 // // among many cappuccino order span records. 62 // trace.Log(ctx, "orderID", orderID) 63 // 64 // trace.WithSpan(ctx, "steamMilk", steamMilk) 65 // trace.WithSpan(ctx, "extractCoffee", extractCoffee) 66 // trace.WithSpan(ctx, "mixMilkCoffee", mixMilkCoffee) 67 // }) 68 // 69 // A task is a higher-level component that aids tracing of logical 70 // operations such as an RPC request, an HTTP request, or an 71 // interesting local operation which may require multiple goroutines 72 // working together. Since tasks can involve multiple goroutines, 73 // they are tracked via a context.Context object. NewContext creates 74 // a new task and embeds it in the returned context.Context object. 75 // Log messages and spans are attached to the task, if any, in the 76 // Context passed to Log and WithSpan. 77 // 78 // For example, assume that we decided to froth milk, extract coffee, 79 // and mix milk and coffee in separate goroutines. With a task, 80 // the trace tool can identify the goroutines involved in a specific 81 // cappuccino order. 82 // 83 // ctx, taskEnd:= trace.NewContext(ctx, "makeCappuccino") 84 // trace.Log(ctx, "orderID", orderID) 85 // 86 // milk := make(chan bool) 87 // espresso := make(chan bool) 88 // 89 // go func() { 90 // trace.WithSpan(ctx, "steamMilk", steamMilk) 91 // milk<-true 92 // })() 93 // go func() { 94 // trace.WithSpan(ctx, "extractCoffee", extractCoffee) 95 // espresso<-true 96 // })() 97 // go func() { 98 // defer taskEnd() // When assemble is done, the order is complete. 99 // <-espresso 100 // <-milk 101 // trace.WithSpan(ctx, "mixMilkCoffee", mixMilkCoffee) 102 // })() 103 // 104 // The trace tool computes the latency of a task by measuring the 105 // time between the task creation and the task end and provides 106 // latency distributions for each task type found in the trace. 107 package trace 108 109 import ( 110 "io" 111 "runtime" 112 "sync" 113 "sync/atomic" 114 ) 115 116 // Start enables tracing for the current program. 117 // While tracing, the trace will be buffered and written to w. 118 // Start returns an error if tracing is already enabled. 119 func Start(w io.Writer) error { 120 tracing.Lock() 121 defer tracing.Unlock() 122 123 if err := runtime.StartTrace(); err != nil { 124 return err 125 } 126 go func() { 127 for { 128 data := runtime.ReadTrace() 129 if data == nil { 130 break 131 } 132 w.Write(data) 133 } 134 }() 135 atomic.StoreInt32(&tracing.enabled, 1) 136 return nil 137 } 138 139 // Stop stops the current tracing, if any. 140 // Stop only returns after all the writes for the trace have completed. 141 func Stop() { 142 tracing.Lock() 143 defer tracing.Unlock() 144 atomic.StoreInt32(&tracing.enabled, 0) 145 146 runtime.StopTrace() 147 } 148 149 var tracing struct { 150 sync.Mutex // gate mutators (Start, Stop) 151 enabled int32 // accessed via atomic 152 }