You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kratos/pkg/net/trace/context.go

111 lines
2.5 KiB

6 years ago
package trace
import (
"strconv"
"strings"
"github.com/pkg/errors"
)
const (
flagSampled = 0x01
flagDebug = 0x02
)
var (
errEmptyTracerString = errors.New("trace: cannot convert empty string to spancontext")
errInvalidTracerString = errors.New("trace: string does not match spancontext string format")
)
// SpanContext implements opentracing.SpanContext
type spanContext struct {
5 years ago
// TraceID represents globally unique ID of the trace.
6 years ago
// Usually generated as a random number.
5 years ago
TraceID uint64
6 years ago
5 years ago
// SpanID represents span ID that must be unique within its trace,
6 years ago
// but does not have to be globally unique.
5 years ago
SpanID uint64
6 years ago
5 years ago
// ParentID refers to the ID of the parent span.
6 years ago
// Should be 0 if the current span is a root span.
5 years ago
ParentID uint64
6 years ago
5 years ago
// Flags is a bitmap containing such bits as 'sampled' and 'debug'.
Flags byte
6 years ago
5 years ago
// Probability
Probability float32
6 years ago
5 years ago
// Level current level
Level int
6 years ago
}
func (c spanContext) isSampled() bool {
5 years ago
return (c.Flags & flagSampled) == flagSampled
6 years ago
}
func (c spanContext) isDebug() bool {
5 years ago
return (c.Flags & flagDebug) == flagDebug
6 years ago
}
// IsValid check spanContext valid
func (c spanContext) IsValid() bool {
5 years ago
return c.TraceID != 0 && c.SpanID != 0
6 years ago
}
// emptyContext emptyContext
var emptyContext = spanContext{}
// String convert spanContext to String
// {TraceID}:{SpanID}:{ParentID}:{flags}:[extend...]
// TraceID: uint64 base16
// SpanID: uint64 base16
// ParentID: uint64 base16
// flags:
// - :0 sampled flag
// - :1 debug flag
// extend:
// sample-rate: s-{base16(BigEndian(float32))}
func (c spanContext) String() string {
base := make([]string, 4)
base[0] = strconv.FormatUint(c.TraceID, 16)
base[1] = strconv.FormatUint(c.SpanID, 16)
base[2] = strconv.FormatUint(c.ParentID, 16)
5 years ago
base[3] = strconv.FormatUint(uint64(c.Flags), 16)
6 years ago
return strings.Join(base, ":")
}
// ContextFromString parse spanContext form string
func contextFromString(value string) (spanContext, error) {
if value == "" {
return emptyContext, errEmptyTracerString
}
items := strings.Split(value, ":")
if len(items) < 4 {
return emptyContext, errInvalidTracerString
}
parseHexUint64 := func(hexs []string) ([]uint64, error) {
rets := make([]uint64, len(hexs))
var err error
for i, hex := range hexs {
rets[i], err = strconv.ParseUint(hex, 16, 64)
if err != nil {
break
}
}
return rets, err
}
rets, err := parseHexUint64(items[0:4])
if err != nil {
return emptyContext, errInvalidTracerString
}
sctx := spanContext{
5 years ago
TraceID: rets[0],
SpanID: rets[1],
ParentID: rets[2],
Flags: byte(rets[3]),
6 years ago
}
return sctx, nil
}