diff --git a/pkg/net/trace/context.go b/pkg/net/trace/context.go index e3d20bd94..1aab864c9 100644 --- a/pkg/net/trace/context.go +++ b/pkg/net/trace/context.go @@ -19,39 +19,39 @@ var ( // SpanContext implements opentracing.SpanContext type spanContext struct { - // traceID represents globally unique ID of the trace. + // TraceID represents globally unique ID of the trace. // Usually generated as a random number. - traceID uint64 + TraceID uint64 - // spanID represents span ID that must be unique within its trace, + // SpanID represents span ID that must be unique within its trace, // but does not have to be globally unique. - spanID uint64 + SpanID uint64 - // parentID refers to the ID of the parent span. + // ParentID refers to the ID of the parent span. // Should be 0 if the current span is a root span. - parentID uint64 + ParentID uint64 - // flags is a bitmap containing such bits as 'sampled' and 'debug'. - flags byte + // Flags is a bitmap containing such bits as 'sampled' and 'debug'. + Flags byte - // probability - probability float32 + // Probability + Probability float32 - // current level - level int + // Level current level + Level int } func (c spanContext) isSampled() bool { - return (c.flags & flagSampled) == flagSampled + return (c.Flags & flagSampled) == flagSampled } func (c spanContext) isDebug() bool { - return (c.flags & flagDebug) == flagDebug + return (c.Flags & flagDebug) == flagDebug } // IsValid check spanContext valid func (c spanContext) IsValid() bool { - return c.traceID != 0 && c.spanID != 0 + return c.TraceID != 0 && c.SpanID != 0 } // emptyContext emptyContext @@ -69,10 +69,10 @@ var emptyContext = spanContext{} // sample-rate: s-{base16(BigEndian(float32))} func (c spanContext) String() string { base := make([]string, 4) - base[0] = strconv.FormatUint(uint64(c.traceID), 16) - base[1] = strconv.FormatUint(uint64(c.spanID), 16) - base[2] = strconv.FormatUint(uint64(c.parentID), 16) - base[3] = strconv.FormatUint(uint64(c.flags), 16) + base[0] = strconv.FormatUint(uint64(c.TraceID), 16) + base[1] = strconv.FormatUint(uint64(c.SpanID), 16) + base[2] = strconv.FormatUint(uint64(c.ParentID), 16) + base[3] = strconv.FormatUint(uint64(c.Flags), 16) return strings.Join(base, ":") } @@ -101,10 +101,10 @@ func contextFromString(value string) (spanContext, error) { return emptyContext, errInvalidTracerString } sctx := spanContext{ - traceID: rets[0], - spanID: rets[1], - parentID: rets[2], - flags: byte(rets[3]), + TraceID: rets[0], + SpanID: rets[1], + ParentID: rets[2], + Flags: byte(rets[3]), } return sctx, nil } diff --git a/pkg/net/trace/dapper.go b/pkg/net/trace/dapper.go index 03048da19..88934b103 100644 --- a/pkg/net/trace/dapper.go +++ b/pkg/net/trace/dapper.go @@ -60,13 +60,13 @@ func (d *dapper) New(operationName string, opts ...Option) Trace { } else { sampled, probability = d.sampler.IsSampled(traceID, operationName) } - pctx := spanContext{traceID: traceID} + pctx := spanContext{TraceID: traceID} if sampled { - pctx.flags = flagSampled - pctx.probability = probability + pctx.Flags = flagSampled + pctx.Probability = probability } if opt.Debug { - pctx.flags |= flagDebug + pctx.Flags |= flagDebug return d.newSpanWithContext(operationName, pctx).SetTag(TagString(TagSpanKind, "server")).SetTag(TagBool("debug", true)) } // 为了兼容临时为 New 的 Span 设置 span.kind @@ -80,21 +80,21 @@ func (d *dapper) newSpanWithContext(operationName string, pctx spanContext) Trac // sp.context = pctx // return sp //} - if pctx.level > _maxLevel { + if pctx.Level > _maxLevel { // if span reach max limit level return noopspan return noopspan{} } - level := pctx.level + 1 + level := pctx.Level + 1 nctx := spanContext{ - traceID: pctx.traceID, - parentID: pctx.spanID, - flags: pctx.flags, - level: level, + TraceID: pctx.TraceID, + ParentID: pctx.SpanID, + Flags: pctx.Flags, + Level: level, } - if pctx.spanID == 0 { - nctx.spanID = pctx.traceID + if pctx.SpanID == 0 { + nctx.SpanID = pctx.TraceID } else { - nctx.spanID = genID() + nctx.SpanID = genID() } sp.operationName = operationName sp.context = nctx diff --git a/pkg/net/trace/marshal.go b/pkg/net/trace/marshal.go index 2d3f58226..5553bdf84 100644 --- a/pkg/net/trace/marshal.go +++ b/pkg/net/trace/marshal.go @@ -32,10 +32,10 @@ func marshalSpanV1(sp *Span) ([]byte, error) { protoSpan.Version = protoVersion1 protoSpan.ServiceName = sp.dapper.serviceName protoSpan.OperationName = sp.operationName - protoSpan.TraceId = sp.context.traceID - protoSpan.SpanId = sp.context.spanID - protoSpan.ParentId = sp.context.parentID - protoSpan.SamplingProbability = sp.context.probability + protoSpan.TraceId = sp.context.TraceID + protoSpan.SpanId = sp.context.SpanID + protoSpan.ParentId = sp.context.ParentID + protoSpan.SamplingProbability = sp.context.Probability protoSpan.StartTime = ×tamp.Timestamp{ Seconds: sp.startTime.Unix(), Nanos: int32(sp.startTime.Nanosecond()), diff --git a/pkg/net/trace/span.go b/pkg/net/trace/span.go index f943f84a7..635785f69 100644 --- a/pkg/net/trace/span.go +++ b/pkg/net/trace/span.go @@ -43,22 +43,18 @@ func (s *Span) TraceID() string { return s.context.String() } -func (s *Span) Tid() uint64 { - return s.context.traceID -} - -func (s *Span) SpanID() uint64 { - return s.context.spanID -} - -func (s *Span) ParentID() uint64 { - return s.context.parentID +func (s *Span) Context() spanContext { + return s.context } func (s *Span) Tags() []Tag { return s.tags } +func (s *Span) Logs() []*protogen.Log { + return s.logs +} + func (s *Span) Fork(serviceName, operationName string) Trace { if s.childs > _maxChilds { // if child span more than max childs set return noopspan diff --git a/pkg/net/trace/zipkin/zipkin.go b/pkg/net/trace/zipkin/zipkin.go index 8cd1532b0..a8be5d2e9 100644 --- a/pkg/net/trace/zipkin/zipkin.go +++ b/pkg/net/trace/zipkin/zipkin.go @@ -25,9 +25,10 @@ func newReport(c *Config) *report { // WriteSpan write a trace span to queue. func (r *report) WriteSpan(raw *trace.Span) (err error) { - traceID := model.TraceID{Low: raw.Tid()} - spanID := model.ID(raw.SpanID()) - parentID := model.ID(raw.ParentID()) + ctx := raw.Context() + traceID := model.TraceID{Low: ctx.TraceID} + spanID := model.ID(ctx.SpanID) + parentID := model.ID(ctx.ParentID) span := model.SpanModel{ SpanContext: model.SpanContext{ TraceID: traceID, @@ -42,7 +43,16 @@ func (r *report) WriteSpan(raw *trace.Span) (err error) { for _, tag := range raw.Tags() { switch tag.Key { case trace.TagSpanKind: - span.Kind = model.Kind(tag.Value.(string)) + switch tag.Value.(string) { + case "client": + span.Kind = model.Client + case "server": + span.Kind = model.Server + case "producer": + span.Kind = model.Producer + case "consumer": + span.Kind = model.Consumer + } case trace.TagPeerService: span.LocalEndpoint = &model.Endpoint{ServiceName: tag.Value.(string)} default: @@ -54,6 +64,9 @@ func (r *report) WriteSpan(raw *trace.Span) (err error) { } } } + for _, lg := range raw.Logs() { + span.Tags[lg.Key] = string(lg.Value) + } r.rpt.Send(span) return } diff --git a/pkg/net/trace/zipkin/zipkin_test.go b/pkg/net/trace/zipkin/zipkin_test.go index 34435b5d5..94d0ea566 100644 --- a/pkg/net/trace/zipkin/zipkin_test.go +++ b/pkg/net/trace/zipkin/zipkin_test.go @@ -1,7 +1,9 @@ package zipkin import ( + "io/ioutil" "net/http" + "net/http/httptest" "testing" "time" @@ -10,18 +12,35 @@ import ( ) func TestZipkin(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + t.Errorf("expected 'POST' request, got '%s'", r.Method) + } + + aSpanPayload, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Errorf("unexpected error: %s", err.Error()) + } + + t.Logf("%s\n", aSpanPayload) + })) + defer ts.Close() + c := &Config{ - Endpoint: "http://127.0.0.1:9411/api/v2/spans", + Endpoint: ts.URL, Timeout: xtime.Duration(time.Second * 5), BatchSize: 100, } + //c.Endpoint = "http://127.0.0.1:9411/api/v2/spans" report := newReport(c) t1 := trace.NewTracer("service1", report, true) t2 := trace.NewTracer("service2", report, true) - sp1 := t1.New("opt_1") - sp2 := sp1.Fork("", "opt_client") + sp1 := t1.New("option_1") + sp2 := sp1.Fork("service3", "opt_client") + // inject header := make(http.Header) t1.Inject(sp2, trace.HTTPFormat, header) + t.Log(header) sp3, err := t2.Extract(trace.HTTPFormat, header) if err != nil { t.Fatal(err)