aboutsummaryrefslogtreecommitdiff
path: root/vendor/go.opencensus.io/plugin/ochttp/propagation/b3/b3.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/go.opencensus.io/plugin/ochttp/propagation/b3/b3.go')
-rw-r--r--vendor/go.opencensus.io/plugin/ochttp/propagation/b3/b3.go123
1 files changed, 123 insertions, 0 deletions
diff --git a/vendor/go.opencensus.io/plugin/ochttp/propagation/b3/b3.go b/vendor/go.opencensus.io/plugin/ochttp/propagation/b3/b3.go
new file mode 100644
index 0000000..f777772
--- /dev/null
+++ b/vendor/go.opencensus.io/plugin/ochttp/propagation/b3/b3.go
@@ -0,0 +1,123 @@
+// Copyright 2018, OpenCensus 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 b3 contains a propagation.HTTPFormat implementation
+// for B3 propagation. See https://github.com/openzipkin/b3-propagation
+// for more details.
+package b3 // import "go.opencensus.io/plugin/ochttp/propagation/b3"
+
+import (
+ "encoding/hex"
+ "net/http"
+
+ "go.opencensus.io/trace"
+ "go.opencensus.io/trace/propagation"
+)
+
+// B3 headers that OpenCensus understands.
+const (
+ TraceIDHeader = "X-B3-TraceId"
+ SpanIDHeader = "X-B3-SpanId"
+ SampledHeader = "X-B3-Sampled"
+)
+
+// HTTPFormat implements propagation.HTTPFormat to propagate
+// traces in HTTP headers in B3 propagation format.
+// HTTPFormat skips the X-B3-ParentId and X-B3-Flags headers
+// because there are additional fields not represented in the
+// OpenCensus span context. Spans created from the incoming
+// header will be the direct children of the client-side span.
+// Similarly, reciever of the outgoing spans should use client-side
+// span created by OpenCensus as the parent.
+type HTTPFormat struct{}
+
+var _ propagation.HTTPFormat = (*HTTPFormat)(nil)
+
+// SpanContextFromRequest extracts a B3 span context from incoming requests.
+func (f *HTTPFormat) SpanContextFromRequest(req *http.Request) (sc trace.SpanContext, ok bool) {
+ tid, ok := ParseTraceID(req.Header.Get(TraceIDHeader))
+ if !ok {
+ return trace.SpanContext{}, false
+ }
+ sid, ok := ParseSpanID(req.Header.Get(SpanIDHeader))
+ if !ok {
+ return trace.SpanContext{}, false
+ }
+ sampled, _ := ParseSampled(req.Header.Get(SampledHeader))
+ return trace.SpanContext{
+ TraceID: tid,
+ SpanID: sid,
+ TraceOptions: sampled,
+ }, true
+}
+
+// ParseTraceID parses the value of the X-B3-TraceId header.
+func ParseTraceID(tid string) (trace.TraceID, bool) {
+ if tid == "" {
+ return trace.TraceID{}, false
+ }
+ b, err := hex.DecodeString(tid)
+ if err != nil {
+ return trace.TraceID{}, false
+ }
+ var traceID trace.TraceID
+ if len(b) <= 8 {
+ // The lower 64-bits.
+ start := 8 + (8 - len(b))
+ copy(traceID[start:], b)
+ } else {
+ start := 16 - len(b)
+ copy(traceID[start:], b)
+ }
+
+ return traceID, true
+}
+
+// ParseSpanID parses the value of the X-B3-SpanId or X-B3-ParentSpanId headers.
+func ParseSpanID(sid string) (spanID trace.SpanID, ok bool) {
+ if sid == "" {
+ return trace.SpanID{}, false
+ }
+ b, err := hex.DecodeString(sid)
+ if err != nil {
+ return trace.SpanID{}, false
+ }
+ start := 8 - len(b)
+ copy(spanID[start:], b)
+ return spanID, true
+}
+
+// ParseSampled parses the value of the X-B3-Sampled header.
+func ParseSampled(sampled string) (trace.TraceOptions, bool) {
+ switch sampled {
+ case "true", "1":
+ return trace.TraceOptions(1), true
+ default:
+ return trace.TraceOptions(0), false
+ }
+}
+
+// SpanContextToRequest modifies the given request to include B3 headers.
+func (f *HTTPFormat) SpanContextToRequest(sc trace.SpanContext, req *http.Request) {
+ req.Header.Set(TraceIDHeader, hex.EncodeToString(sc.TraceID[:]))
+ req.Header.Set(SpanIDHeader, hex.EncodeToString(sc.SpanID[:]))
+
+ var sampled string
+ if sc.IsSampled() {
+ sampled = "1"
+ } else {
+ sampled = "0"
+ }
+ req.Header.Set(SampledHeader, sampled)
+}