| // Copyright 2017, 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 propagation implements the binary trace context format. |
| package propagation // import "go.opencensus.io/trace/propagation" |
| |
| // TODO: link to external spec document. |
| |
| // BinaryFormat format: |
| // |
| // Binary value: <version_id><version_format> |
| // version_id: 1 byte representing the version id. |
| // |
| // For version_id = 0: |
| // |
| // version_format: <field><field> |
| // field_format: <field_id><field_format> |
| // |
| // Fields: |
| // |
| // TraceId: (field_id = 0, len = 16, default = "0000000000000000") - 16-byte array representing the trace_id. |
| // SpanId: (field_id = 1, len = 8, default = "00000000") - 8-byte array representing the span_id. |
| // TraceOptions: (field_id = 2, len = 1, default = "0") - 1-byte array representing the trace_options. |
| // |
| // Fields MUST be encoded using the field id order (smaller to higher). |
| // |
| // Valid value example: |
| // |
| // {0, 0, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 1, 97, |
| // 98, 99, 100, 101, 102, 103, 104, 2, 1} |
| // |
| // version_id = 0; |
| // trace_id = {64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79} |
| // span_id = {97, 98, 99, 100, 101, 102, 103, 104}; |
| // trace_options = {1}; |
| |
| import ( |
| "net/http" |
| |
| "go.opencensus.io/trace" |
| ) |
| |
| // Binary returns the binary format representation of a SpanContext. |
| // |
| // If sc is the zero value, Binary returns nil. |
| func Binary(sc trace.SpanContext) []byte { |
| if sc == (trace.SpanContext{}) { |
| return nil |
| } |
| var b [29]byte |
| copy(b[2:18], sc.TraceID[:]) |
| b[18] = 1 |
| copy(b[19:27], sc.SpanID[:]) |
| b[27] = 2 |
| b[28] = uint8(sc.TraceOptions) |
| return b[:] |
| } |
| |
| // FromBinary returns the SpanContext represented by b. |
| // |
| // If b has an unsupported version ID or contains no TraceID, FromBinary |
| // returns with ok==false. |
| func FromBinary(b []byte) (sc trace.SpanContext, ok bool) { |
| if len(b) == 0 || b[0] != 0 { |
| return trace.SpanContext{}, false |
| } |
| b = b[1:] |
| if len(b) >= 17 && b[0] == 0 { |
| copy(sc.TraceID[:], b[1:17]) |
| b = b[17:] |
| } else { |
| return trace.SpanContext{}, false |
| } |
| if len(b) >= 9 && b[0] == 1 { |
| copy(sc.SpanID[:], b[1:9]) |
| b = b[9:] |
| } |
| if len(b) >= 2 && b[0] == 2 { |
| sc.TraceOptions = trace.TraceOptions(b[1]) |
| } |
| return sc, true |
| } |
| |
| // HTTPFormat implementations propagate span contexts |
| // in HTTP requests. |
| // |
| // SpanContextFromRequest extracts a span context from incoming |
| // requests. |
| // |
| // SpanContextToRequest modifies the given request to include the given |
| // span context. |
| type HTTPFormat interface { |
| SpanContextFromRequest(req *http.Request) (sc trace.SpanContext, ok bool) |
| SpanContextToRequest(sc trace.SpanContext, req *http.Request) |
| } |
| |
| // TODO(jbd): Find a more representative but short name for HTTPFormat. |