o11y

package
v1.0.6154-6687da4 Latest Latest
Warning

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

Go to latest
Published: Mar 16, 2023 License: MIT Imports: 11 Imported by: 5

Documentation

Overview

Package o11y core of the ex observability system, currently backed by Honeycomb's libhoney.

There are automatic tracing wrappers for both the standard Go HTTP server and for Gin.

Package o11y provides observability in the form of tracing and metrics

Example (EndDefer)

ExampleEndDefer shows the correct way to capture the error named return.

package main

import (
	"context"
	"fmt"
	"net"

	"github.com/circleci/ex/o11y"
)

type Worker struct{}

// Work must use named returns for the defer to capture the return value correctly.
func (w *Worker) Work(ctx context.Context) (err error) {
	ctx, span := o11y.StartSpan(ctx, "job-store: job-info")
	defer o11y.End(span, &err) // the pointer is needed to grab the changing content of the returned error.
	span.AddField("add-other", "fields as needed")
	o11y.AddField(ctx, "also-via", "context")

	// Do some work, using the modified context
	if _, err := (&net.Dialer{}).DialContext(ctx, "tcp", "localhost:80"); err != nil {
		return fmt.Errorf("i am the error the span.End call will use: %w", err)
	}

	return nil
}

// ExampleEndDefer shows the correct way to capture the error named return.
func main() {
	ctx := context.Background()
	w := Worker{}
	_ = w.Work(ctx)
}
Output:

Index

Examples

Constants

View Source
const (
	MetricTimer = "timer"
	MetricGauge = "gauge"
	MetricCount = "count"
)

Variables

This section is empty.

Functions

func AddField

func AddField(ctx context.Context, key string, val interface{})

AddField adds a field to the currently active span

func AddFieldToTrace

func AddFieldToTrace(ctx context.Context, key string, val interface{})

AddFieldToTrace adds a field to the currently active root span and all of its current and future child spans

func AddResultToSpan

func AddResultToSpan(span Span, err error)

AddResultToSpan takes a possibly nil error, and updates the "error" and "result" fields of the span appropriately.

func DontErrorTrace

func DontErrorTrace(err error) bool

DontErrorTrace returns true if all errors in the chain is a warning or context canceled or context deadline errors.

func End

func End(span Span, err *error)

End completes a span, including using AddResultToSpan to set the error and result fields

The correct way to capture the returned error is given in the doc example, it is like this.. defer o11y.End(span, &err)

Using the unusual pointer to the interface means that clients can call defer on End early, typically on the next line after calling StartSpan as it will capture the address of the named return error at that point. Any further assignments are made to the pointed to data, so that when our End func dereferences the pointer we get the last assigned error as desired.

func HandlePanic

func HandlePanic(ctx context.Context, span Span, panic interface{}, r *http.Request) (err error)

func IsWarning

func IsWarning(err error) bool

IsWarning returns true if any error in the chain is a warning.

func IsWarningNoUnwrap

func IsWarningNoUnwrap(err error) bool

IsWarningNoUnwrap returns true if err itself is a warning. This will not check wrapped errors. This can be used in Is in other errors to check if it is being directly tested for warning.

func Log

func Log(ctx context.Context, name string, fields ...Pair)

Log sends a zero duration trace event.

func LogError

func LogError(ctx context.Context, name string, err error, fields ...Pair)

LogError sends a zero duration trace event with an error.

func NewWarning

func NewWarning(warn string) error

NewWarning will return a generic error that can be tested for warning. No two errors created with NewWarning will be tested as equal with Is.

func WithBaggage

func WithBaggage(ctx context.Context, baggage Baggage) context.Context

func WithProvider

func WithProvider(ctx context.Context, p Provider) context.Context

WithProvider returns a child context which contains the Provider. The Provider can be retrieved with FromContext.

Types

type Baggage

type Baggage map[string]string

Baggage is a map of values used for telemetry purposes. See: https://github.com/open-telemetry/opentelemetry-specification/blob/14b5b6a944e390e368dd2e2ef234d220d8287d19/specification/baggage/api.md

func DeserializeBaggage

func DeserializeBaggage(s string) (Baggage, error)

func GetBaggage

func GetBaggage(ctx context.Context) Baggage

func (*Baggage) Scan

func (b *Baggage) Scan(value interface{}) error

Scan satisfies the `Scanner` interface to allow the database driver to un-marshall it back into a struct from the JSON blob in the database.

type ClosableMetricsProvider

type ClosableMetricsProvider interface {
	MetricsProvider
	io.Closer
}

type Helpers

type Helpers interface {
	// ExtractPropagation pulls propagation information out of the context
	ExtractPropagation(ctx context.Context) PropagationContext
	// InjectPropagation adds propagation header fields into the returned root span returning
	// the context carrying that span
	InjectPropagation(context.Context, PropagationContext) (context.Context, Span)
	// TraceIDs return standard o11y ids
	TraceIDs(ctx context.Context) (traceID, parentID string)
}

type Metric

type Metric struct {
	Type MetricType
	// Name is the metric name that will be emitted
	Name string
	// Field is the span field to use as the metric's value
	Field string
	// FixedTag is an optional tag added at Metric definition time
	FixedTag *Tag
	// TagFields are additional span fields to use as metric tags
	TagFields []string
}

func Count

func Count(name string, valueField string, fixedTag *Tag, tagFields ...string) Metric

func Duration

func Duration(name string, valueField string, fields ...string) Metric

func Gauge

func Gauge(name string, valueField string, tagFields ...string) Metric

func Incr

func Incr(name string, fields ...string) Metric

func Timing

func Timing(name string, fields ...string) Metric

type MetricType

type MetricType string

type MetricsProvider

type MetricsProvider interface {
	// Histogram aggregates values agent side for a period of time.
	// This is similar to TimeInMilliseconds, but not limited to timing data
	Histogram(name string, value float64, tags []string, rate float64) error
	// TimeInMilliseconds measures timing data only. For example, how long a network call takes
	TimeInMilliseconds(name string, value float64, tags []string, rate float64) error
	// Gauge measures the value of a metric at a particular time.
	Gauge(name string, value float64, tags []string, rate float64) error
	// Count sends an individual value in time.
	Count(name string, value int64, tags []string, rate float64) error
}

type Pair

type Pair struct {
	Key   string
	Value interface{}
}

Pair is a key value pair used to add metadata to a span.

func Field

func Field(key string, value interface{}) Pair

Field returns a new metadata pair.

type PropagationContext

type PropagationContext struct {
	// Parent contains single string serialisation of just the trace parent fields
	Parent string
	// Headers contains the map of all context propagation headers
	Headers map[string]string
}

PropagationContext contains trace context values that are propagated from service to service. Typically, the Parent field is also present as a value in the Headers map. This seeming DRY breakage is so the special value for the field name of the Parent trace ID is not leaked, and accidentally depended upon.

func PropagationContextFromHeader

func PropagationContextFromHeader(h http.Header) PropagationContext

PropagationContextFromHeader is a helper constructs a PropagationContext from h. It is not filtered to the headers needed for propagation. It is expected to be used as the input to InjectPropagation.

type Provider

type Provider interface {
	// AddGlobalField adds data which should apply to every span in the application
	//
	// eg. version, service, k8s_replicaset
	AddGlobalField(key string, val interface{})

	// StartSpan begins a new span that'll represent a unit of work
	//
	// `name` should be a short human readable identifier of the work.
	// It can and should include some details to distinguish it from other
	// similar spans - like the URL or the DB query name.
	//
	// The caller is responsible for calling End(), usually via defer:
	//
	//   ctx, span := o11y.StartSpan(ctx, "GET /help")
	//   defer span.End()
	StartSpan(ctx context.Context, name string) (context.Context, Span)

	// GetSpan returns the currently active span
	GetSpan(ctx context.Context) Span

	// AddField is for adding application-level information to the currently active span
	//
	// Any field name will be prefixed with "app."
	AddField(ctx context.Context, key string, val interface{})

	// AddFieldToTrace is for adding useful information to the root span.
	//
	// This will be propagated onto every child span.
	//
	// eg. build-url, plan-id, project-id, org-id etc
	AddFieldToTrace(ctx context.Context, key string, val interface{})

	// Log sends a zero duration trace event.
	Log(ctx context.Context, name string, fields ...Pair)

	Close(ctx context.Context)

	// MetricsProvider grants lower control over the metrics that o11y sends, allowing skipping spans.
	MetricsProvider() MetricsProvider

	// Helpers returns some specific helper functions
	Helpers() Helpers
}

func FromContext

func FromContext(ctx context.Context) Provider

FromContext returns the provider stored in the context, or nil if none exists.

type Span

type Span interface {
	// AddField is for adding application-level information to the span
	//
	// Any field name will be prefixed with "app."
	AddField(key string, val interface{})

	// AddRawField is for adding useful information to the span in library/plumbing code
	// Generally application code should prefer AddField() to avoid namespace clashes
	//
	// eg. result, http.status_code, db.system etc
	//
	// Refer to the opentelemetry draft spec for naming inspiration
	// https://github.com/open-telemetry/opentelemetry-specification/tree/7ae3d066c95c716ef3086228ef955d84ba03ac88/specification/trace/semantic_conventions
	AddRawField(key string, val interface{})

	// RecordMetric tells the provider to emit a metric to its metric backend when the span ends
	RecordMetric(metric Metric)

	// End sets the duration of the span and tells the related provider that the span is complete,
	// so it can do its appropriate processing. The span should not be used after End is called.
	End()
}

func StartSpan

func StartSpan(ctx context.Context, name string) (context.Context, Span)

StartSpan starts a span from a context that must contain a provider for this to have any effect.

type Tag

type Tag struct {
	Name  string
	Value interface{}
}

func NewTag

func NewTag(name string, value interface{}) *Tag

Directories

Path Synopsis
Package honeycomb implements o11y tracing.
Package honeycomb implements o11y tracing.
wrappers
baggage
Package baggage contains the internal implementation of the o11y baggage.
Package baggage contains the internal implementation of the o11y baggage.
o11ygin
Package o11ygin contains middleware for the Gin router.
Package o11ygin contains middleware for the Gin router.
o11ynethttp
Package o11ynethttp contains middleware for the standard Go HTTP server.
Package o11ynethttp contains middleware for the standard Go HTTP server.

Jump to

Keyboard shortcuts

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