...

Source file src/runtime/trace/trace.go

Documentation: runtime/trace

		 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 traces
		 6  // for the 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=trace.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, regions,
		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 region is for logging a time interval during a goroutine's execution.
		52  // By definition, a region starts and ends in the same goroutine.
		53  // Regions can be nested to represent subintervals.
		54  // For example, the following code records four regions in the execution
		55  // trace to trace the durations of sequential steps in a cappuccino making
		56  // operation.
		57  //
		58  //	 trace.WithRegion(ctx, "makeCappuccino", func() {
		59  //
		60  //			// orderID allows to identify a specific order
		61  //			// among many cappuccino order region records.
		62  //			trace.Log(ctx, "orderID", orderID)
		63  //
		64  //			trace.WithRegion(ctx, "steamMilk", steamMilk)
		65  //			trace.WithRegion(ctx, "extractCoffee", extractCoffee)
		66  //			trace.WithRegion(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. NewTask creates
		74  // a new task and embeds it in the returned context.Context object.
		75  // Log messages and regions are attached to the task, if any, in the
		76  // Context passed to Log and WithRegion.
		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, task := trace.NewTask(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.WithRegion(ctx, "steamMilk", steamMilk)
		91  //							milk <- true
		92  //			}()
		93  //			go func() {
		94  //							trace.WithRegion(ctx, "extractCoffee", extractCoffee)
		95  //							espresso <- true
		96  //			}()
		97  //			go func() {
		98  //							defer task.End() // When assemble is done, the order is complete.
		99  //							<-espresso
	 100  //							<-milk
	 101  //							trace.WithRegion(ctx, "mixMilkCoffee", mixMilkCoffee)
	 102  //			}()
	 103  //
	 104  //
	 105  // The trace tool computes the latency of a task by measuring the
	 106  // time between the task creation and the task end and provides
	 107  // latency distributions for each task type found in the trace.
	 108  package trace
	 109  
	 110  import (
	 111  	"io"
	 112  	"runtime"
	 113  	"sync"
	 114  	"sync/atomic"
	 115  )
	 116  
	 117  // Start enables tracing for the current program.
	 118  // While tracing, the trace will be buffered and written to w.
	 119  // Start returns an error if tracing is already enabled.
	 120  func Start(w io.Writer) error {
	 121  	tracing.Lock()
	 122  	defer tracing.Unlock()
	 123  
	 124  	if err := runtime.StartTrace(); err != nil {
	 125  		return err
	 126  	}
	 127  	go func() {
	 128  		for {
	 129  			data := runtime.ReadTrace()
	 130  			if data == nil {
	 131  				break
	 132  			}
	 133  			w.Write(data)
	 134  		}
	 135  	}()
	 136  	atomic.StoreInt32(&tracing.enabled, 1)
	 137  	return nil
	 138  }
	 139  
	 140  // Stop stops the current tracing, if any.
	 141  // Stop only returns after all the writes for the trace have completed.
	 142  func Stop() {
	 143  	tracing.Lock()
	 144  	defer tracing.Unlock()
	 145  	atomic.StoreInt32(&tracing.enabled, 0)
	 146  
	 147  	runtime.StopTrace()
	 148  }
	 149  
	 150  var tracing struct {
	 151  	sync.Mutex			 // gate mutators (Start, Stop)
	 152  	enabled		int32 // accessed via atomic
	 153  }
	 154  

View as plain text