trace

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

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

Go to latest
Published: Oct 20, 2015 License: MIT Imports: 9 Imported by: 8

README

Trace package GoDoc

Trace is a golang package that implements a distributed tracing capability inspired by Google's Dapper. Traces may be optionally recorded to a database backend or local file. HTTP middleware is provided to facilitate easy tracing of requests and cascading of trace contexts during request fanout scenarios.

To install the package:

$ go get github.com/SpirentOrion/trace

Tracing Data Model

Each trace is logically comprised of one or more spans in a tree-like structure. You are free to determine the granularity of traces and spans. Typical usages include:

  • Each request received at a web API endpoint starts a new trace.
  • Each scheduled background task starts a new trace.
  • Each span represents some type of start-to-finish activity. By creating new spans you can differentiate between different types or stages of activity within a single trace.

Traces are identified by a probabilistically unique 64-bit integer. All spans within in a trace share the same trace id. Identifiers are randomly generated within this number space and thus do not require use of a centralized allocator.

Spans are also identified by their own unique 64-bit integer values. Each span records its trace id, the id of its parent span, its location, its start time, its finish time, and other data that you may provide.

With this structure it is possible to build a causal record of activity within trace. For any trace, activity began with the first span -- the span with a parent id of 0. Any spans within the same trace that have a parent id matching the first span's id were caused by the first span. And so on.

If processing of a span requires fanout to other services or processes the trace context may be propagated using HTTP request headers or other appropriate mechanisms. Each span's location indicates where the activity actually occurred, in terms of both process and hostname. When activity spans multiple hosts, start and finish times are based on the host's clock and aren't necessarily synchronized.

Recording Backends

Currently, two recording backend packages are provided:

Backend Import Path
DynamoDB github.com/SpirentOrion/trace/dynamorec
YAML github.com/SpirentOrion/trace/yamlrec

Example

A simple example is provided with trace recording via the YAML recorder:

$ cd $GOPATH/src/github.com/SpirentOrion/trace/example
$ go run main.go

Separately:

$ curl -i http://127.0.0.1/foo/bar
$ cat example.yaml

Note that the YAML recorder only records finished spans. Each span is rendered as a separate document in the YAML stream.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// Process is process name used when New or Continue create new Spans.
	Process string
)

Functions

func CurrentSpanId

func CurrentSpanId() int64

CurrentSpanId returns the caller's current span id.

func CurrentTraceId

func CurrentTraceId() int64

CurrentTraceId returns the caller's current trace id.

func GenerateId

func GenerateId() (int64, error)

GenerateId returns a probablistically unique 64-bit id. All id values returned by this function will be positive integers. This may be useful for callers that want to generate their own id values.

func Go

func Go(s *Span, f func())

Go functions similarly to Run, except that f is run in a new goroutine.

func Record

func Record(rec Recorder, buffer int, logger Logger) error

Record starts recording in a goroutine. Because Run must not be allowed to block, buffer must be greater than zero. If a Logger is provided, then errors that occur during recording will be logged.

func Run

func Run(s *Span, f func())

Run records a Span (to provide visibility that the span has started), invokes the function f, and then records the Span a second time (to update the finish time).

Types

type Handler

type Handler struct {
	// Kind is the kind value used when starting new traces.
	Kind string
	// HeaderKey is the key used when ServeHTTP inserts an id header in requests or responses.
	HeaderKey string
	// HonorReqHeader determines whether or not ServeHTTP honors id headers in requests.
	HonorReqHeader bool
	// AddRespHeader determines whether or not ServeHTTP adds id headers to responses.
	AddRespHeader bool
}

func NewHandler

func NewHandler() *Handler

NewHandler creates a middleware handler that facilitates HTTP request tracing.

If the request contains an id header and HonorReqHeader is true, then the id values are used (allowing trace contexts to span services). Otherwise a new trace id is generated. An id header is optionally added to the response.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(rw http.ResponseWriter, req *http.Request, next http.HandlerFunc)

type Logger

type Logger interface {
	Println(v ...interface{})
}

Logger is an interface compatible with log.Logger.

type Recorder

type Recorder interface {
	Record(s *Span) error
}

Recorder instances persist Spans to an external datastore.

type Span

type Span struct {
	SpanId    int64                  `yaml:"span_id"`
	TraceId   int64                  `yaml:"trace_id"`
	ParentId  int64                  `yaml:"parent_id"`
	Process   string                 `yaml:",omitempty"`
	Kind      string                 `yaml:",omitempty"`
	Name      string                 `yaml:",omitempty"`
	Start     time.Time              `yaml:"-"`
	StartStr  string                 `yaml:"start,omitempty"`
	Finish    time.Time              `yaml:"-"`
	FinishStr string                 `yaml:"finish,omitempty"`
	DataMap   map[string]interface{} `yaml:",omitempty,inline"`
}

Span tracks a processing activity within a trace.

func Continue

func Continue(kind string, name string) (*Span, error)

Continue continues an existing trace. If recording is active, a new Span instance is allocated and returned, otherwise no allocation occurs and nil is returned (along with an error).

func MaybeContinue

func MaybeContinue(kind string, name string) *Span

MaybeContinue continues an existing trace but ignores errors.

func MaybeNew

func MaybeNew(traceId int64, kind string, name string) *Span

MaybeNew starts a new trace but ignores errors.

func New

func New(traceId int64, kind string, name string) (*Span, error)

New starts a new trace. If recording is active, a new Span is allocated and returned, otherwise no allocation occurs and nil is returned (along with an error).

As a caller convenience, if traceId is non-zero, then that value is used instead of generating a probablistically unique id. This may be useful for callers that want to generate their own id values.

func (*Span) Data

func (s *Span) Data() map[string]interface{}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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