Skip to content

Commit 1bf15db

Browse files
authored
Chore: Upgrade otel dependencies (#967)
1 parent d4d1f4e commit 1bf15db

File tree

5 files changed

+114
-212
lines changed

5 files changed

+114
-212
lines changed

backend/httpclient/tracing_middleware.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"go.opentelemetry.io/otel/attribute"
1212
"go.opentelemetry.io/otel/codes"
1313
"go.opentelemetry.io/otel/propagation"
14+
semconv "go.opentelemetry.io/otel/semconv/v1.25.0"
1415
"go.opentelemetry.io/otel/trace"
1516

1617
"github.com/grafana/grafana-plugin-sdk-go/backend/tracing"
@@ -33,11 +34,7 @@ func TracingMiddleware(tracer trace.Tracer) Middleware {
3334
ctx, span := t.Start(req.Context(), "HTTP Outgoing Request", trace.WithSpanKind(trace.SpanKindClient))
3435
defer span.End()
3536

36-
ctx = httptrace.WithClientTrace(
37-
ctx,
38-
otelhttptrace.NewClientTrace(ctx, otelhttptrace.WithoutSubSpans(), otelhttptrace.WithoutHeaders()),
39-
)
40-
37+
ctx = httptrace.WithClientTrace(ctx, otelhttptrace.NewClientTrace(ctx, otelhttptrace.WithoutSubSpans(), otelhttptrace.WithoutHeaders()))
4138
req = req.WithContext(ctx)
4239
for k, v := range opts.Labels {
4340
span.SetAttributes(attribute.Key(k).String(v))
@@ -46,10 +43,13 @@ func TracingMiddleware(tracer trace.Tracer) Middleware {
4643
otel.GetTextMapPropagator().Inject(ctx, propagation.HeaderCarrier(req.Header))
4744
res, err := next.RoundTrip(req)
4845

49-
span.SetAttributes(attribute.String("http.url", req.URL.String()))
50-
span.SetAttributes(attribute.String("http.method", req.Method))
46+
span.SetAttributes(
47+
semconv.HTTPURL(req.URL.String()),
48+
semconv.HTTPMethod(req.Method),
49+
)
5150

5251
if err != nil {
52+
span.SetStatus(codes.Error, "request failed")
5353
span.RecordError(err)
5454
return res, err
5555
}
@@ -58,10 +58,10 @@ func TracingMiddleware(tracer trace.Tracer) Middleware {
5858
// we avoid measuring contentlength less than zero because it indicates
5959
// that the content size is unknown. https://godoc.org/github.com/badu/http#Response
6060
if res.ContentLength > 0 {
61-
span.SetAttributes(attribute.Key(httpContentLengthTagKey).Int64(res.ContentLength))
61+
span.SetAttributes(attribute.Int64(httpContentLengthTagKey, res.ContentLength))
6262
}
6363

64-
span.SetAttributes(attribute.Int("http.status_code", res.StatusCode))
64+
span.SetAttributes(semconv.HTTPStatusCode(res.StatusCode))
6565
if res.StatusCode >= 400 {
6666
span.SetStatus(codes.Error, fmt.Sprintf("error with HTTP status code %s", strconv.Itoa(res.StatusCode)))
6767
}

backend/httpclient/tracing_middleware_test.go

Lines changed: 60 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -9,118 +9,15 @@ import (
99
"github.com/stretchr/testify/require"
1010
"go.opentelemetry.io/otel/attribute"
1111
"go.opentelemetry.io/otel/codes"
12+
sdktrace "go.opentelemetry.io/otel/sdk/trace"
1213
"go.opentelemetry.io/otel/sdk/trace/tracetest"
14+
semconv "go.opentelemetry.io/otel/semconv/v1.25.0"
1315
"go.opentelemetry.io/otel/trace"
14-
"go.opentelemetry.io/otel/trace/embedded"
1516

1617
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
1718
"github.com/grafana/grafana-plugin-sdk-go/internal/tracerprovider"
1819
)
1920

20-
type mockTracerProvider struct {
21-
embedded.TracerProvider
22-
}
23-
24-
var _ trace.TracerProvider = mockTracerProvider{}
25-
26-
func (p mockTracerProvider) Tracer(string, ...trace.TracerOption) trace.Tracer {
27-
return &mockTracer{}
28-
}
29-
30-
type mockTracer struct {
31-
embedded.Tracer
32-
33-
spans []*mockSpan
34-
}
35-
36-
var _ trace.Tracer = &mockTracer{}
37-
38-
func (t *mockTracer) Start(ctx context.Context, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) {
39-
config := trace.NewSpanStartConfig(opts...)
40-
span := &mockSpan{}
41-
span.SetName(name)
42-
span.SetAttributes(config.Attributes()...)
43-
t.spans = append(t.spans, span)
44-
return trace.ContextWithSpan(ctx, span), span
45-
}
46-
47-
// mockSpan is an implementation of Span that preforms no operations.
48-
type mockSpan struct {
49-
embedded.Span
50-
51-
name string
52-
ended bool
53-
54-
errored bool
55-
errs []error
56-
57-
statusCode codes.Code
58-
statusMessage string
59-
60-
attributes []attribute.KeyValue
61-
events []string
62-
}
63-
64-
var _ trace.Span = &mockSpan{}
65-
66-
// checkValid panics if s has already ended, otherwise it does nothing.
67-
// This ensures that ended spans are never edited afterwards.
68-
func (s *mockSpan) checkValid() {
69-
if s.ended {
70-
panic("span already ended")
71-
}
72-
}
73-
74-
func (s *mockSpan) attributesMap() map[attribute.Key]attribute.Value {
75-
m := make(map[attribute.Key]attribute.Value, len(s.attributes))
76-
for _, attr := range s.attributes {
77-
m[attr.Key] = attr.Value
78-
}
79-
return m
80-
}
81-
82-
func (*mockSpan) SpanContext() trace.SpanContext { return trace.SpanContext{} }
83-
84-
func (*mockSpan) IsRecording() bool { return false }
85-
86-
func (s *mockSpan) SetStatus(code codes.Code, message string) {
87-
s.checkValid()
88-
s.statusCode = code
89-
s.statusMessage = message
90-
}
91-
92-
func (s *mockSpan) SetError(errored bool) {
93-
s.checkValid()
94-
s.errored = errored
95-
}
96-
97-
func (s *mockSpan) SetAttributes(kv ...attribute.KeyValue) {
98-
s.checkValid()
99-
s.attributes = append(s.attributes, kv...)
100-
}
101-
102-
func (s *mockSpan) End(...trace.SpanEndOption) {
103-
s.checkValid()
104-
s.ended = true
105-
}
106-
107-
func (s *mockSpan) RecordError(err error, _ ...trace.EventOption) {
108-
s.checkValid()
109-
s.errs = append(s.errs, err)
110-
}
111-
112-
func (s *mockSpan) AddEvent(event string, _ ...trace.EventOption) {
113-
s.checkValid()
114-
s.events = append(s.events, event)
115-
}
116-
117-
func (s *mockSpan) SetName(name string) {
118-
s.checkValid()
119-
s.name = name
120-
}
121-
122-
func (*mockSpan) TracerProvider() trace.TracerProvider { return mockTracerProvider{} }
123-
12421
func TestTracingMiddlewareWithDefaultTracerDataRace(t *testing.T) {
12522
var tracer trace.Tracer
12623

@@ -141,7 +38,9 @@ func TestTracingMiddlewareWithDefaultTracerDataRace(t *testing.T) {
14138

14239
func TestTracingMiddleware(t *testing.T) {
14340
t.Run("GET request that returns 200 OK should start and capture span", func(t *testing.T) {
144-
tracer := &mockTracer{}
41+
spanRecorder := tracetest.NewSpanRecorder()
42+
provider := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(spanRecorder))
43+
tracer := provider.Tracer("test")
14544

14645
finalRoundTripper := httpclient.RoundTripperFunc(func(req *http.Request) (*http.Response, error) {
14746
return &http.Response{StatusCode: http.StatusOK, Request: req}, nil
@@ -169,24 +68,28 @@ func TestTracingMiddleware(t *testing.T) {
16968
require.NoError(t, res.Body.Close())
17069
}
17170

172-
require.Len(t, tracer.spans, 1)
173-
span := tracer.spans[0]
174-
require.Equal(t, "HTTP Outgoing Request", span.name)
175-
require.True(t, span.ended)
176-
require.False(t, span.errored)
177-
require.Equal(t, codes.Unset, span.statusCode)
178-
require.Empty(t, span.statusMessage)
179-
require.Equal(t, map[attribute.Key]attribute.Value{
180-
"l1": attribute.StringValue("v1"),
181-
"l2": attribute.StringValue("v2"),
182-
"http.url": attribute.StringValue("http://test.com/query"),
183-
"http.method": attribute.StringValue("GET"),
184-
"http.status_code": attribute.Int64Value(200),
185-
}, span.attributesMap())
71+
spans := spanRecorder.Ended()
72+
73+
require.Len(t, spans, 1)
74+
span := spans[0]
75+
require.Equal(t, "HTTP Outgoing Request", span.Name())
76+
require.False(t, span.EndTime().IsZero())
77+
require.False(t, span.Status().Code == codes.Error)
78+
require.Equal(t, codes.Unset, span.Status().Code)
79+
require.Empty(t, span.Status().Description)
80+
require.ElementsMatch(t, []attribute.KeyValue{
81+
attribute.String("l1", "v1"),
82+
attribute.String("l2", "v2"),
83+
semconv.HTTPURL("http://test.com/query"),
84+
semconv.HTTPMethod(http.MethodGet),
85+
semconv.HTTPStatusCode(http.StatusOK),
86+
}, span.Attributes())
18687
})
18788

18889
t.Run("GET request that returns 400 Bad Request should start and capture span", func(t *testing.T) {
189-
tracer := &mockTracer{}
90+
spanRecorder := tracetest.NewSpanRecorder()
91+
provider := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(spanRecorder))
92+
tracer := provider.Tracer("test")
19093

19194
finalRoundTripper := httpclient.RoundTripperFunc(func(req *http.Request) (*http.Response, error) {
19295
return &http.Response{StatusCode: http.StatusBadRequest, Request: req}, nil
@@ -214,27 +117,31 @@ func TestTracingMiddleware(t *testing.T) {
214117
require.NoError(t, res.Body.Close())
215118
}
216119

217-
require.Len(t, tracer.spans, 1)
218-
span := tracer.spans[0]
219-
require.Equal(t, "HTTP Outgoing Request", span.name)
220-
require.True(t, span.ended)
221-
require.False(t, span.errored)
222-
require.Equal(t, codes.Error, span.statusCode)
223-
require.Equal(t, "error with HTTP status code 400", span.statusMessage)
224-
require.Equal(t, map[attribute.Key]attribute.Value{
225-
"l1": attribute.StringValue("v1"),
226-
"l2": attribute.StringValue("v2"),
227-
"http.url": attribute.StringValue("http://test.com/query"),
228-
"http.method": attribute.StringValue("GET"),
229-
"http.status_code": attribute.Int64Value(400),
230-
}, span.attributesMap())
120+
spans := spanRecorder.Ended()
121+
122+
require.Len(t, spans, 1)
123+
span := spans[0]
124+
require.Equal(t, "HTTP Outgoing Request", span.Name())
125+
require.False(t, span.EndTime().IsZero())
126+
require.Equal(t, codes.Error, span.Status().Code)
127+
require.Equal(t, "error with HTTP status code 400", span.Status().Description)
128+
require.Equal(t, []attribute.KeyValue{
129+
attribute.String("l1", "v1"),
130+
attribute.String("l2", "v2"),
131+
semconv.HTTPURL("http://test.com/query"),
132+
semconv.HTTPMethod(http.MethodGet),
133+
semconv.HTTPStatusCode(http.StatusBadRequest),
134+
}, span.Attributes())
231135
})
232136

233137
t.Run("POST request that returns 200 OK should start and capture span", func(t *testing.T) {
234-
tracer := &mockTracer{}
138+
spanRecorder := tracetest.NewSpanRecorder()
139+
provider := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(spanRecorder))
140+
tracer := provider.Tracer("test")
235141

142+
resContentLength := int64(10)
236143
finalRoundTripper := httpclient.RoundTripperFunc(func(req *http.Request) (*http.Response, error) {
237-
return &http.Response{StatusCode: http.StatusOK, Request: req, ContentLength: 10}, nil
144+
return &http.Response{StatusCode: http.StatusOK, Request: req, ContentLength: resContentLength}, nil
238145
})
239146

240147
mw := httpclient.TracingMiddleware(tracer)
@@ -259,24 +166,22 @@ func TestTracingMiddleware(t *testing.T) {
259166
require.NoError(t, res.Body.Close())
260167
}
261168

262-
require.Len(t, tracer.spans, 1)
263-
span := tracer.spans[0]
264-
require.Equal(t, "HTTP Outgoing Request", span.name)
265-
require.True(t, span.ended)
266-
require.False(t, span.errored)
267-
require.Equal(t, codes.Unset, span.statusCode)
268-
require.Empty(t, span.statusMessage)
269-
attrMap := span.attributesMap()
270-
_, ok = attrMap["http.content_length"]
271-
require.True(t, ok, "http.content_length does not exist")
272-
delete(attrMap, "http.content_length")
273-
require.Equal(t, map[attribute.Key]attribute.Value{
274-
"l1": attribute.StringValue("v1"),
275-
"l2": attribute.StringValue("v2"),
276-
"http.url": attribute.StringValue("http://test.com/query"),
277-
"http.method": attribute.StringValue("POST"),
278-
"http.status_code": attribute.Int64Value(200),
279-
}, attrMap)
169+
spans := spanRecorder.Ended()
170+
171+
require.Len(t, spans, 1)
172+
span := spans[0]
173+
require.Equal(t, "HTTP Outgoing Request", span.Name())
174+
require.False(t, span.EndTime().IsZero())
175+
require.Equal(t, codes.Unset, span.Status().Code)
176+
require.Empty(t, span.Status().Description)
177+
require.ElementsMatch(t, []attribute.KeyValue{
178+
attribute.String("l1", "v1"),
179+
attribute.String("l2", "v2"),
180+
semconv.HTTPURL("http://test.com/query"),
181+
semconv.HTTPMethod(http.MethodPost),
182+
semconv.HTTPStatusCode(http.StatusOK),
183+
attribute.Int64("http.content_length", resContentLength),
184+
}, span.Attributes())
280185
})
281186

282187
t.Run("propagation", func(t *testing.T) {

backend/setup.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99

1010
"go.opentelemetry.io/otel"
1111
"go.opentelemetry.io/otel/attribute"
12-
semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
12+
semconv "go.opentelemetry.io/otel/semconv/v1.25.0"
1313

1414
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
1515
"github.com/grafana/grafana-plugin-sdk-go/backend/tracing"

go.mod

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ require (
2424
github.com/stretchr/testify v1.9.0
2525
github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8
2626
github.com/urfave/cli v1.22.15
27-
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0
28-
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.49.0
29-
go.opentelemetry.io/contrib/propagators/jaeger v1.22.0
30-
go.opentelemetry.io/contrib/samplers/jaegerremote v0.18.0
31-
go.opentelemetry.io/otel v1.24.0
32-
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0
33-
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0
34-
go.opentelemetry.io/otel/sdk v1.24.0
35-
go.opentelemetry.io/otel/trace v1.24.0
27+
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.51.0
28+
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.51.0
29+
go.opentelemetry.io/contrib/propagators/jaeger v1.26.0
30+
go.opentelemetry.io/contrib/samplers/jaegerremote v0.20.0
31+
go.opentelemetry.io/otel v1.26.0
32+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0
33+
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.26.0
34+
go.opentelemetry.io/otel/sdk v1.26.0
35+
go.opentelemetry.io/otel/trace v1.26.0
3636
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
3737
golang.org/x/net v0.24.0
3838
golang.org/x/oauth2 v0.18.0
@@ -49,7 +49,7 @@ require (
4949
github.com/bahlo/generic-list-go v0.2.0 // indirect
5050
github.com/beorn7/perks v1.0.1 // indirect
5151
github.com/buger/jsonparser v1.1.1 // indirect
52-
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
52+
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
5353
github.com/cespare/xxhash/v2 v2.3.0 // indirect
5454
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
5555
github.com/davecgh/go-spew v1.1.1 // indirect
@@ -69,7 +69,7 @@ require (
6969
github.com/google/gofuzz v1.1.0 // indirect
7070
github.com/gorilla/mux v1.8.1 // indirect
7171
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect
72-
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect
72+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 // indirect
7373
github.com/hashicorp/yamux v0.1.1 // indirect
7474
github.com/invopop/yaml v0.2.0 // indirect
7575
github.com/josharian/intern v1.0.0 // indirect
@@ -94,14 +94,13 @@ require (
9494
github.com/unknwon/log v0.0.0-20150304194804-e617c87089d3 // indirect
9595
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
9696
github.com/zeebo/xxh3 v1.0.2 // indirect
97-
go.opentelemetry.io/otel/metric v1.24.0 // indirect
98-
go.opentelemetry.io/proto/otlp v1.1.0 // indirect
97+
go.opentelemetry.io/otel/metric v1.26.0 // indirect
98+
go.opentelemetry.io/proto/otlp v1.2.0 // indirect
9999
golang.org/x/mod v0.13.0 // indirect
100100
golang.org/x/tools v0.14.0 // indirect
101101
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
102102
google.golang.org/appengine v1.6.8 // indirect
103-
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect
104-
google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de // indirect
103+
google.golang.org/genproto/googleapis/api v0.0.0-20240415180920-8c6c420018be // indirect
105104
google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect
106105
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect
107106
gopkg.in/yaml.v3 v3.0.1 // indirect

0 commit comments

Comments
 (0)