Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 

84 rader
2.4 KiB

  1. // Copyright 2017 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Package tracecontext provides encoders and decoders for Stackdriver Trace contexts.
  15. package tracecontext
  16. import "encoding/binary"
  17. const (
  18. versionID = 0
  19. traceIDField = 0
  20. spanIDField = 1
  21. optsField = 2
  22. traceIDLen = 16
  23. spanIDLen = 8
  24. optsLen = 1
  25. // Len represents the length of trace context.
  26. Len = 1 + 1 + traceIDLen + 1 + spanIDLen + 1 + optsLen
  27. )
  28. // Encode encodes trace ID, span ID and options into dst. The number of bytes
  29. // written will be returned. If len(dst) isn't big enough to fit the trace context,
  30. // a negative number is returned.
  31. func Encode(dst []byte, traceID []byte, spanID uint64, opts byte) (n int) {
  32. if len(dst) < Len {
  33. return -1
  34. }
  35. var offset = 0
  36. putByte := func(b byte) { dst[offset] = b; offset++ }
  37. putUint64 := func(u uint64) { binary.LittleEndian.PutUint64(dst[offset:], u); offset += 8 }
  38. putByte(versionID)
  39. putByte(traceIDField)
  40. for _, b := range traceID {
  41. putByte(b)
  42. }
  43. putByte(spanIDField)
  44. putUint64(spanID)
  45. putByte(optsField)
  46. putByte(opts)
  47. return offset
  48. }
  49. // Decode decodes the src into a trace ID, span ID and options. If src doesn't
  50. // contain a valid trace context, ok = false is returned.
  51. func Decode(src []byte) (traceID []byte, spanID uint64, opts byte, ok bool) {
  52. if len(src) < Len {
  53. return traceID, spanID, 0, false
  54. }
  55. var offset = 0
  56. readByte := func() byte { b := src[offset]; offset++; return b }
  57. readUint64 := func() uint64 { v := binary.LittleEndian.Uint64(src[offset:]); offset += 8; return v }
  58. if readByte() != versionID {
  59. return traceID, spanID, 0, false
  60. }
  61. for offset < len(src) {
  62. switch readByte() {
  63. case traceIDField:
  64. traceID = src[offset : offset+traceIDLen]
  65. offset += traceIDLen
  66. case spanIDField:
  67. spanID = readUint64()
  68. case optsField:
  69. opts = readByte()
  70. }
  71. }
  72. return traceID, spanID, opts, true
  73. }