Because
Node.jsSDK

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 project

Manual 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

FieldTypeDescription
queryType'sql' | 'nosql'Controls how the query is displayed in the dashboard
tablestringTable name (SQL), shown in the span header
collectionstringCollection 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;
};

On this page