Documentation

Overview

Package profiling contains two logical components: buffer.go and profiling.go. The former implements a circular buffer (a.k.a. ring buffer) in a lock-free manner using atomics. This ring buffer is used by profiling.go to store various statistics. For example, StreamStats is a circular buffer of Stat objects, each of which is comprised of Timers.

This abstraction is designed to accommodate more stats in the future; for example, if one wants to profile the load balancing layer, which is independent of RPC queries, a separate CircularBuffer can be used.

Note that the circular buffer simply takes any interface{}. In the future, more types of measurements (such as the number of memory allocations) could be measured, which might require a different type of object being pushed into the circular buffer.

Index

Constants

This section is empty.

Variables

var StreamStats *buffer.CircularBuffer

StreamStats is a CircularBuffer containing data from the last N RPC calls served, where N is set by the user. This will contain both server stats and client stats (but each stat will be tagged with whether it's a server or a client in its Tags).


Functions

func Enable

func Enable(enabled bool)

Enable turns profiling on and off.

Note that it is impossible to enable profiling for one server and leave it turned off for another. This is intentional and by design -- if the status of profiling was server-specific, clients wouldn't be able to profile themselves. As a result, Enable turns profiling on and off for all servers and clients in the binary. Each stat will be, however, tagged with whether it's a client stat or a server stat; so you should be able to filter for the right type of stats in post-processing.

func InitStats

func InitStats(streamStatsSize uint32) error

InitStats initializes all the relevant Stat objects. Must be called exactly once per lifetime of a process; calls after the first one will return an error.

func IsEnabled

func IsEnabled() bool

IsEnabled returns whether or not profiling is enabled.

Types

type Stat

type Stat struct {
	// Tags is a comma-separated list of strings used to categorize a Stat.
	Tags string
	// Stats may also need to store other unstructured information specific to
	// this stat. For example, a StreamStat will use these bytes to encode the
	// connection ID and stream ID for each RPC to uniquely identify it. The
	// encoding that must be used is unspecified.
	Metadata []byte

	Timers []*Timer
	// contains filtered or unexported fields
}

A Stat is a collection of Timers that represent timing information for different components within this Stat. For example, a Stat may be used to reference the entire lifetime of an RPC request, with Timers within it representing different components such as encoding, compression, and transport.

The user is expected to use the included helper functions to do operations on the Stat such as creating or appending a new timer. Direct operations on the Stat's exported fields (which are exported for encoding reasons) may lead to data races.

func NewStat

func NewStat(tags string) *Stat

NewStat creates and returns a new Stat object.

func (*Stat) AppendTimer

func (stat *Stat) AppendTimer(timer *Timer)

AppendTimer appends a given Timer object to the internal slice of timers. A deep copy of the timer is made (i.e. no reference is retained to this pointer) and the user is expected to lose their reference to the timer to allow the Timer object to be garbage collected.

func (*Stat) NewTimer

func (stat *Stat) NewTimer(tags string) *Timer

NewTimer creates a Timer object within the given stat if stat is non-nil. The value passed in tags will be attached to the newly created Timer. NewTimer also automatically sets the Begin value of the Timer to the current time. The user is expected to call stat.Egress with the returned index as argument to mark the end.

type Timer

type Timer struct {
	// Tags is a comma-separated list of strings (usually forward-slash-separated
	// hierarchical strings) used to categorize a Timer.
	Tags string
	// Begin marks the beginning of this timer. The timezone is unspecified, but
	// must use the same timezone as End; this is so shave off the small, but
	// non-zero time required to convert to a standard timezone such as UTC.
	Begin time.Time
	// End marks the end of a timer.
	End time.Time
	// Each Timer must be started and ended within the same goroutine; GoID
	// captures this goroutine ID. The Go runtime does not typically expose this
	// information, so this is set to zero in the typical case. However, a
	// trivial patch to the runtime package can make this field useful. See
	// goid_modified.go in this package for more details.
	GoID int64
}

A Timer represents the wall-clock beginning and ending of a logical operation.

func NewTimer

func NewTimer(tags string) *Timer

NewTimer creates and returns a new Timer object. This is useful when you don't already have a Stat object to associate this Timer with; for example, before the context of a new RPC query is created, a Timer may be needed to measure transport-related operations.

Use AppendTimer to append the returned Timer to a Stat.

func (*Timer) Egress

func (timer *Timer) Egress()

Egress sets the End field of a timer to the current time.

Directories

Path Synopsis
buffer Package buffer provides a high-performant lock free implementation of a circular buffer used by the profiling code.