summaryrefslogtreecommitdiff
path: root/vendor/go.opentelemetry.io
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-05-14 13:18:54 -0600
committermo khan <mo@mokhan.ca>2025-05-14 13:18:54 -0600
commit4b2d609a0efcc1d9b2f1a08f954d067ad1d9cd1e (patch)
tree0afacf9217b0569130da6b97d4197331681bf119 /vendor/go.opentelemetry.io
parentab373d1fe698cd3f53258c09bc8515d88a6d0b9e (diff)
test: use playwright to test out an OIDC login
Diffstat (limited to 'vendor/go.opentelemetry.io')
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/client.go6
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go7
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go58
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/body_wrapper.go3
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/gen.go10
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go14
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/env.go204
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go14
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/httpconv.go225
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go28
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/v1.20.0.go135
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/netconv.go11
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/start_time_context.go29
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go58
-rw-r--r--vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go2
15 files changed, 649 insertions, 155 deletions
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/client.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/client.go
index 6aae83b..b25641c 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/client.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/client.go
@@ -18,7 +18,7 @@ var DefaultClient = &http.Client{Transport: NewTransport(http.DefaultTransport)}
// Get is a convenient replacement for http.Get that adds a span around the request.
func Get(ctx context.Context, targetURL string) (resp *http.Response, err error) {
- req, err := http.NewRequestWithContext(ctx, "GET", targetURL, nil)
+ req, err := http.NewRequestWithContext(ctx, http.MethodGet, targetURL, nil)
if err != nil {
return nil, err
}
@@ -27,7 +27,7 @@ func Get(ctx context.Context, targetURL string) (resp *http.Response, err error)
// Head is a convenient replacement for http.Head that adds a span around the request.
func Head(ctx context.Context, targetURL string) (resp *http.Response, err error) {
- req, err := http.NewRequestWithContext(ctx, "HEAD", targetURL, nil)
+ req, err := http.NewRequestWithContext(ctx, http.MethodHead, targetURL, nil)
if err != nil {
return nil, err
}
@@ -36,7 +36,7 @@ func Head(ctx context.Context, targetURL string) (resp *http.Response, err error
// Post is a convenient replacement for http.Post that adds a span around the request.
func Post(ctx context.Context, targetURL, contentType string, body io.Reader) (resp *http.Response, err error) {
- req, err := http.NewRequestWithContext(ctx, "POST", targetURL, body)
+ req, err := http.NewRequestWithContext(ctx, http.MethodPost, targetURL, body)
if err != nil {
return nil, err
}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go
index 5d6e615..a83a026 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/common.go
@@ -18,13 +18,6 @@ const (
WriteErrorKey = attribute.Key("http.write_error") // if an error occurred while writing a reply, the string of the error (io.EOF is not recorded)
)
-// Client HTTP metrics.
-const (
- clientRequestSize = "http.client.request.size" // Outgoing request bytes total
- clientResponseSize = "http.client.response.size" // Outgoing response bytes total
- clientDuration = "http.client.duration" // Outgoing end to end duration, milliseconds
-)
-
// Filter is a predicate used to determine whether a given http.request should
// be traced. A Filter must return true if the request should be traced.
type Filter func(*http.Request) bool
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go
index 33580a3..3ea05d0 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go
@@ -12,6 +12,7 @@ import (
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv"
"go.opentelemetry.io/otel"
+ "go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/trace"
)
@@ -21,15 +22,16 @@ type middleware struct {
operation string
server string
- tracer trace.Tracer
- propagators propagation.TextMapPropagator
- spanStartOptions []trace.SpanStartOption
- readEvent bool
- writeEvent bool
- filters []Filter
- spanNameFormatter func(string, *http.Request) string
- publicEndpoint bool
- publicEndpointFn func(*http.Request) bool
+ tracer trace.Tracer
+ propagators propagation.TextMapPropagator
+ spanStartOptions []trace.SpanStartOption
+ readEvent bool
+ writeEvent bool
+ filters []Filter
+ spanNameFormatter func(string, *http.Request) string
+ publicEndpoint bool
+ publicEndpointFn func(*http.Request) bool
+ metricAttributesFn func(*http.Request) []attribute.KeyValue
semconv semconv.HTTPServer
}
@@ -79,12 +81,7 @@ func (h *middleware) configure(c *config) {
h.publicEndpointFn = c.PublicEndpointFn
h.server = c.ServerName
h.semconv = semconv.NewHTTPServer(c.Meter)
-}
-
-func handleErr(err error) {
- if err != nil {
- otel.Handle(err)
- }
+ h.metricAttributesFn = c.MetricAttributesFn
}
// serveHTTP sets up tracing and calls the given next http.Handler with the span
@@ -123,6 +120,11 @@ func (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http
}
}
+ if startTime := StartTimeFromContext(ctx); !startTime.IsZero() {
+ opts = append(opts, trace.WithTimestamp(startTime))
+ requestStartTime = startTime
+ }
+
ctx, span := tracer.Start(ctx, h.spanNameFormatter(h.operation, r), opts...)
defer span.End()
@@ -190,17 +192,31 @@ func (h *middleware) serveHTTP(w http.ResponseWriter, r *http.Request, next http
// Use floating point division here for higher precision (instead of Millisecond method).
elapsedTime := float64(time.Since(requestStartTime)) / float64(time.Millisecond)
- h.semconv.RecordMetrics(ctx, semconv.MetricData{
- ServerName: h.server,
+ metricAttributes := semconv.MetricAttributes{
Req: r,
StatusCode: statusCode,
- AdditionalAttributes: labeler.Get(),
- RequestSize: bw.BytesRead(),
- ResponseSize: bytesWritten,
- ElapsedTime: elapsedTime,
+ AdditionalAttributes: append(labeler.Get(), h.metricAttributesFromRequest(r)...),
+ }
+
+ h.semconv.RecordMetrics(ctx, semconv.ServerMetricData{
+ ServerName: h.server,
+ ResponseSize: bytesWritten,
+ MetricAttributes: metricAttributes,
+ MetricData: semconv.MetricData{
+ RequestSize: bw.BytesRead(),
+ ElapsedTime: elapsedTime,
+ },
})
}
+func (h *middleware) metricAttributesFromRequest(r *http.Request) []attribute.KeyValue {
+ var attributeForRequest []attribute.KeyValue
+ if h.metricAttributesFn != nil {
+ attributeForRequest = h.metricAttributesFn(r)
+ }
+ return attributeForRequest
+}
+
// WithRouteTag annotates spans and metrics with the provided route name
// with HTTP route attribute.
func WithRouteTag(route string, h http.Handler) http.Handler {
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/body_wrapper.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/body_wrapper.go
index a945f55..866aa21 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/body_wrapper.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/body_wrapper.go
@@ -1,3 +1,6 @@
+// Code created by gotmpl. DO NOT MODIFY.
+// source: internal/shared/request/body_wrapper.go.tmpl
+
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/gen.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/gen.go
new file mode 100644
index 0000000..9e00dd2
--- /dev/null
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/gen.go
@@ -0,0 +1,10 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package request // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request"
+
+// Generate request package:
+//go:generate gotmpl --body=../../../../../../internal/shared/request/body_wrapper.go.tmpl "--data={}" --out=body_wrapper.go
+//go:generate gotmpl --body=../../../../../../internal/shared/request/body_wrapper_test.go.tmpl "--data={}" --out=body_wrapper_test.go
+//go:generate gotmpl --body=../../../../../../internal/shared/request/resp_writer_wrapper.go.tmpl "--data={}" --out=resp_writer_wrapper.go
+//go:generate gotmpl --body=../../../../../../internal/shared/request/resp_writer_wrapper_test.go.tmpl "--data={}" --out=resp_writer_wrapper_test.go
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go
index aea171f..73184e7 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request/resp_writer_wrapper.go
@@ -1,3 +1,6 @@
+// Code created by gotmpl. DO NOT MODIFY.
+// source: internal/shared/request/resp_writer_wrapper.go.tmpl
+
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
@@ -44,7 +47,9 @@ func (w *RespWriterWrapper) Write(p []byte) (int, error) {
w.mu.Lock()
defer w.mu.Unlock()
- w.writeHeader(http.StatusOK)
+ if !w.wroteHeader {
+ w.writeHeader(http.StatusOK)
+ }
n, err := w.ResponseWriter.Write(p)
n1 := int64(n)
@@ -80,7 +85,12 @@ func (w *RespWriterWrapper) writeHeader(statusCode int) {
// Flush implements [http.Flusher].
func (w *RespWriterWrapper) Flush() {
- w.WriteHeader(http.StatusOK)
+ w.mu.Lock()
+ defer w.mu.Unlock()
+
+ if !w.wroteHeader {
+ w.writeHeader(http.StatusOK)
+ }
if f, ok := w.ResponseWriter.(http.Flusher); ok {
f.Flush()
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/env.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/env.go
index 9cae4ca..4693a01 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/env.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/env.go
@@ -1,3 +1,6 @@
+// Code created by gotmpl. DO NOT MODIFY.
+// source: internal/shared/semconv/env.go.tmpl
+
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
@@ -9,12 +12,17 @@ import (
"net/http"
"os"
"strings"
+ "sync"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/metric"
)
+// OTelSemConvStabilityOptIn is an environment variable.
+// That can be set to "old" or "http/dup" to opt into the new HTTP semantic conventions.
+const OTelSemConvStabilityOptIn = "OTEL_SEMCONV_STABILITY_OPT_IN"
+
type ResponseTelemetry struct {
StatusCode int
ReadBytes int64
@@ -30,6 +38,11 @@ type HTTPServer struct {
requestBytesCounter metric.Int64Counter
responseBytesCounter metric.Int64Counter
serverLatencyMeasure metric.Float64Histogram
+
+ // New metrics
+ requestBodySizeHistogram metric.Int64Histogram
+ responseBodySizeHistogram metric.Int64Histogram
+ requestDurationHistogram metric.Float64Histogram
}
// RequestTraceAttrs returns trace attributes for an HTTP request received by a
@@ -50,9 +63,18 @@ type HTTPServer struct {
// The req Host will be used to determine the server instead.
func (s HTTPServer) RequestTraceAttrs(server string, req *http.Request) []attribute.KeyValue {
if s.duplicate {
- return append(oldHTTPServer{}.RequestTraceAttrs(server, req), newHTTPServer{}.RequestTraceAttrs(server, req)...)
+ return append(OldHTTPServer{}.RequestTraceAttrs(server, req), CurrentHTTPServer{}.RequestTraceAttrs(server, req)...)
+ }
+ return OldHTTPServer{}.RequestTraceAttrs(server, req)
+}
+
+func (s HTTPServer) NetworkTransportAttr(network string) []attribute.KeyValue {
+ if s.duplicate {
+ return append([]attribute.KeyValue{OldHTTPServer{}.NetworkTransportAttr(network)}, CurrentHTTPServer{}.NetworkTransportAttr(network))
+ }
+ return []attribute.KeyValue{
+ OldHTTPServer{}.NetworkTransportAttr(network),
}
- return oldHTTPServer{}.RequestTraceAttrs(server, req)
}
// ResponseTraceAttrs returns trace attributes for telemetry from an HTTP response.
@@ -60,14 +82,14 @@ func (s HTTPServer) RequestTraceAttrs(server string, req *http.Request) []attrib
// If any of the fields in the ResponseTelemetry are not set the attribute will be omitted.
func (s HTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyValue {
if s.duplicate {
- return append(oldHTTPServer{}.ResponseTraceAttrs(resp), newHTTPServer{}.ResponseTraceAttrs(resp)...)
+ return append(OldHTTPServer{}.ResponseTraceAttrs(resp), CurrentHTTPServer{}.ResponseTraceAttrs(resp)...)
}
- return oldHTTPServer{}.ResponseTraceAttrs(resp)
+ return OldHTTPServer{}.ResponseTraceAttrs(resp)
}
// Route returns the attribute for the route.
func (s HTTPServer) Route(route string) attribute.KeyValue {
- return oldHTTPServer{}.Route(route)
+ return OldHTTPServer{}.Route(route)
}
// Status returns a span status code and message for an HTTP status code
@@ -83,67 +105,120 @@ func (s HTTPServer) Status(code int) (codes.Code, string) {
return codes.Unset, ""
}
-type MetricData struct {
- ServerName string
+type ServerMetricData struct {
+ ServerName string
+ ResponseSize int64
+
+ MetricData
+ MetricAttributes
+}
+
+type MetricAttributes struct {
Req *http.Request
StatusCode int
AdditionalAttributes []attribute.KeyValue
+}
- RequestSize int64
- ResponseSize int64
- ElapsedTime float64
+type MetricData struct {
+ RequestSize int64
+ ElapsedTime float64
}
-func (s HTTPServer) RecordMetrics(ctx context.Context, md MetricData) {
- if s.requestBytesCounter == nil || s.responseBytesCounter == nil || s.serverLatencyMeasure == nil {
- // This will happen if an HTTPServer{} is used insted of NewHTTPServer.
- return
+var (
+ metricAddOptionPool = &sync.Pool{
+ New: func() interface{} {
+ return &[]metric.AddOption{}
+ },
+ }
+
+ metricRecordOptionPool = &sync.Pool{
+ New: func() interface{} {
+ return &[]metric.RecordOption{}
+ },
}
+)
- attributes := oldHTTPServer{}.MetricAttributes(md.ServerName, md.Req, md.StatusCode, md.AdditionalAttributes)
- o := metric.WithAttributeSet(attribute.NewSet(attributes...))
- addOpts := []metric.AddOption{o} // Allocate vararg slice once.
- s.requestBytesCounter.Add(ctx, md.RequestSize, addOpts...)
- s.responseBytesCounter.Add(ctx, md.ResponseSize, addOpts...)
- s.serverLatencyMeasure.Record(ctx, md.ElapsedTime, o)
+func (s HTTPServer) RecordMetrics(ctx context.Context, md ServerMetricData) {
+ if s.requestBytesCounter != nil && s.responseBytesCounter != nil && s.serverLatencyMeasure != nil {
+ attributes := OldHTTPServer{}.MetricAttributes(md.ServerName, md.Req, md.StatusCode, md.AdditionalAttributes)
+ o := metric.WithAttributeSet(attribute.NewSet(attributes...))
+ addOpts := metricAddOptionPool.Get().(*[]metric.AddOption)
+ *addOpts = append(*addOpts, o)
+ s.requestBytesCounter.Add(ctx, md.RequestSize, *addOpts...)
+ s.responseBytesCounter.Add(ctx, md.ResponseSize, *addOpts...)
+ s.serverLatencyMeasure.Record(ctx, md.ElapsedTime, o)
+ *addOpts = (*addOpts)[:0]
+ metricAddOptionPool.Put(addOpts)
+ }
- // TODO: Duplicate Metrics
+ if s.duplicate && s.requestDurationHistogram != nil && s.requestBodySizeHistogram != nil && s.responseBodySizeHistogram != nil {
+ attributes := CurrentHTTPServer{}.MetricAttributes(md.ServerName, md.Req, md.StatusCode, md.AdditionalAttributes)
+ o := metric.WithAttributeSet(attribute.NewSet(attributes...))
+ recordOpts := metricRecordOptionPool.Get().(*[]metric.RecordOption)
+ *recordOpts = append(*recordOpts, o)
+ s.requestBodySizeHistogram.Record(ctx, md.RequestSize, *recordOpts...)
+ s.responseBodySizeHistogram.Record(ctx, md.ResponseSize, *recordOpts...)
+ s.requestDurationHistogram.Record(ctx, md.ElapsedTime, o)
+ *recordOpts = (*recordOpts)[:0]
+ metricRecordOptionPool.Put(recordOpts)
+ }
}
func NewHTTPServer(meter metric.Meter) HTTPServer {
- env := strings.ToLower(os.Getenv("OTEL_SEMCONV_STABILITY_OPT_IN"))
+ env := strings.ToLower(os.Getenv(OTelSemConvStabilityOptIn))
duplicate := env == "http/dup"
server := HTTPServer{
duplicate: duplicate,
}
- server.requestBytesCounter, server.responseBytesCounter, server.serverLatencyMeasure = oldHTTPServer{}.createMeasures(meter)
+ server.requestBytesCounter, server.responseBytesCounter, server.serverLatencyMeasure = OldHTTPServer{}.createMeasures(meter)
+ if duplicate {
+ server.requestBodySizeHistogram, server.responseBodySizeHistogram, server.requestDurationHistogram = CurrentHTTPServer{}.createMeasures(meter)
+ }
return server
}
type HTTPClient struct {
duplicate bool
+
+ // old metrics
+ requestBytesCounter metric.Int64Counter
+ responseBytesCounter metric.Int64Counter
+ latencyMeasure metric.Float64Histogram
+
+ // new metrics
+ requestBodySize metric.Int64Histogram
+ requestDuration metric.Float64Histogram
}
-func NewHTTPClient() HTTPClient {
- env := strings.ToLower(os.Getenv("OTEL_SEMCONV_STABILITY_OPT_IN"))
- return HTTPClient{duplicate: env == "http/dup"}
+func NewHTTPClient(meter metric.Meter) HTTPClient {
+ env := strings.ToLower(os.Getenv(OTelSemConvStabilityOptIn))
+ duplicate := env == "http/dup"
+ client := HTTPClient{
+ duplicate: duplicate,
+ }
+ client.requestBytesCounter, client.responseBytesCounter, client.latencyMeasure = OldHTTPClient{}.createMeasures(meter)
+ if duplicate {
+ client.requestBodySize, client.requestDuration = CurrentHTTPClient{}.createMeasures(meter)
+ }
+
+ return client
}
// RequestTraceAttrs returns attributes for an HTTP request made by a client.
func (c HTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue {
if c.duplicate {
- return append(oldHTTPClient{}.RequestTraceAttrs(req), newHTTPClient{}.RequestTraceAttrs(req)...)
+ return append(OldHTTPClient{}.RequestTraceAttrs(req), CurrentHTTPClient{}.RequestTraceAttrs(req)...)
}
- return oldHTTPClient{}.RequestTraceAttrs(req)
+ return OldHTTPClient{}.RequestTraceAttrs(req)
}
// ResponseTraceAttrs returns metric attributes for an HTTP request made by a client.
func (c HTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue {
if c.duplicate {
- return append(oldHTTPClient{}.ResponseTraceAttrs(resp), newHTTPClient{}.ResponseTraceAttrs(resp)...)
+ return append(OldHTTPClient{}.ResponseTraceAttrs(resp), CurrentHTTPClient{}.ResponseTraceAttrs(resp)...)
}
- return oldHTTPClient{}.ResponseTraceAttrs(resp)
+ return OldHTTPClient{}.ResponseTraceAttrs(resp)
}
func (c HTTPClient) Status(code int) (codes.Code, string) {
@@ -158,8 +233,75 @@ func (c HTTPClient) Status(code int) (codes.Code, string) {
func (c HTTPClient) ErrorType(err error) attribute.KeyValue {
if c.duplicate {
- return newHTTPClient{}.ErrorType(err)
+ return CurrentHTTPClient{}.ErrorType(err)
}
return attribute.KeyValue{}
}
+
+type MetricOpts struct {
+ measurement metric.MeasurementOption
+ addOptions metric.AddOption
+}
+
+func (o MetricOpts) MeasurementOption() metric.MeasurementOption {
+ return o.measurement
+}
+
+func (o MetricOpts) AddOptions() metric.AddOption {
+ return o.addOptions
+}
+
+func (c HTTPClient) MetricOptions(ma MetricAttributes) map[string]MetricOpts {
+ opts := map[string]MetricOpts{}
+
+ attributes := OldHTTPClient{}.MetricAttributes(ma.Req, ma.StatusCode, ma.AdditionalAttributes)
+ set := metric.WithAttributeSet(attribute.NewSet(attributes...))
+ opts["old"] = MetricOpts{
+ measurement: set,
+ addOptions: set,
+ }
+
+ if c.duplicate {
+ attributes := CurrentHTTPClient{}.MetricAttributes(ma.Req, ma.StatusCode, ma.AdditionalAttributes)
+ set := metric.WithAttributeSet(attribute.NewSet(attributes...))
+ opts["new"] = MetricOpts{
+ measurement: set,
+ addOptions: set,
+ }
+ }
+
+ return opts
+}
+
+func (s HTTPClient) RecordMetrics(ctx context.Context, md MetricData, opts map[string]MetricOpts) {
+ if s.requestBytesCounter == nil || s.latencyMeasure == nil {
+ // This will happen if an HTTPClient{} is used instead of NewHTTPClient().
+ return
+ }
+
+ s.requestBytesCounter.Add(ctx, md.RequestSize, opts["old"].AddOptions())
+ s.latencyMeasure.Record(ctx, md.ElapsedTime, opts["old"].MeasurementOption())
+
+ if s.duplicate {
+ s.requestBodySize.Record(ctx, md.RequestSize, opts["new"].MeasurementOption())
+ s.requestDuration.Record(ctx, md.ElapsedTime, opts["new"].MeasurementOption())
+ }
+}
+
+func (s HTTPClient) RecordResponseSize(ctx context.Context, responseData int64, opts map[string]MetricOpts) {
+ if s.responseBytesCounter == nil {
+ // This will happen if an HTTPClient{} is used instead of NewHTTPClient().
+ return
+ }
+
+ s.responseBytesCounter.Add(ctx, responseData, opts["old"].AddOptions())
+}
+
+func (s HTTPClient) TraceAttributes(host string) []attribute.KeyValue {
+ if s.duplicate {
+ return append(OldHTTPClient{}.TraceAttributes(host), CurrentHTTPClient{}.TraceAttributes(host)...)
+ }
+
+ return OldHTTPClient{}.TraceAttributes(host)
+}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go
new file mode 100644
index 0000000..f2cf8a1
--- /dev/null
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/gen.go
@@ -0,0 +1,14 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package semconv // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv"
+
+// Generate semconv package:
+//go:generate gotmpl --body=../../../../../../internal/shared/semconv/bench_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=bench_test.go
+//go:generate gotmpl --body=../../../../../../internal/shared/semconv/env.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=env.go
+//go:generate gotmpl --body=../../../../../../internal/shared/semconv/env_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=env_test.go
+//go:generate gotmpl --body=../../../../../../internal/shared/semconv/httpconv.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=httpconv.go
+//go:generate gotmpl --body=../../../../../../internal/shared/semconv/httpconv_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=httpconv_test.go
+//go:generate gotmpl --body=../../../../../../internal/shared/semconv/util.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=util.go
+//go:generate gotmpl --body=../../../../../../internal/shared/semconv/util_test.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=util_test.go
+//go:generate gotmpl --body=../../../../../../internal/shared/semconv/v1.20.0.go.tmpl "--data={ \"pkg\": \"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp\" }" --out=v1.20.0.go
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/httpconv.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/httpconv.go
index 745b8c6..8b85eff 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/httpconv.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/httpconv.go
@@ -1,3 +1,6 @@
+// Code created by gotmpl. DO NOT MODIFY.
+// source: internal/shared/semconv/httpconv.go.tmpl
+
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
@@ -7,14 +10,17 @@ import (
"fmt"
"net/http"
"reflect"
+ "slices"
"strconv"
"strings"
"go.opentelemetry.io/otel/attribute"
+ "go.opentelemetry.io/otel/metric"
+ "go.opentelemetry.io/otel/metric/noop"
semconvNew "go.opentelemetry.io/otel/semconv/v1.26.0"
)
-type newHTTPServer struct{}
+type CurrentHTTPServer struct{}
// TraceRequest returns trace attributes for an HTTP request received by a
// server.
@@ -32,18 +38,18 @@ type newHTTPServer struct{}
//
// If the primary server name is not known, server should be an empty string.
// The req Host will be used to determine the server instead.
-func (n newHTTPServer) RequestTraceAttrs(server string, req *http.Request) []attribute.KeyValue {
+func (n CurrentHTTPServer) RequestTraceAttrs(server string, req *http.Request) []attribute.KeyValue {
count := 3 // ServerAddress, Method, Scheme
var host string
var p int
if server == "" {
- host, p = splitHostPort(req.Host)
+ host, p = SplitHostPort(req.Host)
} else {
// Prioritize the primary server name.
- host, p = splitHostPort(server)
+ host, p = SplitHostPort(server)
if p < 0 {
- _, p = splitHostPort(req.Host)
+ _, p = SplitHostPort(req.Host)
}
}
@@ -59,7 +65,7 @@ func (n newHTTPServer) RequestTraceAttrs(server string, req *http.Request) []att
scheme := n.scheme(req.TLS != nil)
- if peer, peerPort := splitHostPort(req.RemoteAddr); peer != "" {
+ if peer, peerPort := SplitHostPort(req.RemoteAddr); peer != "" {
// The Go HTTP server sets RemoteAddr to "IP:port", this will not be a
// file-path that would be interpreted with a sock family.
count++
@@ -104,7 +110,7 @@ func (n newHTTPServer) RequestTraceAttrs(server string, req *http.Request) []att
attrs = append(attrs, methodOriginal)
}
- if peer, peerPort := splitHostPort(req.RemoteAddr); peer != "" {
+ if peer, peerPort := SplitHostPort(req.RemoteAddr); peer != "" {
// The Go HTTP server sets RemoteAddr to "IP:port", this will not be a
// file-path that would be interpreted with a sock family.
attrs = append(attrs, semconvNew.NetworkPeerAddress(peer))
@@ -135,7 +141,20 @@ func (n newHTTPServer) RequestTraceAttrs(server string, req *http.Request) []att
return attrs
}
-func (n newHTTPServer) method(method string) (attribute.KeyValue, attribute.KeyValue) {
+func (o CurrentHTTPServer) NetworkTransportAttr(network string) attribute.KeyValue {
+ switch network {
+ case "tcp", "tcp4", "tcp6":
+ return semconvNew.NetworkTransportTCP
+ case "udp", "udp4", "udp6":
+ return semconvNew.NetworkTransportUDP
+ case "unix", "unixgram", "unixpacket":
+ return semconvNew.NetworkTransportUnix
+ default:
+ return semconvNew.NetworkTransportPipe
+ }
+}
+
+func (n CurrentHTTPServer) method(method string) (attribute.KeyValue, attribute.KeyValue) {
if method == "" {
return semconvNew.HTTPRequestMethodGet, attribute.KeyValue{}
}
@@ -150,7 +169,7 @@ func (n newHTTPServer) method(method string) (attribute.KeyValue, attribute.KeyV
return semconvNew.HTTPRequestMethodGet, orig
}
-func (n newHTTPServer) scheme(https bool) attribute.KeyValue { // nolint:revive
+func (n CurrentHTTPServer) scheme(https bool) attribute.KeyValue { // nolint:revive
if https {
return semconvNew.URLScheme("https")
}
@@ -160,7 +179,7 @@ func (n newHTTPServer) scheme(https bool) attribute.KeyValue { // nolint:revive
// TraceResponse returns trace attributes for telemetry from an HTTP response.
//
// If any of the fields in the ResponseTelemetry are not set the attribute will be omitted.
-func (n newHTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyValue {
+func (n CurrentHTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyValue {
var count int
if resp.ReadBytes > 0 {
@@ -195,14 +214,94 @@ func (n newHTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.Ke
}
// Route returns the attribute for the route.
-func (n newHTTPServer) Route(route string) attribute.KeyValue {
+func (n CurrentHTTPServer) Route(route string) attribute.KeyValue {
return semconvNew.HTTPRoute(route)
}
-type newHTTPClient struct{}
+func (n CurrentHTTPServer) createMeasures(meter metric.Meter) (metric.Int64Histogram, metric.Int64Histogram, metric.Float64Histogram) {
+ if meter == nil {
+ return noop.Int64Histogram{}, noop.Int64Histogram{}, noop.Float64Histogram{}
+ }
+
+ var err error
+ requestBodySizeHistogram, err := meter.Int64Histogram(
+ semconvNew.HTTPServerRequestBodySizeName,
+ metric.WithUnit(semconvNew.HTTPServerRequestBodySizeUnit),
+ metric.WithDescription(semconvNew.HTTPServerRequestBodySizeDescription),
+ )
+ handleErr(err)
+
+ responseBodySizeHistogram, err := meter.Int64Histogram(
+ semconvNew.HTTPServerResponseBodySizeName,
+ metric.WithUnit(semconvNew.HTTPServerResponseBodySizeUnit),
+ metric.WithDescription(semconvNew.HTTPServerResponseBodySizeDescription),
+ )
+ handleErr(err)
+ requestDurationHistogram, err := meter.Float64Histogram(
+ semconvNew.HTTPServerRequestDurationName,
+ metric.WithUnit(semconvNew.HTTPServerRequestDurationUnit),
+ metric.WithDescription(semconvNew.HTTPServerRequestDurationDescription),
+ )
+ handleErr(err)
+
+ return requestBodySizeHistogram, responseBodySizeHistogram, requestDurationHistogram
+}
+
+func (n CurrentHTTPServer) MetricAttributes(server string, req *http.Request, statusCode int, additionalAttributes []attribute.KeyValue) []attribute.KeyValue {
+ num := len(additionalAttributes) + 3
+ var host string
+ var p int
+ if server == "" {
+ host, p = SplitHostPort(req.Host)
+ } else {
+ // Prioritize the primary server name.
+ host, p = SplitHostPort(server)
+ if p < 0 {
+ _, p = SplitHostPort(req.Host)
+ }
+ }
+ hostPort := requiredHTTPPort(req.TLS != nil, p)
+ if hostPort > 0 {
+ num++
+ }
+ protoName, protoVersion := netProtocol(req.Proto)
+ if protoName != "" {
+ num++
+ }
+ if protoVersion != "" {
+ num++
+ }
+
+ if statusCode > 0 {
+ num++
+ }
+
+ attributes := slices.Grow(additionalAttributes, num)
+ attributes = append(attributes,
+ semconvNew.HTTPRequestMethodKey.String(standardizeHTTPMethod(req.Method)),
+ n.scheme(req.TLS != nil),
+ semconvNew.ServerAddress(host))
+
+ if hostPort > 0 {
+ attributes = append(attributes, semconvNew.ServerPort(hostPort))
+ }
+ if protoName != "" {
+ attributes = append(attributes, semconvNew.NetworkProtocolName(protoName))
+ }
+ if protoVersion != "" {
+ attributes = append(attributes, semconvNew.NetworkProtocolVersion(protoVersion))
+ }
+
+ if statusCode > 0 {
+ attributes = append(attributes, semconvNew.HTTPResponseStatusCode(statusCode))
+ }
+ return attributes
+}
+
+type CurrentHTTPClient struct{}
// RequestTraceAttrs returns trace attributes for an HTTP request made by a client.
-func (n newHTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue {
+func (n CurrentHTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue {
/*
below attributes are returned:
- http.request.method
@@ -222,7 +321,7 @@ func (n newHTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue
var requestHost string
var requestPort int
for _, hostport := range []string{urlHost, req.Header.Get("Host")} {
- requestHost, requestPort = splitHostPort(hostport)
+ requestHost, requestPort = SplitHostPort(hostport)
if requestHost != "" || requestPort > 0 {
break
}
@@ -284,7 +383,7 @@ func (n newHTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue
}
// ResponseTraceAttrs returns trace attributes for an HTTP response made by a client.
-func (n newHTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue {
+func (n CurrentHTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue {
/*
below attributes are returned:
- http.response.status_code
@@ -311,7 +410,7 @@ func (n newHTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyVa
return attrs
}
-func (n newHTTPClient) ErrorType(err error) attribute.KeyValue {
+func (n CurrentHTTPClient) ErrorType(err error) attribute.KeyValue {
t := reflect.TypeOf(err)
var value string
if t.PkgPath() == "" && t.Name() == "" {
@@ -328,7 +427,7 @@ func (n newHTTPClient) ErrorType(err error) attribute.KeyValue {
return semconvNew.ErrorTypeKey.String(value)
}
-func (n newHTTPClient) method(method string) (attribute.KeyValue, attribute.KeyValue) {
+func (n CurrentHTTPClient) method(method string) (attribute.KeyValue, attribute.KeyValue) {
if method == "" {
return semconvNew.HTTPRequestMethodGet, attribute.KeyValue{}
}
@@ -343,6 +442,98 @@ func (n newHTTPClient) method(method string) (attribute.KeyValue, attribute.KeyV
return semconvNew.HTTPRequestMethodGet, orig
}
+func (n CurrentHTTPClient) createMeasures(meter metric.Meter) (metric.Int64Histogram, metric.Float64Histogram) {
+ if meter == nil {
+ return noop.Int64Histogram{}, noop.Float64Histogram{}
+ }
+
+ var err error
+ requestBodySize, err := meter.Int64Histogram(
+ semconvNew.HTTPClientRequestBodySizeName,
+ metric.WithUnit(semconvNew.HTTPClientRequestBodySizeUnit),
+ metric.WithDescription(semconvNew.HTTPClientRequestBodySizeDescription),
+ )
+ handleErr(err)
+
+ requestDuration, err := meter.Float64Histogram(
+ semconvNew.HTTPClientRequestDurationName,
+ metric.WithUnit(semconvNew.HTTPClientRequestDurationUnit),
+ metric.WithDescription(semconvNew.HTTPClientRequestDurationDescription),
+ )
+ handleErr(err)
+
+ return requestBodySize, requestDuration
+}
+
+func (n CurrentHTTPClient) MetricAttributes(req *http.Request, statusCode int, additionalAttributes []attribute.KeyValue) []attribute.KeyValue {
+ num := len(additionalAttributes) + 2
+ var h string
+ if req.URL != nil {
+ h = req.URL.Host
+ }
+ var requestHost string
+ var requestPort int
+ for _, hostport := range []string{h, req.Header.Get("Host")} {
+ requestHost, requestPort = SplitHostPort(hostport)
+ if requestHost != "" || requestPort > 0 {
+ break
+ }
+ }
+
+ port := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", requestPort)
+ if port > 0 {
+ num++
+ }
+
+ protoName, protoVersion := netProtocol(req.Proto)
+ if protoName != "" {
+ num++
+ }
+ if protoVersion != "" {
+ num++
+ }
+
+ if statusCode > 0 {
+ num++
+ }
+
+ attributes := slices.Grow(additionalAttributes, num)
+ attributes = append(attributes,
+ semconvNew.HTTPRequestMethodKey.String(standardizeHTTPMethod(req.Method)),
+ semconvNew.ServerAddress(requestHost),
+ n.scheme(req.TLS != nil),
+ )
+
+ if port > 0 {
+ attributes = append(attributes, semconvNew.ServerPort(port))
+ }
+ if protoName != "" {
+ attributes = append(attributes, semconvNew.NetworkProtocolName(protoName))
+ }
+ if protoVersion != "" {
+ attributes = append(attributes, semconvNew.NetworkProtocolVersion(protoVersion))
+ }
+
+ if statusCode > 0 {
+ attributes = append(attributes, semconvNew.HTTPResponseStatusCode(statusCode))
+ }
+ return attributes
+}
+
+// Attributes for httptrace.
+func (n CurrentHTTPClient) TraceAttributes(host string) []attribute.KeyValue {
+ return []attribute.KeyValue{
+ semconvNew.ServerAddress(host),
+ }
+}
+
+func (n CurrentHTTPClient) scheme(https bool) attribute.KeyValue { // nolint:revive
+ if https {
+ return semconvNew.URLScheme("https")
+ }
+ return semconvNew.URLScheme("http")
+}
+
func isErrorStatusCode(code int) bool {
return code >= 400 || code < 100
}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go
index e6e1492..315d3dd 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/util.go
@@ -1,3 +1,6 @@
+// Code created by gotmpl. DO NOT MODIFY.
+// source: internal/shared/semconv/util.go.tmpl
+
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
@@ -14,14 +17,14 @@ import (
semconvNew "go.opentelemetry.io/otel/semconv/v1.26.0"
)
-// splitHostPort splits a network address hostport of the form "host",
+// SplitHostPort splits a network address hostport of the form "host",
// "host%zone", "[host]", "[host%zone], "host:port", "host%zone:port",
// "[host]:port", "[host%zone]:port", or ":port" into host or host%zone and
// port.
//
// An empty host is returned if it is not provided or unparsable. A negative
// port is returned if it is not provided or unparsable.
-func splitHostPort(hostport string) (host string, port int) {
+func SplitHostPort(hostport string) (host string, port int) {
port = -1
if strings.HasPrefix(hostport, "[") {
@@ -75,7 +78,16 @@ func serverClientIP(xForwardedFor string) string {
func netProtocol(proto string) (name string, version string) {
name, version, _ = strings.Cut(proto, "/")
- name = strings.ToLower(name)
+ switch name {
+ case "HTTP":
+ name = "http"
+ case "QUIC":
+ name = "quic"
+ case "SPDY":
+ name = "spdy"
+ default:
+ name = strings.ToLower(name)
+ }
return name, version
}
@@ -96,3 +108,13 @@ func handleErr(err error) {
otel.Handle(err)
}
}
+
+func standardizeHTTPMethod(method string) string {
+ method = strings.ToUpper(method)
+ switch method {
+ case http.MethodConnect, http.MethodDelete, http.MethodGet, http.MethodHead, http.MethodOptions, http.MethodPatch, http.MethodPost, http.MethodPut, http.MethodTrace:
+ default:
+ method = "_OTHER"
+ }
+ return method
+}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/v1.20.0.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/v1.20.0.go
index c999b05..742c211 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/v1.20.0.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/v1.20.0.go
@@ -1,3 +1,6 @@
+// Code created by gotmpl. DO NOT MODIFY.
+// source: internal/shared/semconv/v120.0.go.tmpl
+
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
@@ -8,7 +11,6 @@ import (
"io"
"net/http"
"slices"
- "strings"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil"
"go.opentelemetry.io/otel/attribute"
@@ -17,7 +19,7 @@ import (
semconv "go.opentelemetry.io/otel/semconv/v1.20.0"
)
-type oldHTTPServer struct{}
+type OldHTTPServer struct{}
// RequestTraceAttrs returns trace attributes for an HTTP request received by a
// server.
@@ -35,14 +37,18 @@ type oldHTTPServer struct{}
//
// If the primary server name is not known, server should be an empty string.
// The req Host will be used to determine the server instead.
-func (o oldHTTPServer) RequestTraceAttrs(server string, req *http.Request) []attribute.KeyValue {
+func (o OldHTTPServer) RequestTraceAttrs(server string, req *http.Request) []attribute.KeyValue {
return semconvutil.HTTPServerRequest(server, req)
}
+func (o OldHTTPServer) NetworkTransportAttr(network string) attribute.KeyValue {
+ return semconvutil.NetTransport(network)
+}
+
// ResponseTraceAttrs returns trace attributes for telemetry from an HTTP response.
//
// If any of the fields in the ResponseTelemetry are not set the attribute will be omitted.
-func (o oldHTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyValue {
+func (o OldHTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.KeyValue {
attributes := []attribute.KeyValue{}
if resp.ReadBytes > 0 {
@@ -67,7 +73,7 @@ func (o oldHTTPServer) ResponseTraceAttrs(resp ResponseTelemetry) []attribute.Ke
}
// Route returns the attribute for the route.
-func (o oldHTTPServer) Route(route string) attribute.KeyValue {
+func (o OldHTTPServer) Route(route string) attribute.KeyValue {
return semconv.HTTPRoute(route)
}
@@ -84,7 +90,7 @@ const (
serverDuration = "http.server.duration" // Incoming end to end duration, milliseconds
)
-func (h oldHTTPServer) createMeasures(meter metric.Meter) (metric.Int64Counter, metric.Int64Counter, metric.Float64Histogram) {
+func (h OldHTTPServer) createMeasures(meter metric.Meter) (metric.Int64Counter, metric.Int64Counter, metric.Float64Histogram) {
if meter == nil {
return noop.Int64Counter{}, noop.Int64Counter{}, noop.Float64Histogram{}
}
@@ -113,17 +119,17 @@ func (h oldHTTPServer) createMeasures(meter metric.Meter) (metric.Int64Counter,
return requestBytesCounter, responseBytesCounter, serverLatencyMeasure
}
-func (o oldHTTPServer) MetricAttributes(server string, req *http.Request, statusCode int, additionalAttributes []attribute.KeyValue) []attribute.KeyValue {
+func (o OldHTTPServer) MetricAttributes(server string, req *http.Request, statusCode int, additionalAttributes []attribute.KeyValue) []attribute.KeyValue {
n := len(additionalAttributes) + 3
var host string
var p int
if server == "" {
- host, p = splitHostPort(req.Host)
+ host, p = SplitHostPort(req.Host)
} else {
// Prioritize the primary server name.
- host, p = splitHostPort(server)
+ host, p = SplitHostPort(server)
if p < 0 {
- _, p = splitHostPort(req.Host)
+ _, p = SplitHostPort(req.Host)
}
}
hostPort := requiredHTTPPort(req.TLS != nil, p)
@@ -144,7 +150,7 @@ func (o oldHTTPServer) MetricAttributes(server string, req *http.Request, status
attributes := slices.Grow(additionalAttributes, n)
attributes = append(attributes,
- o.methodMetric(req.Method),
+ semconv.HTTPMethod(standardizeHTTPMethod(req.Method)),
o.scheme(req.TLS != nil),
semconv.NetHostName(host))
@@ -164,29 +170,108 @@ func (o oldHTTPServer) MetricAttributes(server string, req *http.Request, status
return attributes
}
-func (o oldHTTPServer) methodMetric(method string) attribute.KeyValue {
- method = strings.ToUpper(method)
- switch method {
- case http.MethodConnect, http.MethodDelete, http.MethodGet, http.MethodHead, http.MethodOptions, http.MethodPatch, http.MethodPost, http.MethodPut, http.MethodTrace:
- default:
- method = "_OTHER"
- }
- return semconv.HTTPMethod(method)
-}
-
-func (o oldHTTPServer) scheme(https bool) attribute.KeyValue { // nolint:revive
+func (o OldHTTPServer) scheme(https bool) attribute.KeyValue { // nolint:revive
if https {
return semconv.HTTPSchemeHTTPS
}
return semconv.HTTPSchemeHTTP
}
-type oldHTTPClient struct{}
+type OldHTTPClient struct{}
-func (o oldHTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue {
+func (o OldHTTPClient) RequestTraceAttrs(req *http.Request) []attribute.KeyValue {
return semconvutil.HTTPClientRequest(req)
}
-func (o oldHTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue {
+func (o OldHTTPClient) ResponseTraceAttrs(resp *http.Response) []attribute.KeyValue {
return semconvutil.HTTPClientResponse(resp)
}
+
+func (o OldHTTPClient) MetricAttributes(req *http.Request, statusCode int, additionalAttributes []attribute.KeyValue) []attribute.KeyValue {
+ /* The following semantic conventions are returned if present:
+ http.method string
+ http.status_code int
+ net.peer.name string
+ net.peer.port int
+ */
+
+ n := 2 // method, peer name.
+ var h string
+ if req.URL != nil {
+ h = req.URL.Host
+ }
+ var requestHost string
+ var requestPort int
+ for _, hostport := range []string{h, req.Header.Get("Host")} {
+ requestHost, requestPort = SplitHostPort(hostport)
+ if requestHost != "" || requestPort > 0 {
+ break
+ }
+ }
+
+ port := requiredHTTPPort(req.URL != nil && req.URL.Scheme == "https", requestPort)
+ if port > 0 {
+ n++
+ }
+
+ if statusCode > 0 {
+ n++
+ }
+
+ attributes := slices.Grow(additionalAttributes, n)
+ attributes = append(attributes,
+ semconv.HTTPMethod(standardizeHTTPMethod(req.Method)),
+ semconv.NetPeerName(requestHost),
+ )
+
+ if port > 0 {
+ attributes = append(attributes, semconv.NetPeerPort(port))
+ }
+
+ if statusCode > 0 {
+ attributes = append(attributes, semconv.HTTPStatusCode(statusCode))
+ }
+ return attributes
+}
+
+// Client HTTP metrics.
+const (
+ clientRequestSize = "http.client.request.size" // Incoming request bytes total
+ clientResponseSize = "http.client.response.size" // Incoming response bytes total
+ clientDuration = "http.client.duration" // Incoming end to end duration, milliseconds
+)
+
+func (o OldHTTPClient) createMeasures(meter metric.Meter) (metric.Int64Counter, metric.Int64Counter, metric.Float64Histogram) {
+ if meter == nil {
+ return noop.Int64Counter{}, noop.Int64Counter{}, noop.Float64Histogram{}
+ }
+ requestBytesCounter, err := meter.Int64Counter(
+ clientRequestSize,
+ metric.WithUnit("By"),
+ metric.WithDescription("Measures the size of HTTP request messages."),
+ )
+ handleErr(err)
+
+ responseBytesCounter, err := meter.Int64Counter(
+ clientResponseSize,
+ metric.WithUnit("By"),
+ metric.WithDescription("Measures the size of HTTP response messages."),
+ )
+ handleErr(err)
+
+ latencyMeasure, err := meter.Float64Histogram(
+ clientDuration,
+ metric.WithUnit("ms"),
+ metric.WithDescription("Measures the duration of outbound HTTP requests."),
+ )
+ handleErr(err)
+
+ return requestBytesCounter, responseBytesCounter, latencyMeasure
+}
+
+// Attributes for httptrace.
+func (c OldHTTPClient) TraceAttributes(host string) []attribute.KeyValue {
+ return []attribute.KeyValue{
+ semconv.NetHostName(host),
+ }
+}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/netconv.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/netconv.go
index b80a1db..de74fa2 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/netconv.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil/netconv.go
@@ -200,6 +200,15 @@ func splitHostPort(hostport string) (host string, port int) {
func netProtocol(proto string) (name string, version string) {
name, version, _ = strings.Cut(proto, "/")
- name = strings.ToLower(name)
+ switch name {
+ case "HTTP":
+ name = "http"
+ case "QUIC":
+ name = "quic"
+ case "SPDY":
+ name = "spdy"
+ default:
+ name = strings.ToLower(name)
+ }
return name, version
}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/start_time_context.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/start_time_context.go
new file mode 100644
index 0000000..9476ef0
--- /dev/null
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/start_time_context.go
@@ -0,0 +1,29 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
+
+import (
+ "context"
+ "time"
+)
+
+type startTimeContextKeyType int
+
+const startTimeContextKey startTimeContextKeyType = 0
+
+// ContextWithStartTime returns a new context with the provided start time. The
+// start time will be used for metrics and traces emitted by the
+// instrumentation. Only one labeller can be injected into the context.
+// Injecting it multiple times will override the previous calls.
+func ContextWithStartTime(parent context.Context, start time.Time) context.Context {
+ return context.WithValue(parent, startTimeContextKey, start)
+}
+
+// StartTimeFromContext retrieves a time.Time from the provided context if one
+// is available. If no start time was found in the provided context, a new,
+// zero start time is returned and the second return value is false.
+func StartTimeFromContext(ctx context.Context) time.Time {
+ t, _ := ctx.Value(startTimeContextKey).(time.Time)
+ return t
+}
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go
index b4119d3..44b86ad 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/transport.go
@@ -13,11 +13,9 @@ import (
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/request"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv"
- "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
- "go.opentelemetry.io/otel/metric"
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/trace"
@@ -29,7 +27,6 @@ type Transport struct {
rt http.RoundTripper
tracer trace.Tracer
- meter metric.Meter
propagators propagation.TextMapPropagator
spanStartOptions []trace.SpanStartOption
filters []Filter
@@ -37,10 +34,7 @@ type Transport struct {
clientTrace func(context.Context) *httptrace.ClientTrace
metricAttributesFn func(*http.Request) []attribute.KeyValue
- semconv semconv.HTTPClient
- requestBytesCounter metric.Int64Counter
- responseBytesCounter metric.Int64Counter
- latencyMeasure metric.Float64Histogram
+ semconv semconv.HTTPClient
}
var _ http.RoundTripper = &Transport{}
@@ -57,8 +51,7 @@ func NewTransport(base http.RoundTripper, opts ...Option) *Transport {
}
t := Transport{
- rt: base,
- semconv: semconv.NewHTTPClient(),
+ rt: base,
}
defaultOpts := []Option{
@@ -68,46 +61,21 @@ func NewTransport(base http.RoundTripper, opts ...Option) *Transport {
c := newConfig(append(defaultOpts, opts...)...)
t.applyConfig(c)
- t.createMeasures()
return &t
}
func (t *Transport) applyConfig(c *config) {
t.tracer = c.Tracer
- t.meter = c.Meter
t.propagators = c.Propagators
t.spanStartOptions = c.SpanStartOptions
t.filters = c.Filters
t.spanNameFormatter = c.SpanNameFormatter
t.clientTrace = c.ClientTrace
+ t.semconv = semconv.NewHTTPClient(c.Meter)
t.metricAttributesFn = c.MetricAttributesFn
}
-func (t *Transport) createMeasures() {
- var err error
- t.requestBytesCounter, err = t.meter.Int64Counter(
- clientRequestSize,
- metric.WithUnit("By"),
- metric.WithDescription("Measures the size of HTTP request messages."),
- )
- handleErr(err)
-
- t.responseBytesCounter, err = t.meter.Int64Counter(
- clientResponseSize,
- metric.WithUnit("By"),
- metric.WithDescription("Measures the size of HTTP response messages."),
- )
- handleErr(err)
-
- t.latencyMeasure, err = t.meter.Float64Histogram(
- clientDuration,
- metric.WithUnit("ms"),
- metric.WithDescription("Measures the duration of outbound HTTP requests."),
- )
- handleErr(err)
-}
-
func defaultTransportFormatter(_ string, r *http.Request) string {
return "HTTP " + r.Method
}
@@ -177,16 +145,15 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {
}
// metrics
- metricAttrs := append(append(labeler.Get(), semconvutil.HTTPClientRequestMetrics(r)...), t.metricAttributesFromRequest(r)...)
- if res.StatusCode > 0 {
- metricAttrs = append(metricAttrs, semconv.HTTPStatusCode(res.StatusCode))
- }
- o := metric.WithAttributeSet(attribute.NewSet(metricAttrs...))
+ metricOpts := t.semconv.MetricOptions(semconv.MetricAttributes{
+ Req: r,
+ StatusCode: res.StatusCode,
+ AdditionalAttributes: append(labeler.Get(), t.metricAttributesFromRequest(r)...),
+ })
- t.requestBytesCounter.Add(ctx, bw.BytesRead(), o)
// For handling response bytes we leverage a callback when the client reads the http response
readRecordFunc := func(n int64) {
- t.responseBytesCounter.Add(ctx, n, o)
+ t.semconv.RecordResponseSize(ctx, n, metricOpts)
}
// traces
@@ -198,9 +165,12 @@ func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {
// Use floating point division here for higher precision (instead of Millisecond method).
elapsedTime := float64(time.Since(requestStartTime)) / float64(time.Millisecond)
- t.latencyMeasure.Record(ctx, elapsedTime, o)
+ t.semconv.RecordMetrics(ctx, semconv.MetricData{
+ RequestSize: bw.BytesRead(),
+ ElapsedTime: elapsedTime,
+ }, metricOpts)
- return res, err
+ return res, nil
}
func (t *Transport) metricAttributesFromRequest(r *http.Request) []attribute.KeyValue {
diff --git a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go
index 502c1bd..1ec9a00 100644
--- a/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go
+++ b/vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go
@@ -5,7 +5,7 @@ package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http
// Version is the current release version of the otelhttp instrumentation.
func Version() string {
- return "0.54.0"
+ return "0.60.0"
// This string is updated by the pre_release.sh script during release
}