mongotrace

package
v0.1.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 12, 2026 License: Apache-2.0 Imports: 26 Imported by: 0

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

View Source
const (

	// ErrorTypeOther is the fallback error.type per OTel when no custom value applies.
	ErrorTypeOther = "_OTHER"
)
View Source
const TraceMetadataKey = "_oteltrace"

TraceMetadataKey is the BSON field name used to store trace metadata in documents.

Variables

View Source
var ErrInitTracerRequired = errors.New("mongotrace: InitTracer must be called before Connect")

ErrInitTracerRequired is returned when Connect is called before InitTracer.

Functions

func ContextFromDocument

func ContextFromDocument(ctx context.Context, raw bson.Raw) context.Context

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

type Client struct {
	*mongo.Client
	// contains filtered or unexported fields
}

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

func (c *Client) Database(name string, opts ...options.Lister[options.DatabaseOptions]) *Database

Database returns a wrapped Database for document-level tracing (uses global TracerProvider).

func (*Client) Disconnect

func (c *Client) Disconnect(ctx context.Context) error

Disconnect disconnects the MongoDB client.

func (*Client) Ping added in v0.1.2

func (c *Client) Ping(ctx context.Context, rp *readpref.ReadPref) error

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

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

Watch starts a change stream. Use ContextFromDocument(ctx, event.FullDocument) to restore trace context from fullDocument. Span follows OTel DB semconv.

type Cursor

type Cursor struct {
	*mongo.Cursor
	// contains filtered or unexported fields
}

Cursor wraps *mongo.Cursor so that callers can optionally extract the trace context stored in each document as they iterate.

func (*Cursor) Decode

func (c *Cursor) Decode(val any) error

Decode decodes the current document into val. It delegates directly to the underlying *mongo.Cursor.Decode.

func (*Cursor) DecodeWithContext

func (c *Cursor) DecodeWithContext(ctx context.Context, val any) (context.Context, error)

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

type Database struct {
	*mongo.Database
	// contains filtered or unexported fields
}

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).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL