Skip to content
This repository was archived by the owner on Jul 31, 2023. It is now read-only.

Commit 76a1a1a

Browse files
author
JBD
authored
Simplify the trace package (#287)
- NewSpan now can create children; (*Span).StartSpan is removed. - s/StartSpanOptions/StartOptions to reduce verbosity. - Only connivance functions works against the context object, Span type provides the full API. - Introspection functions are prefixed with Report* that make them distinguishable.
1 parent d1470af commit 76a1a1a

File tree

16 files changed

+223
-363
lines changed

16 files changed

+223
-363
lines changed

examples/trace/helloworld/main.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,16 @@ func main() {
3232

3333
trace.SetDefaultSampler(trace.AlwaysSample())
3434

35-
span := trace.NewSpan("/foo", trace.StartSpanOptions{})
36-
37-
ctx = trace.WithSpan(ctx, span)
35+
ctx, span := trace.StartSpan(ctx, "/foo")
3836
bar(ctx)
39-
4037
span.End()
4138

4239
time.Sleep(1 * time.Second) // Wait enough for the exporter to report.
4340
}
4441

4542
func bar(ctx context.Context) {
46-
ctx = trace.StartSpan(ctx, "/bar")
47-
defer trace.EndSpan(ctx)
43+
ctx, span := trace.StartSpan(ctx, "/bar")
44+
defer span.End()
4845

4946
// Do bar...
5047
}

examples/trace/jaeger/main.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,16 @@ func main() {
4141
// For demoing purposes, always sample.
4242
trace.SetDefaultSampler(trace.AlwaysSample())
4343

44-
ctx = trace.StartSpan(ctx, "/foo")
44+
ctx, span := trace.StartSpan(ctx, "/foo")
4545
bar(ctx)
46-
trace.EndSpan(ctx)
46+
span.End()
4747

4848
exporter.Flush()
4949
}
5050

5151
func bar(ctx context.Context) {
52-
ctx = trace.StartSpan(ctx, "/bar")
53-
defer trace.EndSpan(ctx)
52+
ctx, span := trace.StartSpan(ctx, "/bar")
53+
defer span.End()
5454

5555
// Do bar...
5656
}

exporter/stackdriver/trace_proto_test.go

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -61,50 +61,50 @@ func TestExportTrace(t *testing.T) {
6161
trace.RegisterExporter(&te)
6262
defer trace.UnregisterExporter(&te)
6363

64-
ctx := trace.StartSpanWithRemoteParent(context.Background(), "span0",
64+
ctx, span0 := trace.StartSpanWithRemoteParent(context.Background(), "span0",
6565
trace.SpanContext{
6666
TraceID: traceID,
6767
SpanID: spanID,
6868
TraceOptions: 1,
6969
},
70-
trace.StartSpanOptions{})
70+
trace.StartOptions{})
7171
{
72-
ctx1 := trace.StartSpan(ctx, "span1")
72+
ctx1, span1 := trace.StartSpan(ctx, "span1")
7373
{
74-
ctx2 := trace.StartSpan(ctx1, "span2")
75-
trace.AddMessageSendEvent(ctx2, 0x123, 1024, 512)
76-
trace.Annotatef(ctx2, nil, "in span%d", 2)
77-
trace.Annotate(ctx2, nil, big.NewRat(2, 4).String())
78-
trace.SetSpanAttributes(ctx2,
74+
_, span2 := trace.StartSpan(ctx1, "span2")
75+
span2.AddMessageSendEvent(0x123, 1024, 512)
76+
span2.Annotatef(nil, "in span%d", 2)
77+
span2.Annotate(nil, big.NewRat(2, 4).String())
78+
span2.SetAttributes(
7979
trace.StringAttribute{Key: "key1", Value: "value1"},
8080
trace.StringAttribute{Key: "key2", Value: "value2"})
81-
trace.SetSpanAttributes(ctx2, trace.Int64Attribute{Key: "key1", Value: 100})
82-
trace.EndSpan(ctx2)
81+
span2.SetAttributes(trace.Int64Attribute{Key: "key1", Value: 100})
82+
span2.End()
8383
}
8484
{
85-
ctx3 := trace.StartSpan(ctx1, "span3")
86-
trace.Annotate(ctx3, nil, "in span3")
87-
trace.AddMessageReceiveEvent(ctx3, 0x456, 2048, 1536)
88-
trace.SetSpanStatus(ctx3, trace.Status{Code: int32(codepb.Code_UNAVAILABLE)})
89-
trace.EndSpan(ctx3)
85+
ctx3, span3 := trace.StartSpan(ctx1, "span3")
86+
span3.Annotate(nil, "in span3")
87+
span3.AddMessageReceiveEvent(0x456, 2048, 1536)
88+
span3.SetStatus(trace.Status{Code: int32(codepb.Code_UNAVAILABLE)})
89+
span3.End()
9090
{
91-
ctx4 := trace.StartSpan(ctx3, "span4")
91+
_, span4 := trace.StartSpan(ctx3, "span4")
9292
x := 42
9393
a1 := []trace.Attribute{trace.StringAttribute{Key: "k1", Value: "v1"}}
9494
a2 := []trace.Attribute{trace.StringAttribute{Key: "k2", Value: "v2"}}
9595
a3 := []trace.Attribute{trace.StringAttribute{Key: "k3", Value: "v3"}}
9696
a4 := map[string]interface{}{"k4": "v4"}
9797
r := big.NewRat(2, 4)
98-
trace.Annotate(ctx4, a1, r.String())
99-
trace.Annotatef(ctx4, a2, "foo %d", x)
100-
trace.Annotate(ctx4, a3, "in span4")
101-
trace.AddLink(ctx4, trace.Link{TraceID: trace.TraceID{1, 2}, SpanID: trace.SpanID{3}, Type: trace.LinkTypeParent, Attributes: a4})
102-
trace.EndSpan(ctx4)
98+
span4.Annotate(a1, r.String())
99+
span4.Annotatef(a2, "foo %d", x)
100+
span4.Annotate(a3, "in span4")
101+
span4.AddLink(trace.Link{TraceID: trace.TraceID{1, 2}, SpanID: trace.SpanID{3}, Type: trace.LinkTypeParent, Attributes: a4})
102+
span4.End()
103103
}
104104
}
105-
trace.EndSpan(ctx1)
105+
span1.End()
106106
}
107-
trace.EndSpan(ctx)
107+
span0.End()
108108
if len(te.spans) != 5 {
109109
t.Errorf("got %d exported spans, want 5", len(te.spans))
110110
}

exporter/stackdriver/trace_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ func TestBundling(t *testing.T) {
3737

3838
trace.SetDefaultSampler(trace.AlwaysSample())
3939
for i := 0; i < 35; i++ {
40-
ctx := trace.StartSpan(context.Background(), "span")
41-
trace.EndSpan(ctx)
40+
_, span := trace.StartSpan(context.Background(), "span")
41+
span.End()
4242
}
4343

4444
// Read the first three bundles.

internal/readme/trace.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func traceExamples() {
2424
ctx := context.Background()
2525

2626
// START startend
27-
ctx = trace.StartSpan(ctx, "your choice of name")
28-
defer trace.EndSpan(ctx)
27+
ctx, span := trace.StartSpan(ctx, "your choice of name")
28+
defer span.End()
2929
// END startend
3030
}

plugin/grpc/grpc_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func TestNewClientStatsHandler(t *testing.T) {
3737
t.Fatal(err)
3838
}
3939

40-
span := trace.NewSpan("/foo", trace.StartSpanOptions{
40+
span := trace.NewSpan("/foo", nil, trace.StartOptions{
4141
Sampler: trace.AlwaysSample(),
4242
})
4343
ctx = trace.WithSpan(ctx, span)
@@ -84,7 +84,7 @@ func TestNewServerStatsHandler(t *testing.T) {
8484
t.Fatal(err)
8585
}
8686

87-
span := trace.NewSpan("/foo", trace.StartSpanOptions{
87+
span := trace.NewSpan("/foo", nil, trace.StartOptions{
8888
Sampler: trace.AlwaysSample(),
8989
})
9090
ctx = trace.WithSpan(ctx, span)

plugin/grpc/grpctrace/grpc.go

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ const traceContextKey = "grpc-trace-bin"
6767
// SpanContext added to the outgoing gRPC metadata.
6868
func (c *ClientStatsHandler) TagRPC(ctx context.Context, rti *stats.RPCTagInfo) context.Context {
6969
name := "Sent" + strings.Replace(rti.FullMethodName, "/", ".", -1)
70-
ctx = trace.StartSpanWithOptions(ctx, name, trace.StartSpanOptions{RecordEvents: true, RegisterNameForLocalSpanStore: true})
70+
ctx, _ = trace.StartSpanWithOptions(ctx, name, trace.StartOptions{RecordEvents: true, RegisterNameForLocalSpanStore: true})
7171
traceContextBinary := propagation.Binary(trace.FromContext(ctx).SpanContext())
7272
if len(traceContextBinary) == 0 {
7373
return ctx
@@ -88,13 +88,15 @@ func (c *ClientStatsHandler) TagRPC(ctx context.Context, rti *stats.RPCTagInfo)
8888
func (s *ServerStatsHandler) TagRPC(ctx context.Context, rti *stats.RPCTagInfo) context.Context {
8989
md, _ := metadata.FromIncomingContext(ctx)
9090
name := "Recv" + strings.Replace(rti.FullMethodName, "/", ".", -1)
91-
opt := trace.StartSpanOptions{RecordEvents: true, RegisterNameForLocalSpanStore: true}
91+
opt := trace.StartOptions{RecordEvents: true, RegisterNameForLocalSpanStore: true}
9292
if s := md[traceContextKey]; len(s) > 0 {
9393
if parent, ok := propagation.FromBinary([]byte(s[0])); ok {
94-
return trace.StartSpanWithRemoteParent(ctx, name, parent, opt)
94+
ctx, _ = trace.StartSpanWithRemoteParent(ctx, name, parent, opt)
95+
return ctx
9596
}
9697
}
97-
return trace.StartSpanWithOptions(ctx, name, opt)
98+
ctx, _ = trace.StartSpanWithOptions(ctx, name, opt)
99+
return ctx
98100
}
99101

100102
// HandleRPC processes the RPC stats, adding information to the current trace span.
@@ -108,30 +110,31 @@ func (s *ServerStatsHandler) HandleRPC(ctx context.Context, rs stats.RPCStats) {
108110
}
109111

110112
func handleRPC(ctx context.Context, rs stats.RPCStats) {
113+
span := trace.FromContext(ctx)
111114
// TODO: compressed and uncompressed sizes are not populated in every message.
112115
switch rs := rs.(type) {
113116
case *stats.Begin:
114-
trace.SetSpanAttributes(ctx,
117+
span.SetAttributes(
115118
trace.BoolAttribute{Key: "Client", Value: rs.Client},
116119
trace.BoolAttribute{Key: "FailFast", Value: rs.FailFast})
117120
case *stats.InPayload:
118-
trace.AddMessageReceiveEvent(ctx, 0 /* TODO: messageID */, int64(rs.Length), int64(rs.WireLength))
121+
span.AddMessageReceiveEvent(0 /* TODO: messageID */, int64(rs.Length), int64(rs.WireLength))
119122
case *stats.InHeader:
120-
trace.AddMessageReceiveEvent(ctx, 0, int64(rs.WireLength), int64(rs.WireLength))
123+
span.AddMessageReceiveEvent(0, int64(rs.WireLength), int64(rs.WireLength))
121124
case *stats.InTrailer:
122-
trace.AddMessageReceiveEvent(ctx, 0, int64(rs.WireLength), int64(rs.WireLength))
125+
span.AddMessageReceiveEvent(0, int64(rs.WireLength), int64(rs.WireLength))
123126
case *stats.OutPayload:
124-
trace.AddMessageSendEvent(ctx, 0, int64(rs.Length), int64(rs.WireLength))
127+
span.AddMessageSendEvent(0, int64(rs.Length), int64(rs.WireLength))
125128
case *stats.OutHeader:
126-
trace.AddMessageSendEvent(ctx, 0, 0, 0)
129+
span.AddMessageSendEvent(0, 0, 0)
127130
case *stats.OutTrailer:
128-
trace.AddMessageSendEvent(ctx, 0, int64(rs.WireLength), int64(rs.WireLength))
131+
span.AddMessageSendEvent(0, int64(rs.WireLength), int64(rs.WireLength))
129132
case *stats.End:
130133
if rs.Error != nil {
131134
code, desc := grpc.Code(rs.Error), grpc.ErrorDesc(rs.Error)
132-
trace.SetSpanStatus(ctx, trace.Status{Code: int32(code), Message: desc})
135+
span.SetStatus(trace.Status{Code: int32(code), Message: desc})
133136
}
134-
trace.EndSpan(ctx)
137+
span.End()
135138
}
136139
}
137140

plugin/http/httptrace/httptrace.go

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
package httptrace
1717

1818
import (
19-
"context"
2019
"io"
2120
"net/http"
2221
"net/url"
@@ -51,10 +50,9 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
5150
name := spanNameFromURL("Sent", req.URL)
5251
// TODO(jbd): Discuss whether we want to prefix
5352
// outgoing requests with Sent.
54-
ctx := trace.StartSpan(req.Context(), name)
53+
ctx, span := trace.StartSpan(req.Context(), name)
5554
req = req.WithContext(ctx)
5655

57-
span := trace.FromContext(ctx)
5856
for _, f := range t.Formats {
5957
f.ToRequest(span.SpanContext(), req)
6058
}
@@ -63,23 +61,23 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
6361

6462
// TODO(jbd): Add status and attributes.
6563
if err != nil {
66-
trace.EndSpan(ctx)
64+
span.End()
6765
return resp, err
6866
}
6967

7068
// trace.EndSpan(ctx) will be invoked after
7169
// a read from resp.Body returns io.EOF or when
7270
// resp.Body.Close() is invoked.
73-
resp.Body = &spanEndBody{rc: resp.Body, spanCtx: ctx}
71+
resp.Body = &spanEndBody{rc: resp.Body, span: span}
7472
return resp, err
7573
}
7674

7775
// spanEndBody wraps a response.Body and invokes
7876
// trace.EndSpan on encountering io.EOF on reading
7977
// the body of the original response.
8078
type spanEndBody struct {
81-
rc io.ReadCloser
82-
spanCtx context.Context
79+
rc io.ReadCloser
80+
span *trace.Span
8381

8482
endSpanOnce sync.Once
8583
}
@@ -96,7 +94,7 @@ func (seb *spanEndBody) Read(b []byte) (int, error) {
9694
seb.endSpan()
9795
default:
9896
// For all other errors, set the span status
99-
trace.SetSpanStatus(seb.spanCtx, trace.Status{
97+
seb.span.SetStatus(trace.Status{
10098
// Code 2 is the error code for Internal server error.
10199
Code: 2,
102100
Message: err.Error(),
@@ -108,7 +106,7 @@ func (seb *spanEndBody) Read(b []byte) (int, error) {
108106
// endSpan invokes trace.EndSpan exactly once
109107
func (seb *spanEndBody) endSpan() {
110108
seb.endSpanOnce.Do(func() {
111-
trace.EndSpan(seb.spanCtx)
109+
seb.span.End()
112110
})
113111
}
114112

@@ -178,12 +176,13 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
178176
break
179177
}
180178
}
179+
var span *trace.Span
181180
if ok {
182-
ctx = trace.StartSpanWithRemoteParent(ctx, name, sc, trace.StartSpanOptions{})
181+
ctx, span = trace.StartSpanWithRemoteParent(ctx, name, sc, trace.StartOptions{})
183182
} else {
184-
ctx = trace.StartSpan(ctx, name)
183+
ctx, span = trace.StartSpan(ctx, name)
185184
}
186-
defer trace.EndSpan(ctx)
185+
defer span.End()
187186

188187
// TODO(jbd): Add status and attributes.
189188
r = r.WithContext(ctx)

plugin/http/httptrace/httptrace_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func (t testPropagator) ToRequest(sc trace.SpanContext, req *http.Request) {
7171
}
7272

7373
func TestTransport_RoundTrip(t *testing.T) {
74-
parent := trace.NewSpan("parent", trace.StartSpanOptions{})
74+
parent := trace.NewSpan("parent", nil, trace.StartOptions{})
7575
tests := []struct {
7676
name string
7777
parent *trace.Span
@@ -171,9 +171,9 @@ func TestEndToEnd(t *testing.T) {
171171
trace.RegisterExporter(&spans)
172172
defer trace.UnregisterExporter(&spans)
173173

174-
ctx := trace.StartSpanWithOptions(context.Background(),
174+
ctx, _ := trace.StartSpanWithOptions(context.Background(),
175175
"top-level",
176-
trace.StartSpanOptions{
176+
trace.StartOptions{
177177
RecordEvents: true,
178178
Sampler: trace.AlwaysSample(),
179179
})

trace/doc.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ It is common to want to capture all the activity of a function call in a span. F
4343
this to work, the function must take a context.Context as a parameter. Add these two
4444
lines to the top of the function:
4545
46-
ctx = trace.StartSpan(ctx, "your choice of name")
47-
defer trace.EndSpan(ctx)
46+
ctx, span := trace.StartSpan(ctx, "your choice of name")
47+
defer span.End()
4848
4949
StartSpan will create a new top-level span if the context
5050
doesn't contain another span, otherwise it will create a child span.

0 commit comments

Comments
 (0)