trace

package module
v0.0.0-...-d282251 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 3, 2018 License: Apache-2.0 Imports: 8 Imported by: 0

README

Installation

To install this package, clone it under your $GOPATH/src/ directory.

Usage

Package trace allows debugging programs via trace statements inserted in code. Sometimes you need to see the sequence in which functions are called, and stepping through each manually with a debugger is not the appropriate answer. If you've ever sprinkled "Printf" statements throughout your code to get insight into what's happenning, this package is strictly better: in addition to printing the messages you specify, it denotes the structure of the stack by appropriately indenting them (and indenting the names of the callers), and printing time stamps of when the trace calls occurred.

Tracing is as simple as inserting a Trace statements where you want to do the tracing. These statements will print all the currrent stack frames to the most recent previously traced stack frame that is on the current stack.

trace.Trace()

You may also pass printf-style arguments to Trace to display interesting state of your program:

trace("Label: my var=%v", myvar)

You should turn on tracing before the point in your program where you want to trace. If you want to trace a package init() function, turn it on there. This function call is idempotent. It is merely a shorthand for setting Global.On:

trace.On(true)

You may also turn off tracing at any point you wish:

trace.On(false)

In fact, you may change many of the seetings of an active Tracer object by modifying them directly. For example, to make global tracer only trace the last reported goroutine, use

trace.Global.LockGoRoutine = true

While in most cases you'll want to use the trace.Global logger (accessible directly and through the trace.Trace function), you can also create custom Tracer objects and use them via Tracer.Trace().

Tracer is concurrency-safe. When Trace() is called from a different goroutine than its previous call, it prints a warning about a goroutine switch. Optionally, it can print just the current goroutine stack frame including frames recorded earlier (if OnGoroutineSwitchPrintCurrentStack is set; default is false in Global), or print the entire history of the stack for this goroutine (if OnGoroutineSwitchPrintStackHistory is set; default is true in Global).

Disclaimer

This is not an officially supported Google product.

Documentation

Overview

Package trace allows debugging programs via trace statements inserted in code. Sometimes you need to see the sequence in which functions are called, and stepping through each manually with a debugger is not the appropriate answer. If you've ever sprinkled "Printf" statements throughout your code to get insight into what's happenning, this package is strictly better: in addition to printing the messages you specify, it denotes the structure of the stack by appropriately indenting them (and indenting the names of the callers), and printing time stamps of when the trace calls occurred.

Tracing is as simple as inserting a Trace statements where you want to do the tracing. These statements will print all the currrent stack frames to the most recent previously traced stack frame that is on the current stack.

trace.Trace()

You may also pass Printf-style arguments to Trace to display interesting state of your program:

trace("Label: my var=%v", myvar)

You should turn on tracing before the point in your program where you want to trace. If you want to trace a package init() function, turn it on there. This function call is idempotent. It is merely a shorthand for setting Global.On:

trace.On(true)

You may also turn off tracing at any point you wish:

trace.On(false)

In fact, you may change many of the seetings of an active Tracer object by modifying them directly. For example, to make global tracer only trace the last reported goroutine, use

trace.Global.LockGoRoutine = true

While in most cases you'll want to use the trace.Global logger (accessible directly and through the trace.Trace function), you can also create custom Tracer objects and use them via Tracer.Trace().

Tracer is concurrency-safe. When Trace() is called from a different goroutine than its previous call, it prints a warning about a goroutine switch. Optionally, it can print just the current goroutine stack frame including frames recorded earlier (if OnGoroutineSwitchPrintCurrentStack is set; default is false in Global), or print the entire history of the stack for this goroutine (if OnGoroutineSwitchPrintStackHistory is set; default is true in Global).

Example
package main

import (
	"time"
	"trace"
)

func a(n string) {
	trace.Trace("Alice: [%s]", n)
}

func b(n string) {
	trace.Trace("Barb! [%s]", n)
	for i := 1; i < 5; i++ {
		time.Sleep(10 * time.Millisecond)
		a("barb " + n)
	}
	trace.Trace("Bob! [%s]", n)
	for i := 1; i < 5; i++ {
		time.Sleep(10 * time.Millisecond)
		a("bob " + n)
	}
	trace.Trace("Blaise! [%s]", n)
}
func d(n string) {
	trace.Trace("Dely! [%s]", n)
	for i := 1; i < 5; i++ {
		trace.Trace()
	}
	trace.Trace("Dan! [%s]", n)
}

func c(n string) {
	trace.Trace("Carol before [%s]", n)
	time.Sleep(50 * time.Millisecond)
	a("carol " + n)
	trace.Trace("Carol after [%s]", n)

}

func main() {
	trace.Global.On = true
	trace.Trace("Start")
	c("one")

	if true {
		go a("two")
		go c("three")
		go b("four")
		go b("five")
	} else {
		a("six")
		c("seven")
		b("eight")
		b("nine")
	}
	a("ten")
	d("eleven")

	trace.Trace("The end!")
	time.Sleep(5 * time.Second)
}

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func GoroutineID

func GoroutineID() int

GoroutineID returns the numerical ID of the currently running goroutine.

func On

func On(on bool)

On turns tracing with the global debugger on or off. It's nothing more than a shorthand for setting Global.On manually.

func Trace

func Trace(args ...interface{})

Trace prints out the call stack of the current goroutine. The top stack frame is annotated with `args`, which are interpreted as parameters to fmt.Printf().

Example
package main

import (
	"trace"
)

func main() {
	trace.On(true)
	trace.Trace("First")
	func() {
		trace.Trace("Third")
	}()
	trace.Trace("Second")
}

func TruncateError

func TruncateError(err error, max int) string

TruncateError returns the string representation of `err` truncated to `max` characters.

Types

type FrameInfo

type FrameInfo struct {
	runtime.Frame

	// The time at which this stack frame was recorded. Note that
	// parent functions up the stack (until the previous call to
	// Trace()) will have the same TimeRecorded because they were
	// recorded at the same time, even though they were actually
	// entered at different times.
	TimeRecorded time.Time
}

func (*FrameInfo) Copy

func (fr *FrameInfo) Copy() *FrameInfo

Copy returns a deep copy of `fr`.

func (*FrameInfo) Equal

func (fr *FrameInfo) Equal(other *FrameInfo) bool

Equal returns true if `fr` is identical to `other`.

func (*FrameInfo) Same

func (fr *FrameInfo) Same(other *FrameInfo) bool

Same returns true if fr.Frame and other.Frame are equal.

type GoroutineInfo

type GoroutineInfo struct {
	// ID holds the numerical ID of this subroutine.
	ID int

	// Frames is a list of the current stack frames, with the top
	// of the stack being the 0th element.
	Frames []*FrameInfo

	// TopMessage is the message, if any, logged on the last call
	// to Trace() on this goroutine.
	//
	// Note that only the top frame in the current stack at any
	// moment could possibly have a message. All the previous
	// stack frames are by necessity from a function call site,
	// not from a Trace() call site, so they cannot have any
	// messages in them. As a result, we store the topMessage once
	// per goroutine rather than having mostly empty fields in
	// frames
	TopMessage string

	// History holds all the logging entries ever written for this
	// goroutine.
	History []string
}

func (*GoroutineInfo) Copy

func (gi *GoroutineInfo) Copy() *GoroutineInfo

Copy returns a deep copy of `gi`.

type Logger

type Logger interface {
	Printf(format string, v ...interface{})
	Println(v ...interface{})
}

Logger defines the output functionality needed by Tracer. Note that log.Logger satisfies this interface.

type Tracer

type Tracer struct {
	// On determines whether the Tracer is active or not.
	On bool

	// Out receives the output of the Trace() calls.
	Out Logger

	// Capacity holds the maximum stack size we can accomodate.
	Capacity int

	// SourceLength holds the maxium displayed length,
	// right-justified, of the string specifying the source code
	// file name and line number. The
	SourceLength int

	// LockGoroutine causes Trace() to only record and emit output
	// for the current (ie last invoking) goroutine.
	LockGoroutine bool

	// OmitTime causes Tracer to not output date/time info. This
	// might be useful to shorten output lines if the Logger
	// specified in Out already displays time info. However, it is
	// recommended to leave this set to false so that accurate
	// time stamps are displayed when printing previously recorded
	// frames (if enabled via the OnGoroutinePrint* options).
	OmitTime bool

	// ClockFn is the function that will return the time used to
	// record when Trace() calls were invoked. If not specified,
	// time.Now will be used.
	ClockFn func() time.Time

	// OnGoroutineSwitchPrintCurrentStack prints out the current
	// state of the call stack when switching to a different
	// goroutine. Note that this does NOT print the whole History
	// of the stack for this goroutine.
	OnGoroutineSwitchPrintCurrentStack bool

	// OnGoroutineSwitchPrintStackHistory prints out the entire
	// history of the current call stack when switching to a
	// different goroutine.
	OnGoroutineSwitchPrintStackHistory bool
	// contains filtered or unexported fields
}

Tracer records and echoes the call stack when Trace() is invoked. The public parameters configure how Tracer operates, and may be changed at run time, in which case they take effect on the next call to Trace().

var Global *Tracer

Global is the global instance of Tracer, which can be easily accessed by the trace.Trace() function. The public parameters of Global may be changed dynamically and affect subsequent calls to Trace(). Refer to this module's init() function for more details.

func (*Tracer) Goroutines

func (tr *Tracer) Goroutines() map[int]*GoroutineInfo

Goroutines returns a map of goroutine IDs to GoroutineInfo objects reflecting the current state of `tr`. The returned map is a deep copy of the internal state of `tr`.

func (*Tracer) Trace

func (tr *Tracer) Trace(skip int, args ...interface{})

Trace records and echoes the state of the current goroutine's stack since the last time it was recorded. Those "new" entries are printed with a "+" marker. Previous entries on the call stack may be printed depending on the values of OnGoroutineSwitchPrintCurrentStack and OnGoroutineSwitchPrintStackHistory; those previous entries will NOT have a "+" marker.

Note that the output cannot distinguish between to consecutive calls to Trace from the same stack frame, vs two consecutive calls to Trace from sibling stack frames.

The parameter `skip` denotes the number of stack frames to skip in processing; a value of 0 denotes to start processing with the caller of this function as the top of the stack.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL