Skip to content
This repository has been archived by the owner on Nov 7, 2022. It is now read-only.

Add support to Zipkin V1 #271

Merged

Conversation

pjanotti
Copy link

Fixes #250

Add a trace translator from Zipkin V1 to OC proto.
Per ealier dicussion we just need to support JSON,
this gets OC service working with current Envoy tracing
for Zipkin.

@pjanotti pjanotti self-assigned this Dec 15, 2018
@songy23
Copy link
Contributor

songy23 commented Dec 15, 2018

This PR is too large - maybe create a separate PR to check in the test data first?

@pjanotti
Copy link
Author

pjanotti commented Dec 15, 2018

@songy23 The test data came straight from Envoy but there was a bit of redundant stuff in terms of code coverage. Removed redundant parts keeping the core annotations to document the type of annotation that we expect to get. That is about 550 less lines of code on the tests. Unfortunately, expressing the OC proto in go is a bit verbose, we have other tests like that but perhaps it is a good idea to find a less verbose way to express them.

There seems to be something wrong with the go dependencies on Travis but at first glance I don't think it was introduced by my change.

@pjanotti pjanotti mentioned this pull request Dec 15, 2018
Copy link
Member

@odeke-em odeke-em left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for working on this @pjanotti, this looks cool! I've added some suggestions, PTAL!

return nil
}

// Unknow service name works both as a default value and a flag to indicate that a valid endpoint was found.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/Unknow /Unknown /g

res := &annotationParseResult{}
timeEvents := make([]*tracepb.Span_TimeEvent, 0, len(annotations))
for _, currAnnotation := range annotations {
if currAnnotation == nil && currAnnotation.Value != "" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This condition can't ever hold and will always panic if currAnnotation == nil. Did you mean

if currAnnotation == nil || curAnnotation.Value == "" {
   continue
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch!

}
}

func sortTrace(trace []*agenttracepb.ExportTraceServiceRequest) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update this name to sortTracesByName

@@ -110,13 +112,30 @@ func (zr *ZipkinReceiver) StartTraceReception(ctx context.Context, spanSink rece
return err
}

func (zr *ZipkinReceiver) parseAndConvertToTraceSpans(blob []byte, hdr http.Header) (reqs []*agenttracepb.ExportTraceServiceRequest, err error) {
func (zr *ZipkinReceiver) parseAndConvertToTraceSpans(blob []byte, r *http.Request) (reqs []*agenttracepb.ExportTraceServiceRequest, err error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I realize that this arguments change was made to keep the tests simple and easily reuse the code, but unfortunately I think that now we don't spell out that we handle both Zipkin v1 and v2. To make that clear, I think we can keep the contents of this function as it was before but rename it to v2ToTraceSpans and then make one v1ToTraceSpans while keeping the multiplexing logic at the ServeHTTP level.

so

// v1ToTraceSpans parses Zipkin v1 JSON traces and converts them to OpenCensus Proto spans.
func (zr *ZipkinReceiver) v1ToTraceSpans(blob []byte, hdr http.Header) (reqs []*agenttracepb.ExportTraceServiceRequest, err error) {
       return tracetranslator.Zipkinv1JSONBatchToOCProto(blob)
}
// v2ToTraceSpans parses Zipkin v2 JSON or Protobuf traces and converts them to OpenCensus Proto spans.
func (zr *ZipkinReceiver) v2ToTraceSpans(blob []byte, hdr http.Header) (reqs []*agenttracepb.ExportTraceServiceRequest, err error) {
       ...
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it will be better with two separate functions.

@@ -237,7 +256,7 @@ func (zr *ZipkinReceiver) ServeHTTP(w http.ResponseWriter, r *http.Request) {
_ = c.Close()
}
_ = r.Body.Close()
ereqs, err := zr.parseAndConvertToTraceSpans(slurp, r.Header)
ereqs, err := zr.parseAndConvertToTraceSpans(slurp, r)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking for r != nil is impossible because we already just dereferenced r, please keep this signature.

and then in here is where we'll do the multiplexing.

_ = r.Body.Close

// Now deserialize and process the spans.
const asZipkinv1 = r.URL != nil && strings.HasPrefix(r.URL.Path, "/api/v1/spans")

var ereqs []*agenttracepb.ExportTraceServiceRequest
var err error

if asZipkinv1 {
     ereqs, err = zr.v1ToTraceSpans(slurp, r.Header)
} else {
     ereqs, err = zr.v2ToTraceSpans(slurp, r.Header)
}

@@ -102,9 +102,10 @@ func TestConvertSpansToTraceSpans_protobuf(t *testing.T) {
zi := new(ZipkinReceiver)
hdr := make(http.Header)
hdr.Set("Content-Type", "application/x-protobuf")
r := &http.Request{Header: hdr}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we keep the multiplexing in ServeHTTP while cleanly separating the methods for v1 and v2, then we don't have to manually create this Request or make this line change and make a specific unit test for v1.

If we want to ensure that they properly multiplex, we can just use ServeHTTP in tests like this

req := http.NewRequest("POST", "http://opencensus.io/", blob)
req.Header.Set("Content-Type", CONTENT_TYPE)
rec := httptest.Recorder()
zi.ServeHTTP(rec, req)
res := rec.Result()
zBlob, _ := ioutil.ReadAll(res.Body)
zreqs, err := json.Unmarshal(zBlob, &recv)

Paulo Janotti added 3 commits December 17, 2018 14:08
Before removing dead code

Clean-up and multiple batches test

Add Node attributes and some cleanup

Remove unused file
The test data came straight from Envoy but there was a bit of
redundant stuff in terms of code coverage. Removed most of it
keeping the core annotations to document the type of annotation
that we expect to get.
@pjanotti pjanotti force-pushed the zipkin-v1-support-rebase branch from ce699c3 to 54df561 Compare December 17, 2018 22:09
@pjanotti
Copy link
Author

Thanks for the review @odeke-em, code looks better now 👍

@pjanotti pjanotti merged commit bb3054c into census-instrumentation:master Dec 17, 2018
@pjanotti pjanotti deleted the zipkin-v1-support-rebase branch December 17, 2018 22:17
fivesheep pushed a commit to fivesheep/opencensus-service that referenced this pull request Jun 12, 2019
* Add support to Zipkin V1

* Reducing test data without affecting coverage.

* PR Feedback
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants