Database spans
Record database queries automatically or manually.
MongoDB - wrapCollection
Wrap a MongoDB collection once and every operation is traced automatically. Import from because/mongodb:
import { wrapCollection } from '@refactorlabs/because/mongodb';
const usersCol = wrapCollection(db.collection('users'));Then use it exactly as you would a normal collection:
await because.startTrace('Process application', async () => {
// db span recorded automatically - filter, collection, duration, found/not
const user = await usersCol.findOne({ accountId: req.accountId });
const results = await usersCol
.find({ status: 'active', plan: 'enterprise' })
.toArray();
});Each span captures the operation name, collection, filter/pipeline, and a result summary (found, count, insertedId, etc.). Document contents are never recorded - only metadata about the query result.
Redacting filter values
If your filters contain PII, pass a redact option:
const customersCol = wrapCollection(db.collection('customers'), {
redact: ['name', 'billing.accountName', 'billing.accountNumber']
});Redact paths are applied to the span's input (the filter object). See Redaction for syntax.
Supported operations
findOne, find (via .toArray()), insertOne, insertMany, updateOne, updateMany, deleteOne, deleteMany, replaceOne, findOneAndUpdate, findOneAndDelete, aggregate (via .toArray()), countDocuments
Install
mongodb is a peer dependency - use the version already in your project:
npm install @refactorlabs/because
# mongodb already in your projectManual spans
For SQL databases or when you need full control, use addSpan with type: 'db' directly.
SQL
because.addSpan('db', 'Fetch users', {
metadata: { table: 'users', queryType: 'sql' },
input: { query: 'SELECT * FROM users WHERE active = $1', params: [true] },
output: { count: 42 },
durationMs: 12
});NoSQL
because.addSpan('db', 'Fetch users', {
metadata: { collection: 'users', queryType: 'nosql' },
input: {
filter: { active: true },
projection: { name: 1, email: 1 },
sort: { createdAt: -1 }
},
output: { count: 42 },
durationMs: 8
});Metadata fields
| Field | Type | Description |
|---|---|---|
queryType | 'sql' | 'nosql' | Controls how the query is displayed in the dashboard |
table | string | Table name (SQL), shown in the span header |
collection | string | Collection name (NoSQL), shown in the span header |
Output convention
Pass summary stats (counts, affected rows, timings) rather than raw documents. Large result sets belong in your application logs, not in trace spans.
Types
import type { DbSpanOptions, DbSpanMetadata } from '@refactorlabs/because';type DbSpanMetadata = {
collection?: string;
table?: string;
queryType?: 'sql' | 'nosql';
};
type DbSpanOptions = {
metadata?: DbSpanMetadata;
input?: JsonObject;
output?: JsonObject;
durationMs?: number;
};