Skip to content

Commit 338f620

Browse files
committed
Uploaded wrapper source code
1 parent a0fc057 commit 338f620

8 files changed

Lines changed: 719 additions & 1 deletion

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
# gomongorwapper
1+
# gomongowrapper
22
MongoDB Go wrapper source code

example_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright 2018, OpenCensus Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package mongowrapper_test
16+
17+
import (
18+
"context"
19+
"log"
20+
21+
"github.com/mongodb/mongo-go-driver/bson"
22+
23+
"github.com/opencensus-integrations/gomongowrapper"
24+
25+
"go.opencensus.io/trace"
26+
)
27+
28+
func Example() {
29+
client, err := mongowrapper.NewClient("mongodb://foo:bar@localhost:27017")
30+
if err != nil {
31+
log.Fatalf("Failed to create the new client: %v", err)
32+
}
33+
coll := client.Database("the_db").Collection("music")
34+
35+
ctx, span := trace.StartSpan(context.Background(), "Fetch")
36+
defer span.End()
37+
38+
q := bson.M{"name": "Examples"}
39+
cur, err := coll.Find(ctx, q)
40+
if err != nil {
41+
log.Fatalf("Find error: %v", err)
42+
}
43+
44+
for cur.Next(ctx) {
45+
elem := make(map[string]int)
46+
if err := cur.Decode(elem); err != nil {
47+
log.Printf("Decode error: %v", err)
48+
continue
49+
}
50+
log.Printf("Got result: %v\n", elem)
51+
}
52+
}

mongo.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright 2018, OpenCensus Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package mongowrapper
16+
17+
import (
18+
"context"
19+
20+
"github.com/mongodb/mongo-go-driver/mongo"
21+
"github.com/mongodb/mongo-go-driver/mongo/clientopt"
22+
)
23+
24+
func Connect(ctx context.Context, uri string, opts ...clientopt.Option) (*WrappedClient, error) {
25+
ctx, span := roundtripTrackingSpan(ctx, "github.com/mongodb/mongo-go-driver.Connect")
26+
defer span.end(ctx)
27+
28+
cc, err := mongo.NewClientWithOptions(uri, opts...)
29+
if err != nil {
30+
span.setError(err)
31+
return nil, err
32+
}
33+
34+
wc := &WrappedClient{cc: cc}
35+
err = wc.Connect(ctx)
36+
if err != nil {
37+
span.setError(err)
38+
}
39+
return wc, err
40+
}

observability.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Copyright 2018, OpenCensus Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package mongowrapper
16+
17+
import (
18+
"context"
19+
"sync"
20+
"time"
21+
22+
"go.opencensus.io/stats"
23+
"go.opencensus.io/stats/view"
24+
"go.opencensus.io/tag"
25+
"go.opencensus.io/trace"
26+
)
27+
28+
var (
29+
keyMethod, _ = tag.NewKey("method")
30+
keyStatus, _ = tag.NewKey("status")
31+
keyError, _ = tag.NewKey("error")
32+
)
33+
34+
var mLatencyMs = stats.Float64("latency", "The latency in milliseconds", "ms")
35+
36+
var allViews = []*view.View{
37+
{
38+
Name: "mongo/client/latency", Description: "The latency of the various calls",
39+
Measure: mLatencyMs,
40+
// [0ms, 0.001ms, 0.005ms, 0.01ms, 0.05ms, 0.1ms, 0.5ms, 1ms, 1.5ms, 2ms, 2.5ms, 5ms, 10ms, 25ms, 50ms, 100ms, 200ms,
41+
// 400ms, 600ms, 800ms, 1s, 1.5s, 2s, 2.5s, 5s, 10s, 20s, 40s, 100s, 200s, 500s, 1000s]
42+
//
43+
Aggregation: view.Distribution(0, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 1.5, 2, 2.5, 5, 10, 25, 50, 100, 200,
44+
400, 600, 800, 1000, 1500, 2000, 2500, 5000, 10000, 20000, 40000, 100000, 200000, 500000, 1000000),
45+
TagKeys: []tag.Key{keyMethod, keyStatus, keyError},
46+
},
47+
{
48+
Name: "mongo/client/calls", Description: "The various calls",
49+
Measure: mLatencyMs,
50+
Aggregation: view.Count(),
51+
TagKeys: []tag.Key{keyMethod, keyStatus, keyError},
52+
},
53+
}
54+
55+
func RegisterAllViews() error {
56+
return view.Register(allViews...)
57+
}
58+
59+
func UnregisterAllViews() {
60+
view.Unregister(allViews...)
61+
}
62+
63+
type spanWithMetrics struct {
64+
startTime time.Time
65+
method string
66+
lastErr error
67+
span *trace.Span
68+
endOnce sync.Once
69+
}
70+
71+
func roundtripTrackingSpan(ctx context.Context, methodName string) (context.Context, *spanWithMetrics) {
72+
ctx, span := trace.StartSpan(ctx, methodName)
73+
return ctx, &spanWithMetrics{span: span, startTime: time.Now()}
74+
}
75+
76+
func (swm *spanWithMetrics) setError(err error) {
77+
if err != nil {
78+
swm.span.SetStatus(trace.Status{Code: trace.StatusCodeUnknown, Message: err.Error()})
79+
}
80+
swm.lastErr = err
81+
}
82+
83+
func (swm *spanWithMetrics) end(ctx context.Context) {
84+
swm.endOnce.Do(func() {
85+
if err := swm.lastErr; err == nil {
86+
ctx, _ = tag.New(ctx, tag.Upsert(keyMethod, swm.method), tag.Upsert(keyStatus, "OK"))
87+
} else {
88+
ctx, _ = tag.New(ctx, tag.Upsert(keyMethod, swm.method), tag.Upsert(keyError, err.Error()))
89+
}
90+
91+
latencyMs := float64(time.Now().Sub(swm.startTime)) / 1e6
92+
stats.Record(ctx, mLatencyMs.M(latencyMs))
93+
swm.span.End()
94+
})
95+
}

wrapped_client.go

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// Copyright 2018, OpenCensus Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package mongowrapper
16+
17+
import (
18+
"context"
19+
20+
"github.com/mongodb/mongo-go-driver/core/readpref"
21+
"github.com/mongodb/mongo-go-driver/core/session"
22+
"github.com/mongodb/mongo-go-driver/mongo"
23+
"github.com/mongodb/mongo-go-driver/mongo/dbopt"
24+
"github.com/mongodb/mongo-go-driver/mongo/listdbopt"
25+
"github.com/mongodb/mongo-go-driver/mongo/sessionopt"
26+
)
27+
28+
type WrappedClient struct {
29+
cc *mongo.Client
30+
}
31+
32+
func NewClient(uri string) (*WrappedClient, error) {
33+
client, err := mongo.NewClient(uri)
34+
if err != nil {
35+
return nil, err
36+
}
37+
return &WrappedClient{cc: client}, nil
38+
}
39+
40+
func (wc *WrappedClient) Connect(ctx context.Context) error {
41+
ctx, span := roundtripTrackingSpan(ctx, "github.com/mongodb/mongo-go-driver.Client.Connect")
42+
defer span.end(ctx)
43+
44+
err := wc.cc.Connect(ctx)
45+
if err != nil {
46+
span.setError(err)
47+
}
48+
return err
49+
}
50+
51+
func (wc *WrappedClient) ConnectionString() string { return wc.cc.ConnectionString() }
52+
53+
func (wc *WrappedClient) Database(name string, opts ...dbopt.Option) *WrappedDatabase {
54+
db := wc.cc.Database(name, opts...)
55+
if db == nil {
56+
return nil
57+
}
58+
return &WrappedDatabase{db: db}
59+
}
60+
61+
func (wc *WrappedClient) Disconnect(ctx context.Context) error {
62+
ctx, span := roundtripTrackingSpan(ctx, "github.com/mongodb/mongo-go-driver.Client.Disconnect")
63+
defer span.end(ctx)
64+
65+
err := wc.cc.Disconnect(ctx)
66+
if err != nil {
67+
span.setError(err)
68+
}
69+
return err
70+
}
71+
72+
func (wc *WrappedClient) ListDatabaseNames(ctx context.Context, filter interface{}, opts ...listdbopt.ListDatabases) ([]string, error) {
73+
ctx, span := roundtripTrackingSpan(ctx, "github.com/mongodb/mongo-go-driver.Client.ListDatabaseNames")
74+
defer span.end(ctx)
75+
76+
dbs, err := wc.cc.ListDatabaseNames(ctx, filter, opts...)
77+
if err != nil {
78+
span.setError(err)
79+
}
80+
return dbs, err
81+
}
82+
83+
func (wc *WrappedClient) ListDatabases(ctx context.Context, filter interface{}, opts ...listdbopt.ListDatabases) (mongo.ListDatabasesResult, error) {
84+
ctx, span := roundtripTrackingSpan(ctx, "github.com/mongodb/mongo-go-driver.Client.ListDatabases")
85+
defer span.end(ctx)
86+
87+
dbr, err := wc.cc.ListDatabases(ctx, filter, opts...)
88+
if err != nil {
89+
span.setError(err)
90+
}
91+
return dbr, err
92+
}
93+
94+
func (wc *WrappedClient) Ping(ctx context.Context, rp *readpref.ReadPref) error {
95+
ctx, span := roundtripTrackingSpan(ctx, "github.com/mongodb/mongo-go-driver.Client.Ping")
96+
defer span.end(ctx)
97+
98+
err := wc.cc.Ping(ctx, rp)
99+
if err != nil {
100+
span.setError(err)
101+
}
102+
return err
103+
}
104+
105+
func (wc *WrappedClient) StartSession(opts ...sessionopt.Session) (mongo.Session, error) {
106+
return wc.cc.StartSession(opts...)
107+
}
108+
109+
func (wc *WrappedClient) UseSession(ctx context.Context, fn func(mongo.SessionContext) error) error {
110+
return wc.cc.UseSession(ctx, fn)
111+
}
112+
113+
func (wc *WrappedClient) UseSessionWithOptions(ctx context.Context, opts []sessionopt.Session, fn func(mongo.SessionContext) error) error {
114+
return wc.cc.UseSessionWithOptions(ctx, opts, fn)
115+
}
116+
117+
func (wc *WrappedClient) ValidSession(sess *session.Client) error {
118+
return wc.cc.ValidSession(sess)
119+
}
120+
121+
func (wc *WrappedClient) Client() *mongo.Client { return wc.cc }

0 commit comments

Comments
 (0)