Add a span name getter to opencensus endpoint options (#948)
* Add a span name getter to opencensus endpoint options
* Add GetSpanDetails option
* Split GetSpanDetails function
* Simplify getting the name
* Improve documentation
* Simplify attributes
* Update documentation
* Update tracing/opencensus/endpoint_options.go
Co-authored-by: Peter Bourgon <peterbourgon@users.noreply.github.com>
Márk Sági-Kazár authored 3 years ago
GitHub committed 3 years ago
30 | 30 | |
31 | 31 | return func(next endpoint.Endpoint) endpoint.Endpoint { |
32 | 32 | return func(ctx context.Context, request interface{}) (response interface{}, err error) { |
33 | if cfg.GetName != nil { | |
34 | if newName := cfg.GetName(ctx, name); newName != "" { | |
35 | name = newName | |
36 | } | |
37 | } | |
38 | ||
33 | 39 | ctx, span := trace.StartSpan(ctx, name) |
34 | 40 | if len(cfg.Attributes) > 0 { |
35 | 41 | span.AddAttributes(cfg.Attributes...) |
36 | 42 | } |
37 | 43 | defer span.End() |
44 | ||
45 | if cfg.GetAttributes != nil { | |
46 | if attrs := cfg.GetAttributes(ctx); len(attrs) > 0 { | |
47 | span.AddAttributes(attrs...) | |
48 | } | |
49 | } | |
38 | 50 | |
39 | 51 | defer func() { |
40 | 52 | if err != nil { |
0 | 0 | package opencensus |
1 | 1 | |
2 | import "go.opencensus.io/trace" | |
2 | import ( | |
3 | "context" | |
4 | ||
5 | "go.opencensus.io/trace" | |
6 | ) | |
3 | 7 | |
4 | 8 | // EndpointOptions holds the options for tracing an endpoint |
5 | 9 | type EndpointOptions struct { |
10 | 14 | // Attributes holds the default attributes which will be set on span |
11 | 15 | // creation by our Endpoint middleware. |
12 | 16 | Attributes []trace.Attribute |
17 | ||
18 | // GetName is an optional function that can set the span name based on the existing name | |
19 | // for the endpoint and information in the context. | |
20 | // | |
21 | // If the function is nil, or the returned name is empty, the existing name for the endpoint is used. | |
22 | GetName func(ctx context.Context, name string) string | |
23 | ||
24 | // GetAttributes is an optional function that can extract trace attributes | |
25 | // from the context and add them to the span. | |
26 | GetAttributes func(ctx context.Context) []trace.Attribute | |
13 | 27 | } |
14 | 28 | |
15 | 29 | // EndpointOption allows for functional options to our OpenCensus endpoint |
39 | 53 | o.IgnoreBusinessError = val |
40 | 54 | } |
41 | 55 | } |
56 | ||
57 | // WithSpanName extracts additional attributes from the request context. | |
58 | func WithSpanName(fn func(ctx context.Context, name string) string) EndpointOption { | |
59 | return func(o *EndpointOptions) { | |
60 | o.GetName = fn | |
61 | } | |
62 | } | |
63 | ||
64 | // WithSpanAttributes extracts additional attributes from the request context. | |
65 | func WithSpanAttributes(fn func(ctx context.Context) []trace.Attribute) EndpointOption { | |
66 | return func(o *EndpointOptions) { | |
67 | o.GetAttributes = fn | |
68 | } | |
69 | } |
19 | 19 | span3 = "SPAN-3" |
20 | 20 | span4 = "SPAN-4" |
21 | 21 | span5 = "SPAN-5" |
22 | span6 = "SPAN-6" | |
22 | 23 | ) |
23 | 24 | |
24 | 25 | var ( |
75 | 76 | mw = opencensus.TraceEndpoint(span4) |
76 | 77 | mw(passEndpoint)(ctx, failedResponse{err: err3}) |
77 | 78 | |
78 | // span4 | |
79 | // span5 | |
79 | 80 | mw = opencensus.TraceEndpoint(span5, opencensus.WithIgnoreBusinessError(true)) |
80 | 81 | mw(passEndpoint)(ctx, failedResponse{err: err4}) |
81 | 82 | |
83 | // span6 | |
84 | span6Attrs := []trace.Attribute{ | |
85 | trace.StringAttribute("string", "value"), | |
86 | trace.Int64Attribute("int64", 42), | |
87 | } | |
88 | mw = opencensus.TraceEndpoint( | |
89 | "", | |
90 | opencensus.WithSpanName(func(ctx context.Context, name string) string { | |
91 | return span6 | |
92 | }), | |
93 | opencensus.WithSpanAttributes(func(ctx context.Context) []trace.Attribute { | |
94 | return span6Attrs | |
95 | }), | |
96 | ) | |
97 | mw(endpoint.Nop)(ctx, nil) | |
98 | ||
82 | 99 | // check span count |
83 | 100 | spans := e.Flush() |
84 | if want, have := 5, len(spans); want != have { | |
101 | if want, have := 6, len(spans); want != have { | |
85 | 102 | t.Fatalf("incorrected number of spans, wanted %d, got %d", want, have) |
86 | 103 | } |
87 | 104 | |
155 | 172 | t.Fatalf("incorrect attribute count, wanted %d, got %d", want, have) |
156 | 173 | } |
157 | 174 | |
175 | // test span 6 | |
176 | span = spans[5] | |
177 | if want, have := span6, span.Name; want != have { | |
178 | t.Errorf("incorrect span name, wanted %q, got %q", want, have) | |
179 | } | |
180 | ||
181 | if want, have := 2, len(span.Attributes); want != have { | |
182 | t.Fatalf("incorrect attribute count, wanted %d, got %d", want, have) | |
183 | } | |
158 | 184 | } |