TUN-6030: Add ttfb span for origin http request

This commit is contained in:
Devin Carr
2022-04-11 16:02:13 -07:00
parent 775c2bc93e
commit a97233bb3e
6 changed files with 57 additions and 25 deletions

View File

@@ -3,7 +3,10 @@ package tracing
import (
"context"
"errors"
"fmt"
"net/http"
"os"
"runtime"
"github.com/rs/zerolog"
otelContrib "go.opentelemetry.io/contrib/propagators/Jaeger"
@@ -22,19 +25,26 @@ const (
service = "cloudflared"
tracerInstrumentName = "origin"
tracerContextName = "cf-trace-id"
tracerContextNameOverride = "uber-trace-id"
TracerContextName = "cf-trace-id"
TracerContextNameOverride = "uber-trace-id"
IntCloudflaredTracingHeader = "cf-int-cloudflared-tracing"
)
var (
CanonicalCloudflaredTracingHeader = http.CanonicalHeaderKey(IntCloudflaredTracingHeader)
Http2TransportAttribute = trace.WithAttributes(TransportAttributeKey.String("http2"))
QuicTransportAttribute = trace.WithAttributes(TransportAttributeKey.String("quic"))
Http2TransportAttribute = trace.WithAttributes(transportAttributeKey.String("http2"))
QuicTransportAttribute = trace.WithAttributes(transportAttributeKey.String("quic"))
HostOSAttribute = semconv.HostTypeKey.String(runtime.GOOS)
HostArchAttribute = semconv.HostArchKey.String(runtime.GOARCH)
TransportAttributeKey = attribute.Key("transport")
TrafficAttributeKey = attribute.Key("traffic")
otelVersionAttribute attribute.KeyValue
hostnameAttribute attribute.KeyValue
cloudflaredVersionAttribute attribute.KeyValue
serviceAttribute = semconv.ServiceNameKey.String(service)
transportAttributeKey = attribute.Key("transport")
otelVersionAttributeKey = attribute.Key("jaeger.version")
errNoopTracerProvider = errors.New("noop tracer provider records no spans")
)
@@ -42,6 +52,14 @@ var (
func init() {
// Register the jaeger propagator globally.
otel.SetTextMapPropagator(otelContrib.Jaeger{})
otelVersionAttribute = otelVersionAttributeKey.String(fmt.Sprintf("go-otel-%s", otel.Version()))
if hostname, err := os.Hostname(); err == nil {
hostnameAttribute = attribute.String("hostname", hostname)
}
}
func Init(version string) {
cloudflaredVersionAttribute = semconv.ProcessRuntimeVersionKey.String(version)
}
type TracedRequest struct {
@@ -67,7 +85,12 @@ func NewTracedRequest(req *http.Request) *TracedRequest {
// Record information about this application in a Resource.
tracesdk.WithResource(resource.NewWithAttributes(
semconv.SchemaURL,
semconv.ServiceNameKey.String(service),
serviceAttribute,
otelVersionAttribute,
hostnameAttribute,
cloudflaredVersionAttribute,
HostOSAttribute,
HostArchAttribute,
)),
)
@@ -110,27 +133,28 @@ func EndWithStatus(span trace.Span, code codes.Code, status string) {
span.End()
}
// extractTrace attempts to check for a cf-trace-id from a request header.
// extractTrace attempts to check for a cf-trace-id from a request and return the
// trace context with the provided http.Request.
func extractTrace(req *http.Request) (context.Context, bool) {
// Only add tracing for requests with appropriately tagged headers
remoteTraces := req.Header.Values(tracerContextName)
remoteTraces := req.Header.Values(TracerContextName)
if len(remoteTraces) <= 0 {
// Strip the cf-trace-id header
req.Header.Del(tracerContextName)
req.Header.Del(TracerContextName)
return nil, false
}
traceHeader := make(map[string]string, 1)
traceHeader := map[string]string{}
for _, t := range remoteTraces {
// Override the 'cf-trace-id' as 'uber-trace-id' so the jaeger propagator can extract it.
// Last entry wins if multiple provided
traceHeader[tracerContextNameOverride] = t
traceHeader[TracerContextNameOverride] = t
}
// Strip the cf-trace-id header
req.Header.Del(tracerContextName)
req.Header.Del(TracerContextName)
if traceHeader[tracerContextNameOverride] == "" {
if traceHeader[TracerContextNameOverride] == "" {
return nil, false
}
remoteCtx := otel.GetTextMapPropagator().Extract(req.Context(), propagation.MapCarrier(traceHeader))