Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add WithCommandLoggingDisabled to otelmongo tracer #723

4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [Unreleased]

## [0.19.0] - 2021-03-19
## [0.19.0] - 2021-03-29
davidgwcurve marked this conversation as resolved.
Show resolved Hide resolved

### Changed

- Upgrade to v0.19.0 of `go.opentelemetry.io/otel`.
- The `go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo` instrumentation now accepts a `WithCommandLoggingDisabled`,
so the caller can specify whether to opt-out of tracing the mongo command. (#712)
davidgwcurve marked this conversation as resolved.
Show resolved Hide resolved

## [0.18.0] - 2021-03-04

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ endif


GOTEST_MIN = go test -v -timeout 30s
GOTEST = $(GOTEST_MIN) -race
GOTEST = CGO_ENABLED=1 $(GOTEST_MIN) -race
davidgwcurve marked this conversation as resolved.
Show resolved Hide resolved
GOTEST_WITH_COVERAGE = $(GOTEST) -coverprofile=coverage.out -covermode=atomic -coverpkg=./...

.DEFAULT_GOAL := precommit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ type config struct {
TracerProvider trace.TracerProvider

Tracer trace.Tracer

CommandLoggingDisabled bool
}

// newConfig returns a config with all Options set.
Expand Down Expand Up @@ -55,3 +57,11 @@ func WithTracerProvider(provider trace.TracerProvider) Option {
cfg.TracerProvider = provider
}
}

// WithCommandLoggingDisabled specifies if tracing of the mongo command is disabled or not.
// If none is specified, logging of the mongo command is enabled.
davidgwcurve marked this conversation as resolved.
Show resolved Hide resolved
func WithCommandLoggingDisabled(disabled bool) Option {
davidgwcurve marked this conversation as resolved.
Show resolved Hide resolved
return func(cfg *config) {
cfg.CommandLoggingDisabled = disabled
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,20 @@ type monitor struct {

func (m *monitor) Started(ctx context.Context, evt *event.CommandStartedEvent) {
hostname, port := peerInfo(evt)
b, _ := bson.MarshalExtJSON(evt.Command, false, false)

attrs := []attribute.KeyValue{
ServiceName(m.serviceName),
DBOperation(evt.CommandName),
DBInstance(evt.DatabaseName),
DBStatement(string(b)),
DBSystem("mongodb"),
PeerHostname(hostname),
PeerPort(port),
}
if !m.cfg.CommandLoggingDisabled {
b, _ := bson.MarshalExtJSON(evt.Command, false, false)
attrs = append(attrs, DBStatement(string(b)))
}

opts := []trace.SpanOption{
trace.WithAttributes(attrs...),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,42 +35,64 @@ func TestMain(m *testing.M) {
}

func Test(t *testing.T) {
sr := new(oteltest.SpanRecorder)
provider := oteltest.NewTracerProvider(oteltest.WithSpanRecorder(sr))
tt := []struct {
title string
commandLoggingDisabled bool
}{
{
title: "should successfully trace spans",
commandLoggingDisabled: false,
},
{
title: "should successfully trace spans without the statement when command logging is disabled",
commandLoggingDisabled: true,
},
}

hostname, port := "localhost", "27017"
for _, tc := range tt {
t.Run(tc.title, func(t *testing.T) {
sr := new(oteltest.SpanRecorder)
provider := oteltest.NewTracerProvider(oteltest.WithSpanRecorder(sr))

ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()
hostname, port := "localhost", "27017"

ctx, span := provider.Tracer(defaultTracerName).Start(ctx, "mongodb-test")
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
defer cancel()

addr := "mongodb://localhost:27017/?connect=direct"
opts := options.Client()
opts.Monitor = NewMonitor("mongo", WithTracerProvider(provider))
opts.ApplyURI(addr)
client, err := mongo.Connect(ctx, opts)
if err != nil {
t.Fatal(err)
}
ctx, span := provider.Tracer(defaultTracerName).Start(ctx, "mongodb-test")

_, err = client.Database("test-database").Collection("test-collection").InsertOne(ctx, bson.D{{Key: "test-item", Value: "test-value"}})
if err != nil {
t.Fatal(err)
}
addr := "mongodb://localhost:27017/?connect=direct"
opts := options.Client()
opts.Monitor = NewMonitor("mongo", WithTracerProvider(provider), WithCommandLoggingDisabled(tc.commandLoggingDisabled))
opts.ApplyURI(addr)
client, err := mongo.Connect(ctx, opts)
if err != nil {
t.Fatal(err)
}

span.End()
_, err = client.Database("test-database").Collection("test-collection").InsertOne(ctx, bson.D{{Key: "test-item", Value: "test-value"}})
if err != nil {
t.Fatal(err)
}

spans := sr.Completed()
assert.Len(t, spans, 2)
assert.Equal(t, spans[0].SpanContext().TraceID, spans[1].SpanContext().TraceID)
span.End()

s := spans[0]
assert.Equal(t, "mongo", s.Attributes()[ServiceNameKey].AsString())
assert.Equal(t, "insert", s.Attributes()[DBOperationKey].AsString())
assert.Equal(t, hostname, s.Attributes()[PeerHostnameKey].AsString())
assert.Equal(t, port, s.Attributes()[PeerPortKey].AsString())
assert.Contains(t, s.Attributes()[DBStatementKey].AsString(), `"test-item":"test-value"`)
assert.Equal(t, "test-database", s.Attributes()[DBInstanceKey].AsString())
assert.Equal(t, "mongodb", s.Attributes()[DBSystemKey].AsString())
spans := sr.Completed()
assert.Len(t, spans, 2)
assert.Equal(t, spans[0].SpanContext().TraceID, spans[1].SpanContext().TraceID)

s := spans[0]
assert.Equal(t, "mongo", s.Attributes()[ServiceNameKey].AsString())
assert.Equal(t, "insert", s.Attributes()[DBOperationKey].AsString())
assert.Equal(t, hostname, s.Attributes()[PeerHostnameKey].AsString())
assert.Equal(t, port, s.Attributes()[PeerPortKey].AsString())
if tc.commandLoggingDisabled {
assert.NotContains(t, s.Attributes()[DBStatementKey].AsString(), `"test-item":"test-value"`)
} else {
assert.Contains(t, s.Attributes()[DBStatementKey].AsString(), `"test-item":"test-value"`)
}
assert.Equal(t, "test-database", s.Attributes()[DBInstanceKey].AsString())
assert.Equal(t, "mongodb", s.Attributes()[DBSystemKey].AsString())
})
}
}