Skip to content

Commit

Permalink
feat: adds support for isNoop check on spans. (openzipkin#181)
Browse files Browse the repository at this point in the history
* feat: adds support for isNoop check on spans.

Span.IsNoop is specially usefull to avoid expensive operations when the tags or logs are not being recorded e.g. if you are about to read the body and process it to obtain certain tags, the check would save that computation as no changes will take effect.

* chore: fixes license year.

* chore: changes the IsNoop change into a package level function as per @basvanbeek's suggestion

IsNoop is more of the concern of the tracer and not necessarily of the span's concern, hence turning this method into a function.
  • Loading branch information
jcchavezs committed Nov 11, 2020
1 parent b98d756 commit f113cc0
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 15 deletions.
8 changes: 5 additions & 3 deletions middleware/grpc/server.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019 The OpenZipkin Authors
// Copyright 2020 The OpenZipkin Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -83,8 +83,10 @@ func (s *serverHandler) TagRPC(ctx context.Context, rti *stats.RPCTagInfo) conte

span := s.tracer.StartSpan(name, zipkin.Kind(model.Server), zipkin.Parent(sc), zipkin.RemoteEndpoint(remoteEndpointFromContext(ctx, "")))

for k, v := range s.defaultTags {
span.Tag(k, v)
if !zipkin.IsNoop(span) {
for k, v := range s.defaultTags {
span.Tag(k, v)
}
}

return zipkin.NewContext(ctx, span)
Expand Down
5 changes: 4 additions & 1 deletion middleware/grpc/shared.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019 The OpenZipkin Authors
// Copyright 2020 The OpenZipkin Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -39,6 +39,9 @@ func spanName(rti *stats.RPCTagInfo) string {

func handleRPC(ctx context.Context, rs stats.RPCStats) {
span := zipkin.SpanFromContext(ctx)
if zipkin.IsNoop(span) {
return
}

switch rs := rs.(type) {
case *stats.End:
Expand Down
19 changes: 12 additions & 7 deletions middleware/http/server.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019 The OpenZipkin Authors
// Copyright 2020 The OpenZipkin Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -107,8 +107,6 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
}

remoteEndpoint, _ := zipkin.NewEndpoint("", r.RemoteAddr)

if len(h.name) == 0 {
spanName = r.Method
} else {
Expand All @@ -120,16 +118,23 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
spanName,
zipkin.Kind(model.Server),
zipkin.Parent(sc),
zipkin.RemoteEndpoint(remoteEndpoint),
)
// add our span to context
ctx := zipkin.NewContext(r.Context(), sp)

if zipkin.IsNoop(sp) {
// While the span is not being recorded, we still want to propagate the context.
h.next.ServeHTTP(w, r.WithContext(ctx))
return
}

remoteEndpoint, _ := zipkin.NewEndpoint("", r.RemoteAddr)
sp.SetRemoteEndpoint(remoteEndpoint)

for k, v := range h.defaultTags {
sp.Tag(k, v)
}

// add our span to context
ctx := zipkin.NewContext(r.Context(), sp)

// tag typical HTTP request items
zipkin.TagHTTPMethod.Set(sp, r.Method)
zipkin.TagHTTPPath.Set(sp, r.URL.Path)
Expand Down
8 changes: 7 additions & 1 deletion middleware/http/transport.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019 The OpenZipkin Authors
// Copyright 2020 The OpenZipkin Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -154,6 +154,12 @@ func (t *transport) RoundTrip(req *http.Request) (res *http.Response, err error)
req.Context(), req.URL.Scheme+"/"+req.Method, zipkin.Kind(model.Client), zipkin.RemoteEndpoint(t.remoteEndpoint),
)

if zipkin.IsNoop(sp) {
// While the span is not being recorded, we still want to propagate the context.
_ = b3.InjectHTTP(req)(sp.Context())
return t.rt.RoundTrip(req)
}

for k, v := range t.defaultTags {
sp.Tag(k, v)
}
Expand Down
9 changes: 8 additions & 1 deletion noop.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019 The OpenZipkin Authors
// Copyright 2020 The OpenZipkin Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -39,3 +39,10 @@ func (*noopSpan) Finish() {}
func (*noopSpan) FinishedWithDuration(duration time.Duration) {}

func (*noopSpan) Flush() {}

// IsNoop tells whether the span is noop or not. Usually used to avoid resource misusage
// when customizing a span as data won't be recorded
func IsNoop(s Span) bool {
_, ok := s.(*noopSpan)
return ok
}
2 changes: 1 addition & 1 deletion span.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019 The OpenZipkin Authors
// Copyright 2020 The OpenZipkin Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion span_implementation.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2019 The OpenZipkin Authors
// Copyright 2020 The OpenZipkin Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down

0 comments on commit f113cc0

Please sign in to comment.