79 lines
2.2 KiB
Go
79 lines
2.2 KiB
Go
|
package unitel
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"net/http"
|
||
|
|
||
|
"github.com/getsentry/sentry-go"
|
||
|
"go.opentelemetry.io/otel/attribute"
|
||
|
semconv "go.opentelemetry.io/otel/semconv/v1.26.0"
|
||
|
"go.opentelemetry.io/otel/trace"
|
||
|
)
|
||
|
|
||
|
const httpClientTransportClientID = libBase + "#HTTPTansport"
|
||
|
|
||
|
type HTTPTransport struct {
|
||
|
telemetry *Telemetry
|
||
|
forwardTrace bool
|
||
|
tracedRequestHeaders []string
|
||
|
tracedResponseHeaders []string
|
||
|
Transport http.RoundTripper
|
||
|
|
||
|
tracer trace.Tracer
|
||
|
}
|
||
|
|
||
|
func (t *Telemetry) NewTracedTransport(transport http.RoundTripper, forwardTrace bool, tracedRequestHeaders []string, tracedResponseHeaders []string) *HTTPTransport {
|
||
|
return &HTTPTransport{
|
||
|
telemetry: t,
|
||
|
forwardTrace: forwardTrace,
|
||
|
tracedRequestHeaders: tracedRequestHeaders,
|
||
|
tracedResponseHeaders: tracedResponseHeaders,
|
||
|
Transport: transport,
|
||
|
|
||
|
tracer: t.tracerProvider.Tracer(httpClientTransportClientID, trace.WithInstrumentationVersion(libVersion)),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (t *HTTPTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||
|
span := t.telemetry.
|
||
|
StartSpan(req.Context(), "http.client", fmt.Sprintf("%s %s", req.Method, req.URL), WithOtelOptions(trace.WithSpanKind(trace.SpanKindClient))).
|
||
|
AddAttributes(
|
||
|
semconv.HTTPRequestMethodKey.String(req.Method),
|
||
|
semconv.URLFull(req.URL.String()),
|
||
|
)
|
||
|
defer span.End()
|
||
|
ctx := span.Context()
|
||
|
req = req.WithContext(ctx)
|
||
|
|
||
|
if t.forwardTrace {
|
||
|
t.telemetry.InjectIntoHeaders(ctx, req.Header)
|
||
|
}
|
||
|
|
||
|
for _, header := range t.tracedRequestHeaders {
|
||
|
if v := req.Header.Get(header); v != "" {
|
||
|
span.AddAttributes(attribute.String(fmt.Sprintf("http.request.header.%s", header), v))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
resp, err := t.Transport.RoundTrip(req)
|
||
|
if err != nil {
|
||
|
if hub := sentry.GetHubFromContext(ctx); hub != nil {
|
||
|
hub.CaptureException(err)
|
||
|
}
|
||
|
|
||
|
return resp, err
|
||
|
}
|
||
|
|
||
|
span.
|
||
|
AddAttributes(semconv.HTTPResponseStatusCode(resp.StatusCode)).
|
||
|
SetStatus(httpStatusToSpanStatus(resp.StatusCode, false), "")
|
||
|
|
||
|
for _, header := range t.tracedResponseHeaders {
|
||
|
if v := resp.Header.Get(header); v != "" {
|
||
|
span.AddAttributes(attribute.String(fmt.Sprintf("http.response.header.%s", header), v))
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return resp, err
|
||
|
}
|