go-server-timing: github.com/mitchellh/go-server-timing Index | Files | Directories

package servertiming

import "github.com/mitchellh/go-server-timing"


Package Files

context.go header.go metric.go middleware.go


const HeaderKey = "Server-Timing"

HeaderKey is the specified key for the Server-Timing header.

func Middleware Uses

func Middleware(next http.Handler, opts *MiddlewareOpts) http.Handler

Middleware wraps an http.Handler and provides a *Header in the request context that can be used to set Server-Timing headers. The *Header can be extracted from the context using FromContext.

The options supplied to this can be nil to use defaults.

The Server-Timing header will be written when the status is written only if there are non-empty number of metrics.

To control when Server-Timing is sent, the easiest approach is to wrap this middleware and only call it if the request should send server timings. For examples, see the README.

func NewContext Uses

func NewContext(ctx context.Context, h *Header) context.Context

NewContext returns a new Context that carries the Header value h.

type Header struct {
    // Metrics is the list of metrics in the header.
    Metrics []*Metric

    // The lock that is held when Metrics is being modified. This
    // ONLY NEEDS TO BE SET WHEN working with Metrics directly. If using
    // the functions on the struct, the lock is managed automatically.

Header represents a collection of metrics that can be encoded as a Server-Timing header value.

The functions for working with metrics are concurrency-safe to make it easy to record metrics from goroutines. If you want to avoid the lock overhead, you can access the Metrics field directly.

The functions for working with metrics are also usable on a nil Header pointer. This allows functions that use FromContext to get the *Header value to skip nil-checking and use it as normal. On a nil *Header, Metrics are not recorded.

func FromContext Uses

func FromContext(ctx context.Context) *Header

FromContext returns the *Header in the context, if any. If no Header value exists, nil is returned.

func ParseHeader Uses

func ParseHeader(input string) (*Header, error)

ParseHeader parses a Server-Timing header value.

func (*Header) Add Uses

func (h *Header) Add(m *Metric) *Metric

Add adds the given metric to the header.

This function is safe to call concurrently.

func (*Header) NewMetric Uses

func (h *Header) NewMetric(name string) *Metric

NewMetric creates a new Metric and adds it to this header.

func (*Header) String Uses

func (h *Header) String() string

String returns the valid Server-Timing header value that can be sent in an HTTP response.

type Metric Uses

type Metric struct {
    // Name is the name of the metric. This must be a valid RFC7230 "token"
    // format. In a gist, this is an alphanumeric string that may contain
    // most common symbols but may not contain any whitespace. The exact
    // syntax can be found in RFC7230.
    // It is common for Name to be a unique identifier (such as "sql-1") and
    // for a more human-friendly name to be used in the "desc" field.
    Name string

    // Duration is the duration of this Metric.
    Duration time.Duration

    // Desc is any string describing this metric. For example: "SQL Primary".
    // The specific format of this is `token | quoted-string` according to
    // RFC7230.
    Desc string

    // Extra is a set of extra parameters and values to send with the
    // metric. The specification states that unrecognized parameters are
    // to be ignored so it should be safe to add additional data here. The
    // key must be a valid "token" (same syntax as Name) and the value can
    // be any "token | quoted-string" (same as Desc field).
    // If this map contains a key that would be sent by another field in this
    // struct (such as "desc"), then this value is prioritized over the
    // struct value.
    Extra map[string]string
    // contains filtered or unexported fields

Metric represents a single metric for the Server-Timing header.

The easiest way to use the Metric is to use NewMetric and chain it. This results in a single line defer at the top of a function time a function.

timing := FromContext(r.Context())
defer timing.NewMetric("sql").Start().Stop()

For timing around specific blocks of code:

m := timing.NewMetric("sql").Start()
// ... run your code being timed here

A metric is expected to represent a single timing event. Therefore, no functions on the struct are safe for concurrency by default. If a single Metric is shared by multiple concurrenty goroutines, you must lock access manually.

func (*Metric) GoString Uses

func (m *Metric) GoString() string

GoString is needed for fmt.GoStringer so %v works on pointer value.

func (*Metric) Start Uses

func (m *Metric) Start() *Metric

Start starts a timer for recording the duration of some task. This must be paired with a Stop call to set the duration. Calling this again will reset the start time for a subsequent Stop call.

func (*Metric) Stop Uses

func (m *Metric) Stop() *Metric

Stop ends the timer started with Start and records the duration in the Duration field. Calling this multiple times will modify the Duration based on the last time Start was called.

If Start was never called, this function has zero effect.

func (*Metric) String Uses

func (m *Metric) String() string

String returns the valid Server-Timing metric entry value.

func (*Metric) WithDesc Uses

func (m *Metric) WithDesc(desc string) *Metric

WithDesc is a chaining-friendly helper to set the Desc field on the Metric.

type MiddlewareOpts Uses

type MiddlewareOpts struct {
    // Don’t write headers in the request. Metrics are still gathered though.
    DisableHeaders bool

MiddlewareOpts are options for the Middleware.



Package servertiming imports 10 packages (graph) and is imported by 12 packages. Updated 2020-11-14. Refresh now. Tools for package owners.