echootel

package module
v5.0.0 Latest Latest
Warning

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

Go to latest
Published: Sep 28, 2026 License: MIT Imports: 18 Imported by: 0

README

Sourcegraph GoDoc Go Report Card License

Echo OpenTelemetry (OTel) middleware

OpenTelemetry middleware for Echo framework.

Versioning

This repository does not use semantic versioning. MAJOR version tracks which Echo version should be used. MINOR version tracks API changes (possibly backwards incompatible) and PATCH version is incremented for fixes.

Echo Module Branch Minimal Echo version
v5 github.com/labstack/echo-otel/v5 main v5.2.1
v4 github.com/labstack/echo-otel/v4 v4 v4.15.4

This is the main branch, for Echo v5. github.com/labstack/echo-opentelemetry (v0.0.x, Echo v5) is the previous name of this project and is deprecated.

Always include the MAJOR version suffix (/v5 or /v4) in go get and imports. Without it, go get github.com/labstack/echo-otel fails.

Usage

Add OpenTelemetry middleware dependency with go modules

go get github.com/labstack/echo-otel/v5

Use as an import statement

import echootel "github.com/labstack/echo-otel/v5"

Add middleware in simplified form, by providing only the server name

e.Use(echootel.NewMiddleware("app.example.com"))

Add middleware with configuration options

e.Use(echootel.NewMiddlewareWithConfig(echootel.Config{
  TracerProvider: tp,
}))

Retrieving the tracer from the Echo context

tracer, err := echo.ContextGet[trace.Tracer](c, echootel.TracerKey)

Full example

See example

Custom error handler

The middleware resolves the response status code for returned errors with echo.ResolveResponseStatus: the status of an already sent response, the StatusCode() of the returned error (for example echo.HTTPError), or 500. If you use a custom HTTPErrorHandler that maps errors to other status codes, let the middleware run the error handler, so it reports the status code that was actually sent:

e.Use(echootel.NewMiddlewareWithConfig(echootel.Config{
  ServerName:  "app.example.com",
  OnNextError: func(c *echo.Context, err error) { c.Echo().HTTPErrorHandler(c, err) },
}))

The error is still returned, so the error handler is called again; make it return early when the response is already committed (resp, err := echo.UnwrapResponse(c.Response()); err == nil && resp.Committed). Echo's ProblemDetailsHTTPErrorHandler (Echo v5.4.0+) does this; use the snippet above with it too, as it resolves the status of ProblemErrorer errors and of *echo.ProblemError wrapped in another error differently.

Migrating from otelecho

go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho is deprecated and removed from opentelemetry-go-contrib in favor of this library. For Echo v5 use github.com/labstack/echo-otel/v5. For Echo v4 use github.com/labstack/echo-otel/v4, there is no need to migrate to Echo v5 first.

Replace otelecho.Middleware("my-server", opts...) with echootel.NewMiddleware("my-server"), or with echootel.NewMiddlewareWithConfig(echootel.Config{...}) when you use options. The server name is used as server.address and server.port, so it must be a host name with an optional port, for example api.example.com or api.example.com:8080 (otelecho accepted any string); NewMiddleware panics on an invalid value such as :8080 (no host), Config.ToMiddleware returns an error, and an empty ServerName uses the request Host:

otelecho option echootel.Config field
otelecho.WithTracerProvider(tp) TracerProvider: tp
otelecho.WithMeterProvider(mp) MeterProvider: mp
otelecho.WithPropagators(p) Propagators: p
otelecho.WithSkipper(s) Skipper: s
otelecho.WithMetricAttributeFn(f) MetricAttributes (see below)
otelecho.WithEchoMetricAttributeFn(f) MetricAttributes (see below)
otelecho.WithOnError(f) OnNextError (and OnExtractionError for request extraction failures)

Also note:

  • MetricAttributes replaces the default metric attributes (otelecho appended to them), so return append(v.MetricAttributes(), extra...).
  • otelecho called the Echo error handler from the middleware by default (c.Error(err)); echootel does not. See Custom error handler for how to get the same behavior.
  • The instrumentation scope name changes from go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho to github.com/labstack/echo-otel/v5. Update dashboards and alerts that filter on it.
  • The echo.error span attribute is not set; use error.type and the span status instead.

Migrating from echo-opentelemetry

github.com/labstack/echo-opentelemetry (v0.0.x) is the previous name of this project. It is deprecated and receives no more changes. Change the import path; the API is the same, except that a ServerName without a host is rejected (see below):

import echootel "github.com/labstack/echo-otel/v5"

Telemetry changes compared to echo-opentelemetry v0.0.3:

  • The instrumentation scope name changes from github.com/labstack/echo-opentelemetry to github.com/labstack/echo-otel/v5. Update dashboards and alerts that filter on it.
  • error.type is no longer set for 4xx responses (it used to be *echo.HTTPError for a returned HTTPError, and *echo.httpError for Echo's own errors such as echo.ErrNotFound).
  • A returned 5xx HTTPError reports the status code (500) instead of *echo.HTTPError.
  • A 5xx response written without an error (for example c.String(500, ...)) now reports error.type.
  • A returned error with a StatusCode() int method reports the status code for a 5xx response instead of its Go type.
  • error.type is also added to metrics, see Errors.
  • http.route and the span name are set when the middleware is added with Echo.Pre.
  • An error wrapped with fmt.Errorf("...: %w", err) reports the wrapped error's type (for example *net.OpError) instead of *fmt.wrapError, and an ErrorType() string method in the error chain is used when present.
  • error.type is now one of the span end attributes: a Config.SpanEndAttributes callback must append to the attr argument, otherwise error.type is dropped (v0.0.3 set it separately).
  • A status code of 600-999 now reports error.type (the code).
  • Metrics no longer have server.address, server.port and http.request.method_original; their values come from the request and would make metric cardinality unbounded. They stay on spans. See Metrics.
  • With ServerName set, server.port comes from ServerName only, not from the Host header.
  • An unknown request body size (for example a chunked request) is not recorded, instead of -1.
  • http.route is always the Echo route, never the pattern of an outer http.ServeMux.
  • A panic in a handler is recorded (error.type panic) and then re-panicked, so telemetry is recorded also when a Recover middleware is added before this middleware. With a Recover middleware added after this middleware, the returned *middleware.PanicStackError is reported as panic instead of its Go type. See Errors.
  • A ServerName without a host (for example :8080) is rejected: NewMiddleware panics and Config.ToMiddleware returns an error. v0.0.3 accepted it.
  • network.protocol.version is 2 for HTTP/2 and 3 for HTTP/3, instead of 2.0 and 3.0.
  • Spans no longer have http.request.body.size and http.response.body.size (Opt-In for spans in the semantic conventions). The body size metrics stay. See Spans for how to add them back.

Errors

A request that ends with an error sets error.type on the span and on the metrics, as the semantic conventions require. The rules match the span status:

  • a 4xx response is not an error for server spans: no error.type,
  • a 5xx response without a returned error, or with a returned error that carries the status code (echo.HTTPError or any error with a StatusCode() int method, also when wrapped), reports the status code, for example 500,
  • any other returned error reports its Go type, for example *net.OpError. Errors created with fmt.Errorf("...: %w", err) are unwrapped first; errors joining several errors (errors.Join, fmt.Errorf with more than one %w) report their own type. An ErrorType() string method anywhere in the error chain takes precedence; keep its values low cardinality, as error.type is also a metric attribute.
  • an invalid status code without a returned error reports _OTHER (below 100 or above 999) or the code itself (600-999),
  • a panic reports panic, also when a 4xx response was already sent.

The middleware records a panic and then re-panics, so add a Recover middleware before this middleware (e.Use(middleware.Recover()) first). The recorded status is the status of the response that was already sent, the status of a panic value that carries one (for example echo.ErrUnauthorized), or 500. A Recover middleware added after this middleware (with the default configuration) returns the panic as a *middleware.PanicStackError, which is also reported as panic.

error.type is part of the span end attributes. A Config.SpanEndAttributes callback must append to the attr argument and return it, otherwise error.type and the other end attributes are dropped.

Spans

Spans follow the HTTP server span semantic conventions, with these exceptions:

  • url.query is not set. The query string can contain sensitive data, and the semantic conventions require redacting it. http.request.body.size and http.response.body.size are Opt-In and not set either.
  • http.response.status_code is not set when no response was sent, for example after an http.ErrAbortHandler panic.

client.address comes from c.RealIP(): the connection's remote address, or the result of Echo.IPExtractor when it is set.

Add attributes with SpanStartAttributes and SpanEndAttributes. Both callbacks must append to the attr argument and return it:

SpanStartAttributes: func(c *echo.Context, v *echootel.Values, attr []attribute.KeyValue) []attribute.KeyValue {
  if q := c.Request().URL.RawQuery; q != "" {
    attr = append(attr, semconv.URLQuery(redactQuery(q))) // redactQuery is your own function
  }
  return attr
},
SpanEndAttributes: func(c *echo.Context, v *echootel.Values, attr []attribute.KeyValue) []attribute.KeyValue {
  if v.HTTPRequestBodySize >= 0 {
    attr = append(attr, semconv.HTTPRequestBodySize(int(v.HTTPRequestBodySize)))
  }
  return append(attr, semconv.HTTPResponseBodySize(int(v.HTTPResponseBodySize)))
},

Metrics

The middleware records http.server.request.duration, http.server.request.body.size and http.server.response.body.size with these attributes: http.request.method, url.scheme, http.route, network.protocol.name, network.protocol.version, http.response.status_code and error.type.

server.address, server.port and http.request.method_original are Opt-In for metrics in the semantic conventions and are not added: the Host header and the request method are chosen by the client and would make metric cardinality unbounded. Add attributes with a known set of values with MetricAttributes, for example:

MetricAttributes: func(c *echo.Context, v *echootel.Values) []attribute.KeyValue {
  return append(v.MetricAttributes(), semconv.ServerAddress("api.example.com"))
},

Known limitations

  • Hijacked connections (for example WebSocket upgrades) are reported with the status code that Echo's response has, usually 200, not 101.
  • A panic without a Recover middleware is recorded with status 500, but net/http closes the connection without sending a response.

Dependency update bots

Renovate proposes a new MAJOR version (for example github.com/labstack/echo-otel/v4 to /v5) as an update. A new MAJOR version of this library needs the same MAJOR version of Echo, so update Echo first. To stay on the current Echo version, disable major updates for this library:

{
  "packageRules": [
    {
      "matchManagers": ["gomod"],
      "matchPackageNames": ["github.com/labstack/echo-otel/v4", "github.com/labstack/echo-otel/v5"],
      "matchUpdateTypes": ["major"],
      "enabled": false
    }
  ]
}

Documentation

Index

Constants

View Source
const (
	// TracerKey is the key used to store the tracer in the echo context.
	TracerKey = "labstack-echo-otelecho-tracer"
	// ScopeName is the instrumentation scope name.
	ScopeName = "github.com/labstack/echo-otel/v5"
)
View Source
const Version = "5.0.0"

Version is the current release version of the echo instrumentation.

Variables

This section is empty.

Functions

func ErrorType

func ErrorType(code int, err error) string

ErrorType returns the `error.type` attribute value for a server span and metrics, based on the resolved HTTP response status code and the error that occurred while handling the request. It returns an empty string when the request did not end with an error.

The request is considered to have ended with an error under the same rules as SpanStatus: a 5xx status code, an invalid status code, or an error alongside a 1xx-3xx status code. A 4xx status code is not an error for server spans.

The returned value is:

  • the status code as a string (for example "500") for a 5xx status code when there is no error or the error carries an HTTP status code (implements `StatusCode() int`, like Echo v5's HTTPError),
  • the error type for other errors, as returned by semconv.ErrorType: the value of an `ErrorType() string` method found in the error chain, otherwise the Go type of the error after unwrapping errors created with `fmt.Errorf("...: %w", err)` (for example "*net.OpError"). Errors joining several errors (`errors.Join`, `fmt.Errorf` with more than one `%w`) are not unwrapped and report their own type,
  • the status code as a string for a status code above 599 without an error (net/http sends codes up to 999),
  • "_OTHER" for a status code below 100 without an error.

The spec requires low cardinality. Error types are bounded by the code base, unless errors implement `ErrorType() string` with values that vary per request; avoid that, as error.type is also a metric attribute.

Spec:

If the request fails with an error before response status code was sent or received, error.type SHOULD be set to
exception type (its fully-qualified class name, if applicable) or a component-specific low cardinality error
identifier.

If response status code was sent or received and status indicates an error according to HTTP span status
definition, error.type SHOULD be set to the status code number (represented as a string), an exception type (if
thrown) or a component-specific error identifier.

Reference: - [HTTP server span](https://opentelemetry.io/docs/specs/semconv/http/http-spans/#http-server-span) - [error.type](https://opentelemetry.io/docs/specs/semconv/registry/attributes/error/)

func NewMiddleware

func NewMiddleware(serverName string) echo.MiddlewareFunc

NewMiddleware creates new echo opentelemetry middleware with the given server name.

func NewMiddlewareWithConfig

func NewMiddlewareWithConfig(config Config) echo.MiddlewareFunc

NewMiddlewareWithConfig creates new echo opentelemetry middleware with the given configuration.

func SpanNameFormatter

func SpanNameFormatter(v Values) string

SpanNameFormatter returns the default format for the span name based on the HTTP method and path.

HTTP span names SHOULD be `{method} {target}` if there is a (low-cardinality) `target` available. If there is no (low-cardinality) `{target}` available, HTTP span names SHOULD be `{method}`.

The `{method}` MUST be `{http.request.method}` if the method represents the original method known to the instrumentation. In other cases (when `{http.request.method}` is set to `_OTHER`), `{method}` MUST be `HTTP`

Spec: https://opentelemetry.io/docs/specs/semconv/http/http-spans/#name

func SpanStatus

func SpanStatus(code int, err error) (codes.Code, string)

SpanStatus returns the span status code and error description for a server span, based on the resolved HTTP response status code and the error that occurred while handling the request.

Spec:

Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, unless there was another error
 (e.g., network error receiving the response body; or 3xx codes with max redirects exceeded), in which case status
 MUST be set to Error.

For HTTP status codes in the 4xx range span status MUST be left unset in case of SpanKind.SERVER and SHOULD be set
 to Error in case of SpanKind.CLIENT.

Reference: - [Span.Status](https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status) - [Recording errors on spans](https://opentelemetry.io/docs/specs/semconv/general/recording-errors/)

func SplitAddress

func SplitAddress(address string) (host string, port int, err error)

SplitAddress splits server address or host into host (`server.address`) and port (`server.port`). Empty address is accepted and returns empty host and port. Port is part is not mandatory in address and can be omitted.

Types

type AttributesFunc

type AttributesFunc func(c *echo.Context, v *Values, attr []attribute.KeyValue) []attribute.KeyValue

AttributesFunc is used to extract additional attributes from the echo.Context and return them as a slice of attribute.KeyValue.

type Config

type Config struct {
	// ServerName is set as `server.address` and `server.port` span attributes. They are not added to metrics by
	// default (Opt-In in the semantic conventions); add them with MetricAttributes if needed.
	// Example: "api.example.com" or "example.com:8080". Without a port, `server.port` is not set.
	//
	// If known, this value must be set to the server’s canonical (primary) name.
	// For example, in Apache this corresponds to the ServerName directive
	// (https://httpd.apache.org/docs/2.4/mod/core.html#servername), and in NGINX
	// to the server_name directive
	// (http://nginx.org/en/docs/http/ngx_http_core_module.html#server_name).
	//
	// More generally, the primary server name is the host header value that maps
	// to the HTTP server’s default virtual host. It must include the hostname,
	// and if the server is accessed via a non-default port, the port must be
	// appended using the standard ":port" suffix.
	//
	// If the primary server name is unknown, this field should be set to an
	// empty string. In that case, Request.Host will be used to resolve the
	// effective server name and port. Request.Host is chosen by the client.
	ServerName string

	// Skipper defines a function to skip middleware.
	Skipper middleware.Skipper

	// OnNextError is used to specify how errors returned from the next middleware / handler are handled.
	OnNextError OnErrorFunc

	// OnExtractionError is used to specify how errors returned from request extraction are handled.
	OnExtractionError OnErrorFunc

	// TracerProvider allows overriding the default tracer provider.
	TracerProvider oteltrace.TracerProvider

	// MeterProvider allows overriding the default meter provider.
	MeterProvider metric.MeterProvider

	// Propagators allow overriding the default propagators.
	Propagators propagation.TextMapPropagator

	// SpanStartOptions configures an additional set of trace.SpanStartOptions, which are applied to each new span.
	SpanStartOptions []oteltrace.SpanStartOption

	// SpanStartAttributes is used to extract additional attributes from the echo.Context
	// and return them as a slice of attribute.KeyValue.
	SpanStartAttributes AttributesFunc

	// SpanEndAttributes is used to extract additional attributes from the echo.Context
	// and return them as a slice of attribute.KeyValue.
	SpanEndAttributes AttributesFunc

	// MetricAttributes is used to compose attributes just before Metrics.Record call.
	MetricAttributes MetricAttributesFunc

	// Metrics is used to record custom metrics instead of default.
	Metrics MetricsRecorder
}

Config is used to configure the middleware.

func (Config) ToMiddleware

func (config Config) ToMiddleware() (echo.MiddlewareFunc, error)

ToMiddleware returns echo opentelemetry middleware which will trace incoming requests.

type MetricAttributesFunc

type MetricAttributesFunc func(c *echo.Context, v *Values) []attribute.KeyValue

MetricAttributesFunc is used to compose attributes for Metrics.Record.

type Metrics

type Metrics struct {
	// contains filtered or unexported fields
}

Metrics holds a standard set of OpenTelemetry global request/response metrics

func NewMetrics

func NewMetrics(meter metric.Meter) (*Metrics, error)

NewMetrics creates a new Metrics instance for Standard Required metric instances with the given Meter.

func (*Metrics) Record

func (m *Metrics) Record(ctx context.Context, v RecordValues)

Record records the given RecordValues to the Metrics instance.

type MetricsRecorder

type MetricsRecorder interface {
	Record(c *echo.Context, v RecordValues)
}

MetricsRecorder is used to record metrics. This interface is used to allow custom metrics recording with access to the Echo context, so additional attributes can be extracted from it.

type OnErrorFunc

type OnErrorFunc func(c *echo.Context, err error)

OnErrorFunc is used to specify how errors are handled in the middleware.

type RecordValues

type RecordValues struct {
	// RequestDuration is the duration of request processing. Will be used with `http.server.request.duration` metric.
	RequestDuration time.Duration

	// ExtractedValues are values extracted from HTTP request and response before and after processing the next middleware/handler.
	ExtractedValues Values

	// Attributes are attributes to be used for recording metrics.
	// If left empty, the Metrics.Record method will use default attributes by calling Values.MetricAttributes().
	Attributes []attribute.KeyValue
}

RecordValues represents the values to Record metrics.

type Values

type Values struct {
	// HTTPMethod (`http.request.method`) - HTTP request method.
	//
	// If the HTTP request method is not known to instrumentation, it MUST set the `http.request.method` attribute to `_OTHER`
	//
	// If the HTTP instrumentation could end up converting valid HTTP request methods to `_OTHER`, then it MUST provide a
	// way to override the list of known HTTP methods. If this override is done via environment variable, then the
	// environment variable MUST be named `OTEL_INSTRUMENTATION_HTTP_KNOWN_METHODS` and support a comma-separated list of
	// case-sensitive known HTTP methods (this list MUST be a full override of the default known method, it is not a
	// list of known methods in addition to the defaults).
	//
	// HTTP method names are case-sensitive and `http.request.method` attribute value MUST match a known HTTP method name
	// exactly. Instrumentations for specific web frameworks that consider HTTP methods to be case insensitive, SHOULD
	// populate a canonical equivalent. Tracing instrumentations that do so, MUST also set `http.request.method_original`
	// to the original value.
	//
	// Example: `GET`, `POST`, `_OTHER`
	// Spec: https://opentelemetry.io/docs/specs/semconv/registry/attributes/http/
	//
	// Requirement Level:
	//  * span - Required
	//  * metric - Required
	HTTPMethod string // metric, span

	// HTTPMethodOriginal (`http.request.method_original`) is original HTTP method sent by the client in the request line.
	// Example: `GeT`, `ACL`, `foo`
	//
	// Requirement Level:
	//  * span - conditionally required if raw value differs from `http.request.method` (different case) or `http.request.method` is `_OTHER`
	//  * metric - not used, as the value is chosen by the client and would make metric cardinality unbounded
	HTTPMethodOriginal string // span

	// ServerAddress (`server.address`) is the Name of the local HTTP server that received the request.
	// This value can be provided by middleware configuration or extracted from `Request.Host` (together with ServerPort).
	// Example values: `example.com` `10.1.2.80`, `/tmp/my.sock`
	// See also: https://opentelemetry.io/docs/specs/semconv/http/http-spans/#setting-serveraddress-and-serverport-attributes
	// Spec: https://opentelemetry.io/docs/specs/semconv/registry/attributes/server/
	//
	// Requirement Level:
	//  * span - Recommended
	//  * metric - Opt-In, not added by MetricAttributes as `Request.Host` is chosen by the client. Add it with a custom
	//    metric attributes function when the value comes from configuration.
	ServerAddress string // span

	// ServerPort (`server.port`) is the Port of the local HTTP server that received the request.
	// This value can be provided by middleware configuration or extracted from `Request.Host` (only when ServerAddress
	// is extracted from it too).
	// Example values: `80` `8080`, `443`
	// See also: https://opentelemetry.io/docs/specs/semconv/http/http-spans/#setting-serveraddress-and-serverport-attributes
	// Spec: https://opentelemetry.io/docs/specs/semconv/registry/attributes/server/
	//
	// Requirement Level:
	//  * span - conditionally Required if available and `server.address` is set
	//  * metric - Opt-In, not added by MetricAttributes, same as ServerAddress
	ServerPort int // span

	// NetworkPeerAddress (`network.peer.address`) is peer address of the network connection - IP address or Unix domain socket name.
	// Spec: https://opentelemetry.io/docs/specs/semconv/registry/attributes/network/
	//
	// Go: This value is derived from `Request.RemoteAddr` field value.
	//
	// Requirement Level:
	//  * span - Recommended
	//  * metric - not used
	NetworkPeerAddress string // span (optional)

	// NetworkPeerPort (`network.peer.port`) is peer port number of the network connection.
	// Spec: https://opentelemetry.io/docs/specs/semconv/registry/attributes/network/
	//
	// Go: This value is derived from `Request.RemoteAddr` field value.
	//
	// Requirement Level:
	//  * span - Recommended if `network.peer.address` is set.
	//  * metric - not used
	NetworkPeerPort int // span (optional)

	// ClientAddress (`client.address`) is client address - domain name if available without reverse DNS lookup;
	// otherwise, IP address or Unix domain socket name.
	// Spec: https://opentelemetry.io/docs/specs/semconv/registry/attributes/client/
	//
	// Go: This value is derived by default from `Request.RemoteAddr` field value and is same as `network.peer.address`.
	//     The Echo middleware sets it from `Context.RealIP()`, which follows the Echo instance IP extraction settings
	//     (`Echo.IPExtractor`); headers like `X-Forwarded-For` are easy to spoof when they are trusted from any client.
	//
	// Requirement Level:
	//  * span - Recommended if `network.peer.address` is set.
	//  * metric - not used
	ClientAddress string // span (optional)

	// URLScheme (`url.scheme`) is the [URI scheme](https://www.rfc-editor.org/rfc/rfc3986#section-3.1) component
	// identifying the used protocol.
	// The scheme of the original client request, if possible, from one of these headers:
	// - [Forwarded#proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Forwarded#proto)
	// - [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto)
	// - Otherwise, the scheme of the immediate peer request.
	// Example values: `http`, `https`
	//
	// Requirement Level:
	//  * span - Required
	//  * metric - Required
	URLScheme string // metric, span

	// URLPath (`url.path`) is the [URI](https://www.rfc-editor.org/rfc/rfc3986#section-3.3) path component.
	// Spec: https://opentelemetry.io/docs/specs/semconv/registry/attributes/url/
	//
	// Go: This value is taken from `Request.URL.Path` method value.
	//
	// Requirement Level:
	//  * span - Required
	//  * metric - not used
	URLPath string // span

	// UserAgentOriginal (`user_agent.original`) is the value of the [HTTP User-Agent](https://www.rfc-editor.org/rfc/rfc9110.html#field.user-agent)
	// header sent by the client.
	// Spec: https://opentelemetry.io/docs/specs/semconv/registry/attributes/user-agent/
	//
	// Go: This value is taken from `Request.UserAgent()` method value.
	//
	// Requirement Level:
	//  * span - Recommended
	//  * metric - not used
	UserAgentOriginal string // span

	// NetworkProtocolName (`network.protocol.name`) is OSI application layer or non-OSI equivalent.
	// Value is required if not value is not `http` and `network.protocol.version` value is set.
	// The value SHOULD be normalized to lowercase.
	// Example: `http`, `quic`, `spdy`
	// Spec: https://opentelemetry.io/docs/specs/semconv/registry/attributes/network/
	//
	// Go: This value is derived from `Request.Proto` field value.
	//
	// Requirement Level:
	//  * span - conditionally Required if available and `network.protocol.version` is set
	//  * metric - conditionally Required if available and `network.protocol.version` is set
	NetworkProtocolName string // metric, span

	// NetworkProtocolVersion (`network.protocol.version`) is the actual version of the protocol used for network communication.
	// Example: `1.0`, `1.1`, `2`, `3`
	// Spec: https://opentelemetry.io/docs/specs/semconv/registry/attributes/network/
	//
	// Go: This value is derived from `Request.Proto` field value.
	//
	// Requirement Level:
	//  * span - Recommended
	//  * metric - Recommended
	NetworkProtocolVersion string // metric, span

	// HTTPRoute (`http.route`) is the matched route template for the request. This MUST be low-cardinality and include
	// all static path segments, with dynamic path segments represented with placeholders.
	// Spec: https://opentelemetry.io/docs/specs/semconv/registry/attributes/http/
	//
	// Go: The Echo middleware takes this value from `Context.Path()`, the matched Echo route. ExtractRequest uses the
	//     `Request.Pattern` field when the value is not set.
	//
	// Requirement Level:
	//  * span - Recommended
	//  * metric - Conditionally Required If and only if it's available
	HTTPRoute string // metric, span

	// HTTPRequestBodySize (`http.request.body.size`) is the size of the request payload body in bytes. This is the number
	// of bytes transferred excluding headers and is often, but not always, present as the [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length)
	// header. For requests using transport encoding, this should be the compressed size.
	// Spec: https://opentelemetry.io/docs/specs/semconv/http/http-metrics/#metric-httpserverrequestbodysize
	//
	// Go: This value is taken from `Request.ContentLength` and is negative (-1) if the size is unknown. Unknown size is
	//     not recorded.
	//
	// Requirement Level:
	//  * span - Opt-In, not added by SpanEndAttributes. Add it with a span end attributes function if needed.
	//  * metric - optional, is actual Histogram metric (`http.server.request.body.size`) and NOT attribute to metric.
	HTTPRequestBodySize int64 // metric

	// HTTPResponseStatusCode (`http.response.status_code`) is HTTP response status code.
	// See also RFC: https://datatracker.ietf.org/doc/html/rfc7231#section-6
	// Spec: https://opentelemetry.io/docs/specs/semconv/registry/attributes/http/
	//
	// Zero means no status was sent (for example the handler aborted the request); the attribute is not set then.
	//
	// Requirement Level:
	//  * span - conditionally Required if and only if one was received/sent
	//  * metric - conditionally Required if and only if one was received/sent
	HTTPResponseStatusCode int // metric, span

	// ErrorType (`error.type`) describes the class of error the request ended with. It is empty when the request did
	// not end with an error. Use ErrorType function to determine the value.
	// Spec: https://opentelemetry.io/docs/specs/semconv/registry/attributes/error/
	//
	// Requirement Level:
	//  * span - conditionally Required if request has ended with an error
	//  * metric - conditionally Required if request has ended with an error
	ErrorType string // metric, span

	// HTTPResponseBodySize (`http.response.body.size`) is the size of the response payload body in bytes. This is
	// the number of bytes transferred excluding headers and is often, but not always, present as the
	// [Content-Length](https://www.rfc-editor.org/rfc/rfc9110.html#field.content-length) header. For requests using
	// transport encoding, this should be the compressed size.
	// Spec: https://opentelemetry.io/docs/specs/semconv/http/http-metrics/#metric-httpserverresponsebodysize
	//
	// Requirement Level:
	//  * span - Opt-In, not added by SpanEndAttributes. Add it with a span end attributes function if needed.
	//  * metric - optional, is actual Histogram metric (`http.server.response.body.size`) and NOT attribute to metric.
	HTTPResponseBodySize int64 // metric
}

Values represent extracted values from HTTP request and response to be used for Span and Metrics attributes.

Span: Semantic Conventions for HTTP client and server spans. https://opentelemetry.io/docs/specs/semconv/http/http-spans/ Metrics: Semantic Conventions for HTTP client and server metrics. https://opentelemetry.io/docs/specs/semconv/http/http-metrics/

func (*Values) AppendMetricAttributes

func (v *Values) AppendMetricAttributes(attrs []attribute.KeyValue) []attribute.KeyValue

AppendMetricAttributes appends attributes for metric instruments from extracted values. Use this method instead of `MetricAttributes()` when you want to preallocate/reuse attributes slice. See also: https://opentelemetry.io/docs/specs/semconv/http/http-metrics/

func (*Values) AppendSpanEndAttributes

func (v *Values) AppendSpanEndAttributes(attrs []attribute.KeyValue) []attribute.KeyValue

AppendSpanEndAttributes appends attributes to be used when ending a span, after the next handler has been executed. Use this method instead of `SpanEndAttributes()` when you want to preallocate/reuse attributes slice.

func (*Values) AppendStartAttributes

func (v *Values) AppendStartAttributes(attrs []attribute.KeyValue) []attribute.KeyValue

AppendStartAttributes appends attributes to be used when starting a span. Use this method instead of `SpanStartAttributes()` when you want to preallocate/reuse attributes slice.

func (*Values) ExtractRequest

func (v *Values) ExtractRequest(r *http.Request) error

ExtractRequest extracts values from the given HTTP request and populates the Values struct.

func (*Values) MetricAttributes

func (v *Values) MetricAttributes() []attribute.KeyValue

MetricAttributes creates attributes for metric instruments from extracted values.

Only low cardinality attributes are included: `http.request.method`, `url.scheme`, `http.route`, `network.protocol.name`, `network.protocol.version`, `http.response.status_code` and `error.type`. Opt-In attributes whose values the client chooses (`server.address` and `server.port` from `Request.Host`, `http.request.method_original`) are not included. See also: https://opentelemetry.io/docs/specs/semconv/http/http-metrics/

func (*Values) SpanEndAttributes

func (v *Values) SpanEndAttributes() []attribute.KeyValue

SpanEndAttributes returns a list of attributes to be used when ending a span, after the next handler has been executed.

It adds `http.response.status_code` (if a status was sent) and `error.type` (if the request ended with an error). The Opt-In `http.request.body.size` and `http.response.body.size` attributes are not added.

func (*Values) SpanStartAttributes

func (v *Values) SpanStartAttributes() []attribute.KeyValue

SpanStartAttributes returns a list of attributes to be used when starting a span.

Jump to

Keyboard shortcuts

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