Skip to content

Commit 286bd21

Browse files
authored
Merge pull request #99 from remind101/aws-tracing-helper
Add a helper method to trace aws clients
2 parents 49e7fc7 + 08ac503 commit 286bd21

2 files changed

Lines changed: 130 additions & 0 deletions

File tree

tracing/contrib/aws/request.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package aws
2+
3+
import (
4+
"context"
5+
6+
"github.com/aws/aws-sdk-go/aws/request"
7+
opentracing "github.com/opentracing/opentracing-go"
8+
)
9+
10+
// Option is a hook for adding span tags.
11+
type Option func(opentracing.Span, *request.Request, error)
12+
13+
// Tracer holds tagging options for request tracing.
14+
type Tracer struct {
15+
Opts []Option
16+
}
17+
18+
// New returns a new AWS request tracer with default tagging.
19+
func New(opts ...Option) *Tracer {
20+
opts = append([]Option{defaultTags}, opts...)
21+
return &Tracer{opts}
22+
}
23+
24+
// Send wraps the aws request with an opentracing span.
25+
//
26+
// req, output := dynamoClient.PutItemRequest(input)
27+
// err := t.Send(ctx, req)
28+
func (t *Tracer) Send(ctx context.Context, r *request.Request, opts ...Option) error {
29+
span, ctx := opentracing.StartSpanFromContext(ctx, "client.request")
30+
defer span.Finish()
31+
32+
r.HTTPRequest = r.HTTPRequest.WithContext(ctx)
33+
err := r.Send()
34+
35+
opts = append(t.Opts, opts...)
36+
for _, fn := range opts {
37+
fn(span, r, err)
38+
}
39+
40+
return err
41+
}
42+
43+
func defaultTags(span opentracing.Span, r *request.Request, err error) {
44+
span.SetTag("resource.name", r.Operation.Name)
45+
span.SetTag("http.method", r.Operation.HTTPMethod)
46+
span.SetTag("http.url", r.ClientInfo.Endpoint+r.Operation.HTTPPath)
47+
span.SetTag("out.host", r.ClientInfo.Endpoint)
48+
span.SetTag("aws.operation", r.Operation.Name)
49+
span.SetTag("aws.retry_count", r.RetryCount)
50+
51+
if r.HTTPResponse != nil {
52+
span.SetTag("http.status_code", r.HTTPResponse.StatusCode)
53+
}
54+
55+
if err != nil {
56+
span.SetTag("error.error", err)
57+
}
58+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package aws_test
2+
3+
import (
4+
"context"
5+
"net/http"
6+
"testing"
7+
8+
"github.com/aws/aws-sdk-go/aws"
9+
"github.com/aws/aws-sdk-go/aws/request"
10+
"github.com/aws/aws-sdk-go/awstesting/mock"
11+
opentracing "github.com/opentracing/opentracing-go"
12+
"github.com/opentracing/opentracing-go/mocktracer"
13+
awsot "github.com/remind101/pkg/tracing/contrib/aws"
14+
)
15+
16+
func TestSend(t *testing.T) {
17+
tracer := mocktracer.New()
18+
opentracing.SetGlobalTracer(tracer)
19+
20+
_, ctx := opentracing.StartSpanFromContext(context.Background(), "root")
21+
22+
client := mock.NewMockClient(&aws.Config{Region: aws.String("us-west-2")})
23+
r := client.NewRequest(&request.Operation{
24+
Name: "object.get",
25+
HTTPMethod: "GET",
26+
HTTPPath: "/foobar",
27+
}, nil, nil)
28+
29+
awsTracer := awsot.New()
30+
31+
err := awsTracer.Send(ctx, r, func(s opentracing.Span, r *request.Request, err error) {
32+
s.SetTag("span.type", "external")
33+
s.SetTag("service.name", "aws.s3")
34+
})
35+
36+
if err != nil {
37+
t.Fatalf("expected no error; got %v", err)
38+
}
39+
40+
spans := tracer.FinishedSpans()
41+
if len(spans) != 1 {
42+
t.Fatal("expected 1 finished span")
43+
}
44+
span := spans[0]
45+
if got, want := span.OperationName, "client.request"; got != want {
46+
t.Errorf("got: %+v; expected %+v", got, want)
47+
}
48+
49+
tags := map[string]string{
50+
"span.type": "external",
51+
"service.name": "aws.s3",
52+
"resource.name": "object.get",
53+
"http.method": "GET",
54+
"http.url": client.Endpoint + "/foobar",
55+
"out.host": client.Endpoint,
56+
"aws.operation": "object.get",
57+
}
58+
59+
for k, v := range tags {
60+
if got, want := span.Tag(k).(string), v; got != want {
61+
t.Errorf("span.Tag('%s'): %+v; expected %+v", k, got, want)
62+
}
63+
}
64+
65+
if got, want := span.Tag("http.status_code").(int), http.StatusOK; got != want {
66+
t.Errorf("got: %+v; expected %+v", got, want)
67+
}
68+
69+
if got, want := span.Tag("aws.retry_count").(int), 0; got != want {
70+
t.Errorf("got: %+v; expected %+v", got, want)
71+
}
72+
}

0 commit comments

Comments
 (0)