1
0
Fork 0

Migrate to opentelemetry

This commit is contained in:
Jesse Haka 2024-01-08 10:10:06 +02:00 committed by GitHub
parent 45bb00be04
commit 4ddef9830b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
89 changed files with 2113 additions and 3898 deletions

View file

@ -22,9 +22,13 @@ const StatusClientClosedRequest = 499
const StatusClientClosedRequestText = "Client Closed Request"
func buildSingleHostProxy(target *url.URL, passHostHeader bool, flushInterval time.Duration, roundTripper http.RoundTripper, bufferPool httputil.BufferPool) http.Handler {
// Wrapping the roundTripper with the Tracing roundTripper,
// to handle the reverseProxy client span creation.
tracingRoundTripper := newTracingRoundTripper(roundTripper)
return &httputil.ReverseProxy{
Director: directorBuilder(target, passHostHeader),
Transport: roundTripper,
Transport: tracingRoundTripper,
FlushInterval: flushInterval,
BufferPool: bufferPool,
ErrorHandler: errorHandler,
@ -94,23 +98,7 @@ func isWebSocketUpgrade(req *http.Request) bool {
}
func errorHandler(w http.ResponseWriter, req *http.Request, err error) {
statusCode := http.StatusInternalServerError
switch {
case errors.Is(err, io.EOF):
statusCode = http.StatusBadGateway
case errors.Is(err, context.Canceled):
statusCode = StatusClientClosedRequest
default:
var netErr net.Error
if errors.As(err, &netErr) {
if netErr.Timeout() {
statusCode = http.StatusGatewayTimeout
} else {
statusCode = http.StatusBadGateway
}
}
}
statusCode := computeStatusCode(err)
logger := log.Ctx(req.Context())
logger.Debug().Err(err).Msgf("%d %s", statusCode, statusText(statusCode))
@ -121,6 +109,26 @@ func errorHandler(w http.ResponseWriter, req *http.Request, err error) {
}
}
func computeStatusCode(err error) int {
switch {
case errors.Is(err, io.EOF):
return http.StatusBadGateway
case errors.Is(err, context.Canceled):
return StatusClientClosedRequest
default:
var netErr net.Error
if errors.As(err, &netErr) {
if netErr.Timeout() {
return http.StatusGatewayTimeout
}
return http.StatusBadGateway
}
}
return http.StatusInternalServerError
}
func statusText(statusCode int) string {
if statusCode == StatusClientClosedRequest {
return StatusClientClosedRequestText

View file

@ -14,6 +14,7 @@ import (
"strings"
"time"
"github.com/containous/alice"
"github.com/rs/zerolog/log"
"github.com/traefik/traefik/v3/pkg/config/dynamic"
"github.com/traefik/traefik/v3/pkg/config/runtime"
@ -22,6 +23,7 @@ import (
"github.com/traefik/traefik/v3/pkg/metrics"
"github.com/traefik/traefik/v3/pkg/middlewares/accesslog"
metricsMiddle "github.com/traefik/traefik/v3/pkg/middlewares/metrics"
tracingMiddle "github.com/traefik/traefik/v3/pkg/middlewares/tracing"
"github.com/traefik/traefik/v3/pkg/safe"
"github.com/traefik/traefik/v3/pkg/server/cookie"
"github.com/traefik/traefik/v3/pkg/server/provider"
@ -305,9 +307,18 @@ func (m *Manager) getLoadBalancerServiceHandler(ctx context.Context, serviceName
proxy = accesslog.NewFieldHandler(proxy, accesslog.ServiceName, serviceName, accesslog.AddServiceFields)
if m.metricsRegistry != nil && m.metricsRegistry.IsSvcEnabled() {
proxy = metricsMiddle.NewServiceMiddleware(ctx, proxy, m.metricsRegistry, serviceName)
metricsHandler := metricsMiddle.WrapServiceHandler(ctx, m.metricsRegistry, serviceName)
proxy, err = alice.New().
Append(tracingMiddle.WrapMiddleware(ctx, metricsHandler)).
Then(proxy)
if err != nil {
return nil, fmt.Errorf("error wrapping metrics handler: %w", err)
}
}
proxy = tracingMiddle.NewService(ctx, serviceName, proxy)
lb.Add(proxyName, proxy, nil)
// servers are considered UP by default.

View file

@ -0,0 +1,42 @@
package service
import (
"context"
"net/http"
"github.com/traefik/traefik/v3/pkg/tracing"
"go.opentelemetry.io/otel/trace"
)
type wrapper struct {
rt http.RoundTripper
}
func (t *wrapper) RoundTrip(req *http.Request) (*http.Response, error) {
var span trace.Span
if tracer := tracing.TracerFromContext(req.Context()); tracer != nil {
var tracingCtx context.Context
tracingCtx, span = tracer.Start(req.Context(), "ReverseProxy", trace.WithSpanKind(trace.SpanKindClient))
defer span.End()
req = req.WithContext(tracingCtx)
tracing.LogClientRequest(span, req)
tracing.InjectContextIntoCarrier(req)
}
response, err := t.rt.RoundTrip(req)
if err != nil {
statusCode := computeStatusCode(err)
tracing.LogResponseCode(span, statusCode, trace.SpanKindClient)
return response, err
}
tracing.LogResponseCode(span, response.StatusCode, trace.SpanKindClient)
return response, nil
}
func newTracingRoundTripper(rt http.RoundTripper) http.RoundTripper {
return &wrapper{rt: rt}
}