Skip to content

Debug Mode

Enable query logging for development and debugging.

Basic Usage

typescript
import { setDebug } from '@codician-team/monch';

// Enable debug mode
setDebug(true);

// Now all queries are logged
await Users.findOne({ email: 'alice@example.com' });
// [Monch] findOne users { email: 'alice@example.com' }

await Users.updateOne(
  { _id: userId },
  { $set: { role: 'admin' } }
);
// [Monch] updateOne users { _id: ObjectId(...) } { $set: { role: 'admin' } }

Disable Debug Mode

typescript
setDebug(false);

Custom Logger

Provide a custom logging function:

typescript
setDebug({
  enabled: true,
  logger: (operation, collection, ...args) => {
    console.log(`[DB] ${operation} on ${collection}`, JSON.stringify(args));
  },
});

Logger Signature

typescript
type DebugLogger = (
  operation: string,    // 'find', 'findOne', 'insertOne', etc.
  collection: string,   // Collection name
  ...args: any[]        // Operation arguments (filter, update, options, etc.)
) => void;

What Gets Logged

All collection operations are logged:

OperationLog Format
find[Monch] find {collection} {filter}
findOne[Monch] findOne {collection} {filter}
findById[Monch] findById {collection} {id}
insertOne[Monch] insertOne {collection} {document}
insertMany[Monch] insertMany {collection} {count} documents
updateOne[Monch] updateOne {collection} {filter} {update}
updateMany[Monch] updateMany {collection} {filter} {update}
deleteOne[Monch] deleteOne {collection} {filter}
deleteMany[Monch] deleteMany {collection} {filter}
count[Monch] count {collection} {filter}
aggregate[Monch] aggregate {collection} {pipeline}

Environment-Based Debug

Enable debug mode based on environment:

typescript
import { setDebug } from '@codician-team/monch';

// Enable in development only
setDebug(process.env.NODE_ENV === 'development');

// Or use a dedicated env var
setDebug(process.env.MONCH_DEBUG === 'true');

Integration with Logging Libraries

Winston

typescript
import winston from 'winston';
import { setDebug } from '@codician-team/monch';

const logger = winston.createLogger({
  level: 'debug',
  format: winston.format.json(),
  transports: [new winston.transports.Console()],
});

setDebug({
  enabled: true,
  logger: (operation, collection, ...args) => {
    logger.debug('Database operation', {
      operation,
      collection,
      args,
    });
  },
});

Pino

typescript
import pino from 'pino';
import { setDebug } from '@codician-team/monch';

const logger = pino({ level: 'debug' });

setDebug({
  enabled: true,
  logger: (operation, collection, ...args) => {
    logger.debug({ operation, collection, args }, 'db query');
  },
});

Debugging Performance

Combine debug mode with timing:

typescript
setDebug({
  enabled: true,
  logger: (operation, collection, ...args) => {
    const start = performance.now();
    console.log(`[Monch] Starting ${operation} on ${collection}`);

    // Note: This logs the start, not the actual duration
    // For actual timing, you'd need to wrap operations
  },
});

For actual query timing, wrap operations:

typescript
async function timedQuery<T>(
  name: string,
  fn: () => Promise<T>
): Promise<T> {
  const start = performance.now();
  try {
    return await fn();
  } finally {
    const duration = performance.now() - start;
    console.log(`[Query] ${name} took ${duration.toFixed(2)}ms`);
  }
}

// Usage
const user = await timedQuery('findUser', () =>
  Users.findOne({ email: 'alice@example.com' })
);

Security Considerations

Sensitive Data

Debug logs may contain sensitive information (passwords, tokens, personal data). Never enable debug mode in production or ensure your logger filters sensitive fields.

typescript
setDebug({
  enabled: process.env.NODE_ENV === 'development',
  logger: (operation, collection, ...args) => {
    // Filter sensitive fields
    const sanitized = args.map(arg => {
      if (typeof arg === 'object' && arg !== null) {
        const { password, token, secret, ...safe } = arg;
        return safe;
      }
      return arg;
    });
    console.log(`[Monch] ${operation} ${collection}`, sanitized);
  },
});

Conditional Debugging

Debug specific collections or operations:

typescript
setDebug({
  enabled: true,
  logger: (operation, collection, ...args) => {
    // Only log specific collections
    if (['users', 'orders'].includes(collection)) {
      console.log(`[Monch] ${operation} ${collection}`, ...args);
    }

    // Only log slow operations (after measuring)
    // Or only log mutations
    if (['insertOne', 'updateOne', 'deleteOne'].includes(operation)) {
      console.log(`[Monch] ${operation} ${collection}`, ...args);
    }
  },
});

Released under the MIT License.