Documentation
¶
Overview ¶
Package mongotrace provides a MongoDB driver v2 wrapper that propagates OpenTelemetry trace contexts to and from documents stored in MongoDB. Trace metadata is stored in a reserved field named "_oteltrace" in each document, enabling full lifecycle tracing of data across services.
Index ¶
- Constants
- Variables
- func ContextFromDocument(ctx context.Context, raw bson.Raw) context.Context
- func InitTracer(endpoint string, args ...interface{}) (trace.TracerProvider, error)
- func ShutdownTracer()
- type Client
- func (c *Client) Database(name string, opts ...options.Lister[options.DatabaseOptions]) *Database
- func (c *Client) Disconnect(ctx context.Context) error
- func (c *Client) Ping(ctx context.Context, rp *readpref.ReadPref) error
- func (c *Client) StartSession(opts ...options.Lister[options.SessionOptions]) (*mongo.Session, error)
- type Collection
- func (c *Collection) Aggregate(ctx context.Context, pipeline any, ...) (*Cursor, error)
- func (c *Collection) BulkWrite(ctx context.Context, models []mongo.WriteModel, ...) (*mongo.BulkWriteResult, error)
- func (c *Collection) CountDocuments(ctx context.Context, filter any, opts ...options.Lister[options.CountOptions]) (int64, error)
- func (c *Collection) DeleteMany(ctx context.Context, filter any, ...) (*mongo.DeleteResult, error)
- func (c *Collection) DeleteOne(ctx context.Context, filter any, ...) (*mongo.DeleteResult, error)
- func (c *Collection) DeleteOneByID(ctx context.Context, id any, opts ...options.Lister[options.DeleteOneOptions]) (*mongo.DeleteResult, error)
- func (c *Collection) Distinct(ctx context.Context, fieldName string, filter any, ...) *mongo.DistinctResult
- func (c *Collection) Find(ctx context.Context, filter any, opts ...options.Lister[options.FindOptions]) (*Cursor, error)
- func (c *Collection) FindByIDs(ctx context.Context, ids []any, opts ...options.Lister[options.FindOptions]) (*Cursor, error)
- func (c *Collection) FindOne(ctx context.Context, filter any, ...) *SingleResult
- func (c *Collection) FindOneByID(ctx context.Context, id any, opts ...options.Lister[options.FindOneOptions]) *SingleResult
- func (c *Collection) InsertMany(ctx context.Context, documents []any, ...) (*mongo.InsertManyResult, error)
- func (c *Collection) InsertOne(ctx context.Context, document any, ...) (*mongo.InsertOneResult, error)
- func (c *Collection) ReplaceOne(ctx context.Context, filter any, replacement any, ...) (*mongo.UpdateResult, error)
- func (c *Collection) UpdateByID(ctx context.Context, id any, update any, ...) (*mongo.UpdateResult, error)
- func (c *Collection) UpdateMany(ctx context.Context, filter any, update any, ...) (*mongo.UpdateResult, error)
- func (c *Collection) UpdateOne(ctx context.Context, filter any, update any, ...) (*mongo.UpdateResult, error)
- func (c *Collection) Watch(ctx context.Context, pipeline any, ...) (*mongo.ChangeStream, error)
- type Cursor
- type Database
- type SingleResult
- type TraceMetadata
- type TracerProviderOption
Constants ¶
const (
// ErrorTypeOther is the fallback error.type per OTel when no custom value applies.
ErrorTypeOther = "_OTHER"
)
const TraceMetadataKey = "_oteltrace"
TraceMetadataKey is the BSON field name used to store trace metadata in documents.
Variables ¶
var ErrInitTracerRequired = errors.New("mongotrace: InitTracer must be called before Connect")
ErrInitTracerRequired is returned when Connect is called before InitTracer.
Functions ¶
func ContextFromDocument ¶
ContextFromDocument returns a context enriched with the trace context stored in the document's "_oteltrace" field. Intended for consumers that read documents outside of the Collection CRUD helpers (e.g. change stream fullDocument). When _oteltrace is absent or invalid, the original ctx is returned unchanged.
func InitTracer ¶
func InitTracer(endpoint string, args ...interface{}) (trace.TracerProvider, error)
InitTracer sets the global TracerProvider and TextMapPropagator for the process. Call once at startup (e.g. in main) with OTLP endpoint and resource attributes. Propagator is fixed to TraceContext + Baggage. If the global provider is already an SDK TracerProvider (e.g. set by another package), InitTracer is a no-op. Empty endpoint uses OTEL_EXPORTER_OTLP_ENDPOINT env or "localhost:4317".
InitTracer returns the TracerProvider so the caller can defer shutdown:
tp, err := mongotrace.InitTracer(endpoint, attrs...)
if err != nil { ... }
if sdk, ok := tp.(*sdktrace.TracerProvider); ok {
defer func() { _ = sdk.Shutdown(context.Background()) }()
}
To use a custom TracerProvider (e.g. in tests), pass WithTracerProvider(tp) as an argument.
func ShutdownTracer ¶
func ShutdownTracer()
ShutdownTracer shuts down the TracerProvider set by InitTracer and resets the global state. After ShutdownTracer, Connect must not be used until InitTracer is called again. The package also registers runtime.AddCleanup (Go 1.24+) so ShutdownTracer runs when the process tears down (best-effort). For guaranteed flush before exit, call "defer mongotrace.ShutdownTracer()" in main.
Types ¶
type Client ¶
Client wraps *mongo.Client with OpenTelemetry instrumentation. Call InitTracer once at startup.
func Connect ¶ added in v0.1.3
func Connect(opts ...*options.ClientOptions) (*Client, error)
Connect creates a new Client with the given configuration options, with OpenTelemetry instrumentation. Signature aligns with mongo.Connect(opts ...*options.ClientOptions); options are merged and the OTel monitor is injected (our options are applied last so the monitor is not overwritten). InitTracer must be called first or Connect returns ErrInitTracerRequired.
func (*Client) Database ¶
Database returns a wrapped Database for document-level tracing (uses global TracerProvider).
func (*Client) Disconnect ¶
Disconnect disconnects the MongoDB client.
func (*Client) Ping ¶ added in v0.1.2
Ping runs a ping command against the server. Driver-level otelmongo monitor instruments the command. Use readpref.Primary() or nil for default.
func (*Client) StartSession ¶ added in v0.1.2
func (c *Client) StartSession(opts ...options.Lister[options.SessionOptions]) (*mongo.Session, error)
StartSession starts a new session. Operations executed with the session should use this client's Database/Collection so document-level tracing applies.
type Collection ¶
type Collection struct {
*mongo.Collection
// contains filtered or unexported fields
}
Collection wraps *mongo.Collection and overrides CRUD methods to inject and extract OpenTelemetry trace contexts via the "_oteltrace" document field. All other Collection methods (Name, Database, Drop, Indexes, etc.) are available through the embedded *mongo.Collection.
func NewCollection ¶
func NewCollection(coll *mongo.Collection, tracer trace.Tracer) *Collection
NewCollection wraps an existing *mongo.Collection with trace propagation support using the supplied tracer. Server address/port are left empty.
func (*Collection) Aggregate ¶ added in v0.1.2
func (c *Collection) Aggregate(ctx context.Context, pipeline any, opts ...options.Lister[options.AggregateOptions]) (*Cursor, error)
Aggregate runs an aggregation pipeline and returns a Cursor that supports DecodeWithContext for document trace propagation. Span follows OTel DB semconv.
func (*Collection) BulkWrite ¶ added in v0.1.2
func (c *Collection) BulkWrite(ctx context.Context, models []mongo.WriteModel, opts ...options.Lister[options.BulkWriteOptions]) (*mongo.BulkWriteResult, error)
BulkWrite runs multiple write operations. Span follows OTel DB semconv. For trace propagation into documents, use individual InsertOne/UpdateOne/etc.; BulkWrite does not inject _oteltrace into each model in this version.
func (*Collection) CountDocuments ¶ added in v0.1.2
func (c *Collection) CountDocuments(ctx context.Context, filter any, opts ...options.Lister[options.CountOptions]) (int64, error)
CountDocuments counts documents matching filter. Span follows OTel DB semconv (read-only, no _oteltrace).
func (*Collection) DeleteMany ¶
func (c *Collection) DeleteMany(ctx context.Context, filter any, opts ...options.Lister[options.DeleteManyOptions]) (*mongo.DeleteResult, error)
DeleteMany executes a delete command against all documents matching filter. Span follows OTel DB semconv. No per-document origin read (batch).
func (*Collection) DeleteOne ¶
func (c *Collection) DeleteOne(ctx context.Context, filter any, opts ...options.Lister[options.DeleteOneOptions]) (*mongo.DeleteResult, error)
DeleteOne deletes one document. No extra read; one round-trip only. Span follows OTel DB semconv.
func (*Collection) DeleteOneByID ¶ added in v0.1.2
func (c *Collection) DeleteOneByID(ctx context.Context, id any, opts ...options.Lister[options.DeleteOneOptions]) (*mongo.DeleteResult, error)
DeleteOneByID deletes one document by _id. Span follows OTel DB semconv (no _oteltrace on delete).
func (*Collection) Distinct ¶ added in v0.1.2
func (c *Collection) Distinct(ctx context.Context, fieldName string, filter any, opts ...options.Lister[options.DistinctOptions]) *mongo.DistinctResult
Distinct returns distinct values for fieldName. Span follows OTel DB semconv (read-only). Call the result's Err() after decoding to check for errors.
func (*Collection) Find ¶
func (c *Collection) Find(ctx context.Context, filter any, opts ...options.Lister[options.FindOptions]) (*Cursor, error)
Find executes a find command and returns a Cursor that can extract trace contexts from returned documents. Span name/attrs follow OTel DB semconv.
func (*Collection) FindByIDs ¶ added in v0.1.2
func (c *Collection) FindByIDs(ctx context.Context, ids []any, opts ...options.Lister[options.FindOptions]) (*Cursor, error)
FindByIDs returns a Cursor over documents whose _id is in the given ids slice. Use Cursor.DecodeWithContext for trace propagation from each document's _oteltrace.
func (*Collection) FindOne ¶
func (c *Collection) FindOne(ctx context.Context, filter any, opts ...options.Lister[options.FindOneOptions]) *SingleResult
FindOne executes a find command returning at most one document. The returned *SingleResult carries the span; call Decode to end the span and record a span link to the document's origin trace when present.
func (*Collection) FindOneByID ¶ added in v0.1.2
func (c *Collection) FindOneByID(ctx context.Context, id any, opts ...options.Lister[options.FindOneOptions]) *SingleResult
FindOneByID returns a SingleResult for the document with the given _id. Decode or TraceContext to get span link from document's _oteltrace when present.
func (*Collection) InsertMany ¶
func (c *Collection) InsertMany(ctx context.Context, documents []any, opts ...options.Lister[options.InsertManyOptions]) (*mongo.InsertManyResult, error)
InsertMany inserts documents into the collection. The active trace context from ctx is serialised into each document under the "_oteltrace" field before the insert. otelmongo already creates the command span.
func (*Collection) InsertOne ¶
func (c *Collection) InsertOne(ctx context.Context, document any, opts ...options.Lister[options.InsertOneOptions]) (*mongo.InsertOneResult, error)
InsertOne inserts document into the collection. The active trace context from ctx is serialised into the document under the "_oteltrace" field before the insert. otelmongo already creates the command span.
func (*Collection) ReplaceOne ¶
func (c *Collection) ReplaceOne(ctx context.Context, filter any, replacement any, opts ...options.Lister[options.ReplaceOptions]) (*mongo.UpdateResult, error)
ReplaceOne injects the current trace context into the replacement document. otelmongo already creates the command span.
func (*Collection) UpdateByID ¶ added in v0.1.2
func (c *Collection) UpdateByID(ctx context.Context, id any, update any, opts ...options.Lister[options.UpdateOneOptions]) (*mongo.UpdateResult, error)
UpdateByID updates one document by _id. Injects current trace into update (document _oteltrace is replaced). Span follows OTel DB semconv.
func (*Collection) UpdateMany ¶
func (c *Collection) UpdateMany(ctx context.Context, filter any, update any, opts ...options.Lister[options.UpdateManyOptions]) (*mongo.UpdateResult, error)
UpdateMany injects the current trace context into the update so matched documents record the most recent writer's trace. No per-document origin read (batch). Span follows OTel DB semconv.
func (*Collection) UpdateOne ¶
func (c *Collection) UpdateOne(ctx context.Context, filter any, update any, opts ...options.Lister[options.UpdateOneOptions]) (*mongo.UpdateResult, error)
UpdateOne injects the current trace context into the update so the document's _oteltrace is replaced. No extra read; one round-trip only. Span follows OTel DB semconv.
func (*Collection) Watch ¶ added in v0.1.2
func (c *Collection) Watch(ctx context.Context, pipeline any, opts ...options.Lister[options.ChangeStreamOptions]) (*mongo.ChangeStream, error)
Watch starts a change stream. Use ContextFromDocument(ctx, event.FullDocument) to restore trace context from fullDocument. Span follows OTel DB semconv.
type Cursor ¶
Cursor wraps *mongo.Cursor so that callers can optionally extract the trace context stored in each document as they iterate.
func (*Cursor) Decode ¶
Decode decodes the current document into val. It delegates directly to the underlying *mongo.Cursor.Decode.
func (*Cursor) DecodeWithContext ¶
DecodeWithContext decodes the current document into val and returns a context enriched with the trace context extracted from the document's "_oteltrace" field. When the field is absent the returned context is unchanged.
Use this instead of Decode when you need to propagate the document's origin trace context downstream.
type Database ¶
Database wraps *mongo.Database for document-level tracing (uses global TracerProvider).
func (*Database) Collection ¶
func (d *Database) Collection(name string, opts ...options.Lister[options.CollectionOptions]) *Collection
Collection returns a Collection with document-level trace propagation.
type SingleResult ¶
type SingleResult struct {
*mongo.SingleResult
// contains filtered or unexported fields
}
SingleResult wraps *mongo.SingleResult so that the stored trace context can be propagated as a span link and extracted by callers.
func (*SingleResult) Decode ¶
func (r *SingleResult) Decode(v any) error
Decode decodes the document and records any stored trace context as a span link on the FindOne span before ending it. The span is ended exactly once regardless of how many times Decode is called.
func (*SingleResult) Raw ¶
func (r *SingleResult) Raw() (bson.Raw, error)
Raw returns the raw BSON document and ends the span exactly once.
func (*SingleResult) TraceContext ¶
func (r *SingleResult) TraceContext() context.Context
TraceContext returns a context enriched with the trace context stored in the fetched document's "_oteltrace" field. It must be called after Decode or Raw. The span is ended exactly once when this method is called.
type TraceMetadata ¶
type TraceMetadata struct {
// Traceparent holds the W3C traceparent header value.
Traceparent string `bson:"traceparent"`
// Tracestate holds the W3C tracestate header value (optional).
Tracestate string `bson:"tracestate,omitempty"`
}
TraceMetadata holds the W3C Trace Context fields stored alongside a MongoDB document.
type TracerProviderOption ¶
type TracerProviderOption struct {
TracerProvider trace.TracerProvider
}
TracerProviderOption holds a TracerProvider to use when passed to InitTracer.
func WithTracerProvider ¶
func WithTracerProvider(tp trace.TracerProvider) TracerProviderOption
WithTracerProvider returns an InitTracer option that uses the given TracerProvider instead of creating one from the endpoint. Use when you need a custom provider (e.g. in tests with a SpanRecorder).