-
Notifications
You must be signed in to change notification settings - Fork 600
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
E2E Tracing test - Strong trace assertions #1972
Changes from all commits
b26ff18
6a0ac61
22583fe
2281fc1
6282d5b
dcfbf61
e21bc0a
878b477
471aa2d
79fc201
dd4a885
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,16 @@ | ||||
diff --git a/vendor/go.opencensus.io/trace/trace.go b/vendor/go.opencensus.io/trace/trace.go | ||||
index 38ead7bf..9e6fe483 100644 | ||||
--- a/vendor/go.opencensus.io/trace/trace.go | ||||
+++ b/vendor/go.opencensus.io/trace/trace.go | ||||
@@ -261,6 +261,11 @@ func startSpanInternal(name string, hasParent bool, parent SpanContext, remotePa | ||||
return span | ||||
} | ||||
|
||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove trailing whitespace:
Suggested change
|
||||
+func (s *Span) SetSpanID(spanID SpanID) { | ||||
+ s.data.SpanID = spanID | ||||
+ s.spanContext.SpanID = spanID | ||||
+} | ||||
+ | ||||
// End ends the span. | ||||
func (s *Span) End() { | ||||
if s == nil { |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,3 +33,9 @@ rm -rf $(find vendor/ -name 'BUILD.bazel') | |
update_licenses third_party/VENDOR-LICENSE \ | ||
$(find . -name "*.go" | grep -v vendor | xargs grep "package main" | cut -d: -f1 | xargs -n1 dirname | uniq) | ||
|
||
# HACK HACK HACK | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. :-) |
||
# The only way we found to create a consistent Trace tree without any missing Spans is to | ||
# artificially set the SpanId. See pkg/tracing/traceparent.go for more details. | ||
# Produced with: | ||
# git diff origin/master HEAD -- vendor/go.opencensus.io/trace/trace.go > ./hack/set-span-id.patch | ||
git apply ${REPO_ROOT_DIR}/hack/set-span-id.patch |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,19 +3,15 @@ package ingress | |
import ( | ||
"context" | ||
"errors" | ||
"fmt" | ||
"net/http" | ||
"net/url" | ||
"reflect" | ||
"strconv" | ||
"strings" | ||
"time" | ||
|
||
cloudevents "github.com/cloudevents/sdk-go" | ||
"go.opencensus.io/plugin/ochttp/propagation/b3" | ||
"go.opencensus.io/trace" | ||
"go.uber.org/zap" | ||
"knative.dev/eventing/pkg/broker" | ||
"knative.dev/eventing/pkg/tracing" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pkgtracing ? (to be consistent) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nevermind :-) I see eventing (I feel There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. /resolved |
||
"knative.dev/eventing/pkg/utils" | ||
) | ||
|
||
|
@@ -77,7 +73,7 @@ func (h *Handler) serveHTTP(ctx context.Context, event cloudevents.Event, resp * | |
return nil | ||
} | ||
|
||
tctx = addOutGoingTracing(ctx, event, tctx) | ||
tracing.AddTraceparentAttributeFromContext(ctx, event) | ||
|
||
reporterArgs := &ReportArgs{ | ||
ns: h.Namespace, | ||
|
@@ -133,20 +129,3 @@ func (h *Handler) getTTLToSet(event *cloudevents.Event) int { | |
} | ||
return int(ttl) - 1 | ||
} | ||
|
||
func addOutGoingTracing(ctx context.Context, event cloudevents.Event, tctx cloudevents.HTTPTransportContext) cloudevents.HTTPTransportContext { | ||
// Inject trace into HTTP header. | ||
spanContext := trace.FromContext(ctx).SpanContext() | ||
tctx.Header.Set(b3.TraceIDHeader, spanContext.TraceID.String()) | ||
tctx.Header.Set(b3.SpanIDHeader, spanContext.SpanID.String()) | ||
sampled := 0 | ||
if spanContext.IsSampled() { | ||
sampled = 1 | ||
} | ||
tctx.Header.Set(b3.SampledHeader, strconv.Itoa(sampled)) | ||
|
||
// Set traceparent, a CloudEvent documented extension attribute for distributed tracing. | ||
traceParent := strings.Join([]string{"00", spanContext.TraceID.String(), spanContext.SpanID.String(), fmt.Sprintf("%02x", spanContext.TraceOptions)}, "-") | ||
event.SetExtension(broker.TraceParent, traceParent) | ||
return tctx | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/* | ||
Copyright 2019 The Knative Authors | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package tracing | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"regexp" | ||
"strconv" | ||
|
||
cloudevents "github.com/cloudevents/sdk-go" | ||
"go.opencensus.io/plugin/ochttp/propagation/b3" | ||
"go.opencensus.io/trace" | ||
) | ||
|
||
const ( | ||
// traceparentAttribute is the name of the CloudEvents attribute that contains the trace state. | ||
// See | ||
// https://github.com/cloudevents/spec/blob/v1.0-rc1/extensions/distributed-tracing.md#traceparent | ||
traceparentAttribute = "traceparent" | ||
) | ||
|
||
// AddTraceparentAttributeFromContext returns a CloudEvent that is identical to the input event, | ||
// with the traceparent CloudEvents extension attribute added. The value for that attribute is the | ||
// Span stored in the context. | ||
// | ||
// The context is expected to have passed through the OpenCensus HTTP Handler, so that the Span has | ||
// been added to it. | ||
func AddTraceparentAttributeFromContext(ctx context.Context, event cloudevents.Event) cloudevents.Event { | ||
span := trace.FromContext(ctx) | ||
if span != nil { | ||
event.SetExtension(traceparentAttribute, traceparentAttributeValue(span)) | ||
} | ||
return event | ||
} | ||
|
||
func traceparentAttributeValue(span *trace.Span) string { | ||
flags := "00" | ||
if span.SpanContext().IsSampled() { | ||
flags = "01" | ||
} | ||
return fmt.Sprintf("00-%s-%s-%s", | ||
span.SpanContext().TraceID.String(), | ||
span.SpanContext().SpanID.String(), | ||
flags) | ||
} | ||
|
||
// AddSpanFromTraceparentAttribute extracts the traceparent extension attribute from the CloudEvent | ||
// and returns a context with that span set. If the traceparent extension attribute is not found or | ||
// cannot be parsed, then an error is returned. | ||
func AddSpanFromTraceparentAttribute(ctx context.Context, name string, event cloudevents.Event) (context.Context, error) { | ||
tp, ok := event.Extensions()[traceparentAttribute] | ||
if !ok { | ||
return ctx, fmt.Errorf("extension attributes did not contain %q", traceparentAttribute) | ||
} | ||
tps, ok := tp.(string) | ||
if !ok { | ||
return ctx, fmt.Errorf("extention attribute %q's value was not a string: %T", traceparentAttribute, tps) | ||
} | ||
sc, err := parseTraceparent(tps) | ||
if err != nil { | ||
return ctx, err | ||
} | ||
// Create a fake Span with the saved information. In order to ensure any requests made with this | ||
// context have a parent of the saved Span, set the SpanID to the one saved in the traceparent. | ||
// Normally, a new SpanID is generated and because this Span is never reported would create a | ||
// hole in the Span tree. | ||
_, span := trace.StartSpanWithRemoteParent(ctx, name, sc) | ||
span.SetSpanID(sc.SpanID) | ||
return trace.NewContext(ctx, span), nil | ||
} | ||
|
||
func parseTraceparent(tp string) (trace.SpanContext, error) { | ||
re := regexp.MustCompile("^00-([a-f0-9]{32})-([a-f0-9]{16})-([a-f0-9]{2})$") | ||
m := re.FindStringSubmatch(tp) | ||
if len(m) == 0 { | ||
return trace.SpanContext{}, fmt.Errorf("could not parse traceparent: %q", tp) | ||
} | ||
traceID, ok := b3.ParseTraceID(m[1]) | ||
if !ok { | ||
return trace.SpanContext{}, fmt.Errorf("could not parse traceID: %q", tp) | ||
} | ||
spanID, ok := b3.ParseSpanID(m[2]) | ||
if !ok { | ||
return trace.SpanContext{}, fmt.Errorf("could not parse spanID: %q", tp) | ||
} | ||
options, err := strconv.ParseUint(m[3], 16, 32) | ||
if err != nil { | ||
return trace.SpanContext{}, fmt.Errorf("could not parse options: %q", tp) | ||
} | ||
return trace.SpanContext{ | ||
TraceID: traceID, | ||
SpanID: spanID, | ||
TraceOptions: trace.TraceOptions(options), | ||
}, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is that until some update?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope. I just couldn't find a better way to do it. There probably is one, but I wasn't able to find it.
In theory, we will move to some OpenTelemetry libraries when they go 1.0, at which point I hope we don't need a similar hack :)