Documentation ¶
Index ¶
Constants ¶
const HeaderKey = "Server-Timing"
HeaderKey is the specified key for the Server-Timing header.
Variables ¶
This section is empty.
Functions ¶
func Middleware ¶
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.
Types ¶
type Header ¶
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. sync.Mutex }
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 ¶
FromContext returns the *Header in the context, if any. If no Header value exists, nil is returned.
func (*Header) Add ¶
Add adds the given metric to the header.
This function is safe to call concurrently.
type Metric ¶
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 m.Stop()
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) Start ¶
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 ¶
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.
type MiddlewareOpts ¶
type MiddlewareOpts struct { // Don’t write headers in the request. Metrics are still gathered though. DisableHeaders bool }
MiddlewareOpts are options for the Middleware.