mirror of
https://github.com/hanzoai/krakend-otel.git
synced 2026-09-30 22:49:38 +00:00
Merge pull request #60 from krakend/sc-842/traces_skip_headers
Traces skip headers options
This commit is contained in:
@@ -144,6 +144,7 @@ type GlobalOpts struct {
|
||||
DisableTraces bool `json:"disable_traces"`
|
||||
DisablePropagation bool `json:"disable_propagation"`
|
||||
ReportHeaders bool `json:"report_headers"`
|
||||
SkipHeaders []string `json:"skip_headers"`
|
||||
MetricsStaticAttributes Attributes `json:"metrics_static_attributes"`
|
||||
TracesStaticAttributes Attributes `json:"traces_static_attributes"`
|
||||
SemConv string `json:"semantic_convention"`
|
||||
@@ -155,6 +156,7 @@ type PipeOpts struct {
|
||||
DisableMetrics bool `json:"disable_metrics"`
|
||||
DisableTraces bool `json:"disable_traces"`
|
||||
ReportHeaders bool `json:"report_headers"`
|
||||
SkipHeaders []string `json:"skip_headers"`
|
||||
MetricsStaticAttributes Attributes `json:"metrics_static_attributes"`
|
||||
TracesStaticAttributes Attributes `json:"traces_static_attributes"`
|
||||
}
|
||||
@@ -255,6 +257,7 @@ type BackendTraceOpts struct {
|
||||
DetailedConnection bool `json:"detailed_connection"`
|
||||
StaticAttributes Attributes `json:"static_attributes"`
|
||||
ReportHeaders bool `json:"report_headers"`
|
||||
SkipHeaders []string `json:"skip_headers"`
|
||||
}
|
||||
|
||||
// Enabled tells if there are any traces to be reported.
|
||||
|
||||
@@ -21,6 +21,7 @@ type TransportTracesOptions struct {
|
||||
DetailedConnection bool // add extra detail about the connection to the server: dns lookup, tls...
|
||||
FixedAttributes []attribute.KeyValue // "static" attributes set at config time.
|
||||
ReportHeaders bool
|
||||
SkipHeaders []string
|
||||
}
|
||||
|
||||
// Enabled returns if the transport should create a trace.
|
||||
@@ -34,19 +35,27 @@ type transportTraces struct {
|
||||
fixedAttrs []attribute.KeyValue
|
||||
detailedConnection bool
|
||||
reportHeaders bool
|
||||
skipHeaders map[string]bool
|
||||
}
|
||||
|
||||
func newTransportTraces(tracesOpts *TransportTracesOptions, tracer trace.Tracer, spanName string) *transportTraces {
|
||||
if tracer == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
var sh map[string]bool
|
||||
if len(tracesOpts.SkipHeaders) > 0 {
|
||||
sh = make(map[string]bool, len(tracesOpts.SkipHeaders))
|
||||
for _, v := range tracesOpts.SkipHeaders {
|
||||
sh[v] = true
|
||||
}
|
||||
}
|
||||
return &transportTraces{
|
||||
tracer: tracer,
|
||||
spanName: spanName,
|
||||
fixedAttrs: tracesOpts.FixedAttributes,
|
||||
detailedConnection: tracesOpts.DetailedConnection,
|
||||
reportHeaders: tracesOpts.ReportHeaders,
|
||||
skipHeaders: sh,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +84,7 @@ func (t *transportTraces) start(rtt *roundTripTracking,
|
||||
header := make(http.Header, len(rtt.req.Header)+1)
|
||||
for k, v := range rtt.req.Header {
|
||||
header[k] = v
|
||||
if t.reportHeaders {
|
||||
if t.reportHeaders && (t.skipHeaders == nil || !t.skipHeaders[k]) {
|
||||
reqAttrs = append(reqAttrs,
|
||||
attribute.StringSlice("http.request.header."+strings.ToLower(k), v))
|
||||
}
|
||||
@@ -99,8 +108,10 @@ func (t *transportTraces) end(rtt *roundTripTracking) {
|
||||
respAttrs := otelhttp.TraceResponseAttrs(rtt.resp)
|
||||
if t.reportHeaders {
|
||||
for k, v := range rtt.resp.Header {
|
||||
respAttrs = append(respAttrs,
|
||||
attribute.StringSlice("http.response.header."+strings.ToLower(k), v))
|
||||
if t.skipHeaders == nil || !t.skipHeaders[k] {
|
||||
respAttrs = append(respAttrs,
|
||||
attribute.StringSlice("http.response.header."+strings.ToLower(k), v))
|
||||
}
|
||||
}
|
||||
}
|
||||
rtt.span.SetAttributes(respAttrs...)
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
type TrackingResponseWriter struct {
|
||||
track *tracking
|
||||
recordHeaders bool
|
||||
skipHeaders map[string]bool
|
||||
rw http.ResponseWriter
|
||||
flusher http.Flusher
|
||||
hijacker http.Hijacker
|
||||
@@ -27,7 +28,9 @@ func (w *TrackingResponseWriter) gatherHeaders() {
|
||||
h := w.rw.Header()
|
||||
w.track.responseHeaders = make(map[string][]string, len(h))
|
||||
for k, v := range h {
|
||||
w.track.responseHeaders[k] = v
|
||||
if w.skipHeaders == nil || !w.skipHeaders[k] {
|
||||
w.track.responseHeaders[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,13 +83,14 @@ func (w *TrackingResponseWriter) Flush() {
|
||||
}
|
||||
|
||||
func newTrackingResponseWriter(rw http.ResponseWriter, t *tracking, recordHeaders bool,
|
||||
hijackCallback func(net.Conn, error) (net.Conn, error),
|
||||
skipHeaders map[string]bool, hijackCallback func(net.Conn, error) (net.Conn, error),
|
||||
) *TrackingResponseWriter {
|
||||
flusher, _ := rw.(http.Flusher)
|
||||
hijacker, _ := rw.(http.Hijacker)
|
||||
return &TrackingResponseWriter{
|
||||
track: t,
|
||||
recordHeaders: recordHeaders,
|
||||
skipHeaders: skipHeaders,
|
||||
rw: rw,
|
||||
flusher: flusher,
|
||||
hijacker: hijacker,
|
||||
|
||||
+13
-3
@@ -19,6 +19,7 @@ type trackingHandler struct {
|
||||
metrics *metricsHTTP
|
||||
traces *tracesHTTP
|
||||
reportHeaders bool
|
||||
skipHeaders map[string]bool
|
||||
config state.Config
|
||||
}
|
||||
|
||||
@@ -40,7 +41,7 @@ func (h *trackingHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
r = r.WithContext(t.ctx)
|
||||
|
||||
if h.metrics != nil || h.traces != nil {
|
||||
rw = newTrackingResponseWriter(rw, t, h.reportHeaders, func(c net.Conn, _ error) (net.Conn, error) {
|
||||
rw = newTrackingResponseWriter(rw, t, h.reportHeaders, h.skipHeaders, func(c net.Conn, _ error) (net.Conn, error) {
|
||||
t.Finish()
|
||||
h.traces.end(t)
|
||||
h.metrics.report(t, r)
|
||||
@@ -60,7 +61,7 @@ func NewTrackingHandler(next http.Handler) http.Handler {
|
||||
return NewTrackingHandlerWithTrustedProxies(next, nil)
|
||||
}
|
||||
|
||||
func NewTrackingHandlerWithTrustedProxies(next http.Handler, trustedProxies []string) http.Handler {
|
||||
func NewTrackingHandlerWithTrustedProxies(next http.Handler, trustedProxies []string) http.Handler { // skipcq: GO-R1005
|
||||
otelCfg := state.GlobalConfig()
|
||||
if otelCfg == nil {
|
||||
return next
|
||||
@@ -88,6 +89,14 @@ func NewTrackingHandlerWithTrustedProxies(next http.Handler, trustedProxies []st
|
||||
m = newMetricsHTTP(s.Meter(), metricsAttrs, gCfg.SemConv)
|
||||
}
|
||||
|
||||
var sh map[string]bool
|
||||
if len(gCfg.SkipHeaders) > 0 {
|
||||
sh = make(map[string]bool, len(gCfg.SkipHeaders))
|
||||
for _, v := range gCfg.SkipHeaders {
|
||||
sh[v] = true
|
||||
}
|
||||
}
|
||||
|
||||
var t *tracesHTTP
|
||||
if !gCfg.DisableTraces {
|
||||
tracesAttrs := []attribute.KeyValue{attribute.String("krakend.stage", "global")}
|
||||
@@ -97,7 +106,7 @@ func NewTrackingHandlerWithTrustedProxies(next http.Handler, trustedProxies []st
|
||||
}
|
||||
}
|
||||
|
||||
t = newTracesHTTP(s.Tracer(), tracesAttrs, gCfg.ReportHeaders, trustedProxies)
|
||||
t = newTracesHTTP(s.Tracer(), tracesAttrs, gCfg.ReportHeaders, sh, trustedProxies)
|
||||
}
|
||||
|
||||
return &trackingHandler{
|
||||
@@ -106,6 +115,7 @@ func NewTrackingHandlerWithTrustedProxies(next http.Handler, trustedProxies []st
|
||||
metrics: m,
|
||||
traces: t,
|
||||
reportHeaders: gCfg.ReportHeaders,
|
||||
skipHeaders: sh,
|
||||
config: otelCfg,
|
||||
}
|
||||
}
|
||||
|
||||
+25
-7
@@ -16,11 +16,12 @@ type tracesHTTP struct {
|
||||
tracer trace.Tracer
|
||||
fixedAttrs []attribute.KeyValue
|
||||
reportHeaders bool
|
||||
skipHeaders map[string]bool
|
||||
trustedProxies map[string]bool
|
||||
}
|
||||
|
||||
func newTracesHTTP(tracer trace.Tracer, attrs []attribute.KeyValue,
|
||||
reportHeaders bool, trustedProxies []string,
|
||||
reportHeaders bool, skipHeaders map[string]bool, trustedProxies []string,
|
||||
) *tracesHTTP {
|
||||
var fa []attribute.KeyValue
|
||||
if len(attrs) > 0 {
|
||||
@@ -36,6 +37,7 @@ func newTracesHTTP(tracer trace.Tracer, attrs []attribute.KeyValue,
|
||||
tracer: tracer,
|
||||
fixedAttrs: fa,
|
||||
reportHeaders: reportHeaders,
|
||||
skipHeaders: skipHeaders,
|
||||
trustedProxies: tpm,
|
||||
}
|
||||
}
|
||||
@@ -58,9 +60,17 @@ func (t *tracesHTTP) start(r *http.Request, tr *tracking) *http.Request {
|
||||
tr.span.SetAttributes(t.fixedAttrs...)
|
||||
}
|
||||
if t.reportHeaders {
|
||||
// report all incoming headers
|
||||
for hk, hv := range r.Header {
|
||||
tr.span.SetAttributes(attribute.StringSlice("http.request.header."+strings.ToLower(hk), hv))
|
||||
if len(t.skipHeaders) == 0 {
|
||||
// report all incoming headers
|
||||
for hk, hv := range r.Header {
|
||||
tr.span.SetAttributes(attribute.StringSlice("http.request.header."+strings.ToLower(hk), hv))
|
||||
}
|
||||
} else {
|
||||
for hk, hv := range r.Header {
|
||||
if !t.skipHeaders[hk] {
|
||||
tr.span.SetAttributes(attribute.StringSlice("http.request.header."+strings.ToLower(hk), hv))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return r
|
||||
@@ -86,9 +96,17 @@ func (t *tracesHTTP) end(tr *tracking) {
|
||||
tr.span.SetAttributes(tr.tracesStaticAttrs...)
|
||||
|
||||
if tr.responseHeaders != nil {
|
||||
// report all incoming headers
|
||||
for hk, hv := range tr.responseHeaders {
|
||||
tr.span.SetAttributes(attribute.StringSlice("http.response.header."+strings.ToLower(hk), hv))
|
||||
if len(t.skipHeaders) == 0 {
|
||||
// report all incoming headers
|
||||
for hk, hv := range tr.responseHeaders {
|
||||
tr.span.SetAttributes(attribute.StringSlice("http.response.header."+strings.ToLower(hk), hv))
|
||||
}
|
||||
} else {
|
||||
for hk, hv := range tr.responseHeaders {
|
||||
if !t.skipHeaders[hk] {
|
||||
tr.span.SetAttributes(attribute.StringSlice("http.response.header."+strings.ToLower(hk), hv))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(tr.writeErrs) > 0 {
|
||||
|
||||
+3
-2
@@ -82,7 +82,7 @@ func InstrumentedHTTPClientFactory(clientFactory transport.HTTPClientFactory,
|
||||
|
||||
metricAttrs := attrs
|
||||
for _, kv := range opts.Metrics.StaticAttributes {
|
||||
if len(kv.Key) > 0 && len(kv.Value) > 0 {
|
||||
if kv.Key != "" && kv.Value != "" {
|
||||
metricAttrs = append(metricAttrs, attribute.String(kv.Key, kv.Value))
|
||||
}
|
||||
}
|
||||
@@ -93,7 +93,7 @@ func InstrumentedHTTPClientFactory(clientFactory transport.HTTPClientFactory,
|
||||
traceAttrs = append(traceAttrs,
|
||||
attribute.String("krakend.stage", "backend-request"))
|
||||
for _, kv := range opts.Traces.StaticAttributes {
|
||||
if len(kv.Key) > 0 && len(kv.Value) > 0 {
|
||||
if kv.Key != "" && kv.Value != "" {
|
||||
traceAttrs = append(traceAttrs, attribute.String(kv.Key, kv.Value))
|
||||
}
|
||||
}
|
||||
@@ -112,6 +112,7 @@ func InstrumentedHTTPClientFactory(clientFactory transport.HTTPClientFactory,
|
||||
DetailedConnection: opts.Traces.DetailedConnection,
|
||||
FixedAttributes: traceAttrs,
|
||||
ReportHeaders: opts.Traces.ReportHeaders,
|
||||
SkipHeaders: opts.Traces.SkipHeaders,
|
||||
},
|
||||
OTELInstance: otelState,
|
||||
}
|
||||
|
||||
+10
-8
@@ -49,7 +49,7 @@ func metricsAndTracesMiddleware(next proxy.Proxy, mm *middlewareMeter, mt *middl
|
||||
// and report the duration of this stage in metrics if enabled.
|
||||
func middleware(gs state.OTEL, metricsEnabled bool, tracesEnabled bool,
|
||||
stageName string, urlPattern string, metricsAttrs, tracesAttrs []attribute.KeyValue,
|
||||
reportHeaders bool,
|
||||
reportHeaders bool, skipHeaders []string,
|
||||
) proxy.Middleware {
|
||||
var mt *middlewareTracer
|
||||
var mm *middlewareMeter
|
||||
@@ -62,7 +62,7 @@ func middleware(gs state.OTEL, metricsEnabled bool, tracesEnabled bool,
|
||||
}
|
||||
}
|
||||
if tracesEnabled {
|
||||
mt = newMiddlewareTracer(gs, urlPattern, stageName, reportHeaders, tracesAttrs)
|
||||
mt = newMiddlewareTracer(gs, urlPattern, stageName, reportHeaders, skipHeaders, tracesAttrs)
|
||||
if mt == nil {
|
||||
// TODO: log the error
|
||||
tracesEnabled = false
|
||||
@@ -124,19 +124,20 @@ func ProxyFactory(pf proxy.Factory) proxy.FactoryFunc {
|
||||
metricsAttrs := attrs
|
||||
tracesAttrs := attrs
|
||||
for _, kv := range pipeOpts.MetricsStaticAttributes {
|
||||
if len(kv.Key) > 0 && len(kv.Value) > 0 {
|
||||
if kv.Key != "" && kv.Value != "" {
|
||||
metricsAttrs = append(metricsAttrs, attribute.String(kv.Key, kv.Value))
|
||||
}
|
||||
}
|
||||
|
||||
for _, kv := range pipeOpts.TracesStaticAttributes {
|
||||
if len(kv.Key) > 0 && len(kv.Value) > 0 {
|
||||
if kv.Key != "" && kv.Value != "" {
|
||||
tracesAttrs = append(tracesAttrs, attribute.String(kv.Key, kv.Value))
|
||||
}
|
||||
}
|
||||
|
||||
return middleware(gs, !pipeOpts.DisableMetrics, !pipeOpts.DisableTraces,
|
||||
"proxy", urlPattern, metricsAttrs, tracesAttrs, pipeOpts.ReportHeaders)(next), nil
|
||||
"proxy", urlPattern, metricsAttrs, tracesAttrs, pipeOpts.ReportHeaders,
|
||||
pipeOpts.SkipHeaders)(next), nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +176,7 @@ func BackendFactory(bf proxy.BackendFactory) proxy.BackendFactory {
|
||||
tracesAttrs := attrs
|
||||
if backendOpts.Metrics != nil {
|
||||
for _, kv := range backendOpts.Metrics.StaticAttributes {
|
||||
if len(kv.Key) > 0 && len(kv.Value) > 0 {
|
||||
if kv.Key != "" && kv.Value != "" {
|
||||
metricsAttrs = append(metricsAttrs, attribute.String(kv.Key, kv.Value))
|
||||
}
|
||||
}
|
||||
@@ -185,13 +186,14 @@ func BackendFactory(bf proxy.BackendFactory) proxy.BackendFactory {
|
||||
if backendOpts.Traces != nil {
|
||||
reportHeaders = backendOpts.Traces.ReportHeaders
|
||||
for _, kv := range backendOpts.Traces.StaticAttributes {
|
||||
if len(kv.Key) > 0 && len(kv.Value) > 0 {
|
||||
if kv.Key != "" && kv.Value != "" {
|
||||
tracesAttrs = append(tracesAttrs, attribute.String(kv.Key, kv.Value))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return middleware(gs, !metricsDisabled, !tracesDisabled,
|
||||
"backend", urlPattern, metricsAttrs, tracesAttrs, reportHeaders)(next)
|
||||
"backend", urlPattern, metricsAttrs, tracesAttrs, reportHeaders,
|
||||
backendOpts.Traces.SkipHeaders)(next)
|
||||
}
|
||||
}
|
||||
|
||||
+18
-3
@@ -18,10 +18,13 @@ type middlewareTracer struct {
|
||||
name string
|
||||
tracer trace.Tracer
|
||||
reportHeaders bool
|
||||
skipHeaders map[string]bool
|
||||
attrs []attribute.KeyValue
|
||||
}
|
||||
|
||||
func newMiddlewareTracer(s state.OTEL, name string, stageName string, reportHeaders bool, attrs []attribute.KeyValue) *middlewareTracer {
|
||||
func newMiddlewareTracer(s state.OTEL, name string, stageName string, reportHeaders bool,
|
||||
skipHeaders []string, attrs []attribute.KeyValue,
|
||||
) *middlewareTracer {
|
||||
tracer := s.Tracer()
|
||||
if tracer == nil {
|
||||
return nil
|
||||
@@ -29,10 +32,18 @@ func newMiddlewareTracer(s state.OTEL, name string, stageName string, reportHead
|
||||
tAttrs := make([]attribute.KeyValue, 0, len(attrs)+1)
|
||||
tAttrs = append(tAttrs, attrs...)
|
||||
tAttrs = append(tAttrs, attribute.String("krakend.stage", stageName))
|
||||
var sh map[string]bool
|
||||
if len(skipHeaders) > 0 {
|
||||
sh = make(map[string]bool, len(skipHeaders))
|
||||
for _, k := range skipHeaders {
|
||||
sh[k] = true
|
||||
}
|
||||
}
|
||||
return &middlewareTracer{
|
||||
name: name,
|
||||
tracer: tracer,
|
||||
reportHeaders: reportHeaders,
|
||||
skipHeaders: sh,
|
||||
attrs: tAttrs,
|
||||
}
|
||||
}
|
||||
@@ -42,7 +53,9 @@ func (t *middlewareTracer) start(ctx context.Context, req *proxy.Request) (conte
|
||||
span.SetAttributes(t.attrs...)
|
||||
if t.reportHeaders {
|
||||
for hk, hv := range req.Headers {
|
||||
span.SetAttributes(attribute.StringSlice("http.request.header."+strings.ToLower(hk), hv))
|
||||
if t.skipHeaders == nil || !t.skipHeaders[hk] {
|
||||
span.SetAttributes(attribute.StringSlice("http.request.header."+strings.ToLower(hk), hv))
|
||||
}
|
||||
}
|
||||
}
|
||||
return ctx, span
|
||||
@@ -60,7 +73,9 @@ func (t *middlewareTracer) end(span trace.Span, resp *proxy.Response, err error)
|
||||
span.SetAttributes(semconv.HTTPResponseStatusCodeKey.Int(resp.Metadata.StatusCode))
|
||||
if t.reportHeaders {
|
||||
for hk, hv := range resp.Metadata.Headers {
|
||||
span.SetAttributes(attribute.StringSlice("http.response.header."+strings.ToLower(hk), hv))
|
||||
if t.skipHeaders == nil || !t.skipHeaders[hk] {
|
||||
span.SetAttributes(attribute.StringSlice("http.response.header."+strings.ToLower(hk), hv))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user