### GET Request Example with Parameters and Headers Source: https://nestlens-docs.vercel.app/docs/watchers/http-client This example shows how to make a GET request to an external API, including query parameters and custom headers. The 'X-API-Key' header is masked in the dashboard. ```typescript await firstValueFrom( this.httpService.get('https://api.example.com/users', { params: { page: 1, limit: 10 }, headers: { 'X-API-Key': 'secret' }, // Masked in dashboard }) ); ``` -------------------------------- ### Setup Redis Client with createClient Source: https://nestlens-docs.vercel.app/docs/watchers/redis Installs the 'redis' package and sets up a Redis client using createClient, connecting it to the specified URL. ```typescript // Install: npm install redis import { createClient } from 'redis'; @Module({ providers: [ { provide: 'REDIS_CLIENT', useFactory: async () => { const client = createClient({ url: 'redis://localhost:6379', }); await client.connect(); return client; }, }, ], }) export class AppModule {} ``` -------------------------------- ### Setup Express View Engine Source: https://nestlens-docs.vercel.app/docs/watchers/view Example of setting up the Express view engine with NestJS. Ensure you have installed the necessary package (e.g., `hbs`). ```typescript // Install: npm install hbs import { NestFactory } from '@nestjs/core'; import { NestExpressApplication } from '@nestjs/platform-express'; import { join } from 'path'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.setBaseViewsDir(join(__dirname, '..', 'views')); app.setViewEngine('hbs'); await app.listen(3000); } ``` -------------------------------- ### Install NestLens with Bun Source: https://nestlens-docs.vercel.app/docs/getting-started/installation Use this command to install NestLens using Bun. Ensure Node.js and Bun are installed and meet the version requirements. ```bash bun add nestlens ``` -------------------------------- ### Install SQLite Driver Source: https://nestlens-docs.vercel.app/docs/configuration/storage Install the 'better-sqlite3' package to enable SQLite storage. ```bash npm install better-sqlite3 ``` -------------------------------- ### Install TypeORM and @nestjs/typeorm Source: https://nestlens-docs.vercel.app/docs/integrations/typeorm Install the necessary packages for TypeORM integration. No additional setup is required for NestLens to detect TypeORM. ```bash npm install typeorm @nestjs/typeorm ``` -------------------------------- ### Install Bull or BullMQ Source: https://nestlens-docs.vercel.app/docs/integrations/bull-bullmq Install the necessary packages for either Bull or BullMQ. BullMQ is recommended for its advanced features. ```bash # For Bull npm install @nestjs/bull bull # For BullMQ (recommended) npm install @nestjs/bullmq bullmq ``` -------------------------------- ### Complete NestLens Configuration Example Source: https://nestlens-docs.vercel.app/docs/configuration/basic-config A comprehensive example demonstrating how to configure all basic NestLens options, including general settings, authorization, storage, pruning, rate limiting, watchers, and entry filtering. ```typescript import { Module } from '@nestjs/common'; import { NestLensModule } from 'nestlens'; @Module({ imports: [ NestLensModule.forRoot({ // General settings enabled: process.env.NODE_ENV !== 'production', path: '/nestlens', // Authorization authorization: { allowedEnvironments: ['development', 'local', 'test'], environmentVariable: 'NODE_ENV', allowedIps: ['127.0.0.1', '192.168.1.*'], }, // Storage (memory is default, no config needed) storage: { driver: 'sqlite', sqlite: { filename: '.cache/nestlens.db' }, }, // Pruning pruning: { enabled: true, maxAge: 24, // Keep data for 24 hours interval: 60, // Run pruning every 60 minutes }, // Rate limiting rateLimit: { windowMs: 60000, // 1 minute window maxRequests: 100, // 100 requests per minute }, // Watchers watchers: { request: { enabled: true, ignorePaths: ['/health', '/metrics'], captureHeaders: true, captureBody: true, captureResponse: true, captureUser: true, captureSession: true, }, query: { enabled: true, slowThreshold: 100, }, exception: true, log: { enabled: true, minLevel: 'warn', }, cache: true, event: true, httpClient: { enabled: true, ignoreHosts: ['localhost'], sensitiveHeaders: ['authorization', 'x-api-key'], sensitiveRequestParams: ['password', 'creditCard'], sensitiveResponseParams: ['accessToken', 'apiKey'], }, }, // Entry filtering filter: (entry) => { // Skip internal health checks if (entry.type === 'request' && entry.payload.path?.startsWith('/internal')) { return false; } return true; }, }), ], }) export class AppModule {} ``` -------------------------------- ### Install NestLens with npm Source: https://nestlens-docs.vercel.app/docs/getting-started/installation Use this command to install NestLens using npm. Ensure Node.js and npm are installed and meet the version requirements. ```bash npm install nestlens ``` -------------------------------- ### Simple GET Command Entry Source: https://nestlens-docs.vercel.app/docs/integrations/redis Example of entry data for a simple Redis GET command. It shows the command, arguments, duration, key pattern, status, and the string result. ```json { "command": "get", "args": ["session:abc123"], "duration": 1, "keyPattern": "session:abc123", "status": "success", "result": "{\"userId\": 456}" } ``` -------------------------------- ### Install NestLens with Yarn Source: https://nestlens-docs.vercel.app/docs/getting-started/installation Use this command to install NestLens using Yarn. Ensure Node.js and Yarn are installed and meet the version requirements. ```bash yarn add nestlens ``` -------------------------------- ### Verify NestLens Installation with npm Source: https://nestlens-docs.vercel.app/docs/getting-started/installation After installation, run this command to verify that NestLens has been successfully installed in your project using npm. ```bash npm ls nestlens ``` -------------------------------- ### Install NestLens with pnpm Source: https://nestlens-docs.vercel.app/docs/getting-started/installation Use this command to install NestLens using pnpm. Ensure Node.js and pnpm are installed and meet the version requirements. ```bash pnpm add nestlens ``` -------------------------------- ### SQLite Filename Examples Source: https://nestlens-docs.vercel.app/docs/configuration/storage Examples of how to specify the SQLite database filename, including default, absolute path, and environment-specific configurations. ```javascript // Default location (recommended) { filename: '.cache/nestlens.db' } // Absolute path { filename: '/var/lib/myapp/nestlens.db' } // Environment-specific { filename: `nestlens-${process.env.NODE_ENV}.db` } ``` -------------------------------- ### Queue-Specific Prefixes Example Source: https://nestlens-docs.vercel.app/docs/integrations/bull-bullmq Provides examples of using queue-specific prefixes for organizing jobs. ```plaintext // Queue: email 'email:welcome' 'email:reset-password' 'email:notification' // Queue: reports 'report:daily-sales' 'report:monthly-summary' ``` -------------------------------- ### TypeORM Integration Example Source: https://nestlens-docs.vercel.app/docs/watchers/query Demonstrates how entities and repositories work with the Query Watcher in a TypeORM setup. All queries made through TypeORM repositories are automatically tracked. ```typescript import { Entity, PrimaryGeneratedColumn, Column, } from 'typeorm'; @Entity() export class User { @PrimaryGeneratedColumn() id: number; @Column() name: string; } // All queries are automatically tracked import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; @Injectable() export class UserService { constructor( @InjectRepository(User) private userRepository: Repository, ) {} async findAll() { // This query will be tracked automatically return this.userRepository.find(); } async findOne(id: number) { // Slow queries will be flagged if duration > threshold return this.userRepository.findOne({ where: { id } }); } } ``` -------------------------------- ### Setup NestJS Schedule Module Source: https://nestlens-docs.vercel.app/docs/watchers/schedule Install and import the NestJS Schedule module in your AppModule. ```typescript // Install: npm install @nestjs/schedule import { ScheduleModule } from '@nestjs/schedule'; @Module({ imports: [ScheduleModule.forRoot()], }) export class AppModule {} ``` -------------------------------- ### Install Redis Package Source: https://nestlens-docs.vercel.app/docs/configuration/storage Install the ioredis package using npm. This is required for Redis storage. ```bash npm install ioredis ``` -------------------------------- ### Setup Bull Queue with NestJS Source: https://nestlens-docs.vercel.app/docs/watchers/job Configure and register a Bull queue within your NestJS application. Ensure `@nestjs/bull` and `bull` are installed. ```typescript // Install: npm install @nestjs/bull bull import { BullModule } from '@nestjs/bull'; @Module({ imports: [ BullModule.forRoot({ redis: { host: 'localhost', port: 6379, }, }), BullModule.registerQueue({ name: 'email', }), ], }) export class AppModule {} ``` -------------------------------- ### Example NestLens Redis Configuration Source: https://nestlens-docs.vercel.app/docs/integrations/redis Shows how to configure the Redis watcher within the NestLens module. This example enables the watcher and specifies commands to ignore and a custom maximum result size. ```typescript NestLensModule.forRoot({ watchers: { redis: { enabled: true, ignoreCommands: ['ping', 'info', 'select'], maxResultSize: 2048, }, }, }) ``` -------------------------------- ### Using fetch in Browser/Node.js Source: https://nestlens-docs.vercel.app/docs/configuration/pruning Examples demonstrating how to trigger manual pruning using the `fetch` API in both browser and Node.js environments. ```javascript // Prune with default maxAge const responseDefault = await fetch('http://localhost:3000/nestlens/__nestlens__/api/prune', { method: 'POST', }); const resultDefault = await responseDefault.json(); console.log(`Deleted ${resultDefault.deletedCount} entries (default maxAge)`); // Prune with custom maxAge const responseCustom = await fetch('http://localhost:3000/nestlens/__nestlens__/api/prune', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ maxAge: 12 }), }); const resultCustom = await responseCustom.json(); console.log(`Deleted ${resultCustom.deletedCount} entries (custom maxAge: 12 hours)`); ``` -------------------------------- ### Setup Prisma Service with Model Tracking Source: https://nestlens-docs.vercel.app/docs/integrations/prisma Example of a NestJS Prisma service that integrates with NestLens's ModelWatcher to enable model operation tracking. ```typescript // prisma.service.ts import { Injectable, OnModuleInit } from '@nestjs/common'; import { PrismaClient } from '@prisma/client'; import { ModelWatcher, NESTLENS_MODEL_SUBSCRIBER } from 'nestlens'; import { ModuleRef } from '@nestjs/core'; @Injectable() export class PrismaService extends PrismaClient implements OnModuleInit { constructor(private moduleRef: ModuleRef) { super(); } async onModuleInit() { await this.$connect(); // Get ModelWatcher from NestLens const modelWatcher = this.moduleRef.get(ModelWatcher, { strict: false }); if (modelWatcher) { modelWatcher.setupPrismaClient(this); } } } ``` -------------------------------- ### Setup BullMQ Queue with JobWatcher Source: https://nestlens-docs.vercel.app/docs/integrations/bull-bullmq Use `setupBullMQQueue` for the simplest approach to automatically create QueueEvents when integrating BullMQ with NestLens. ```typescript // Simplest approach - auto-creates QueueEvents await this.jobWatcher.setupBullMQQueue(this.emailQueue, 'email'); ``` -------------------------------- ### Prisma Integration Example Source: https://nestlens-docs.vercel.app/docs/watchers/query Shows how to register a Prisma client globally and how user queries are automatically tracked by the Query Watcher. Queries are identified by model and operation. ```typescript import { Injectable } from '@nestjs/common'; import { PrismaClient } from '@prisma/client'; @Injectable() export class PrismaService extends PrismaClient { constructor() { super(); // Make Prisma client globally available for NestLens (global as any).prisma = this; } } // Your queries are automatically tracked import { Injectable } from '@nestjs/common'; @Injectable() export class UserService { constructor(private prisma: PrismaService) {} async findAll() { // Tracked as: "User.findMany" return this.prisma.user.findMany(); } async create(data: CreateUserDto) { // Tracked as: "User.create" return this.prisma.user.create({ data }); } } ``` -------------------------------- ### Example TypeORM Configuration for NestLens Source: https://nestlens-docs.vercel.app/docs/integrations/typeorm Demonstrates how to configure NestLens watchers for TypeORM using `NestLensModule.forRoot`. This example enables both query and model watchers, setting a custom slow query threshold and specifying patterns and entities to ignore. ```typescript NestLensModule.forRoot({ watchers: { query: { enabled: true, slowThreshold: 200, ignorePatterns: [ /SELECT.*FROM.*migrations/, // Ignore migration queries /^SHOW/, // Ignore SHOW statements ], }, model: { enabled: true, ignoreEntities: ['Migration', 'Session'], captureData: false, // Don't capture sensitive entity data }, }, }) ``` -------------------------------- ### Session Management with Redis Source: https://nestlens-docs.vercel.app/docs/integrations/redis Example of using Redis for session management, storing session tokens with an expiration time. NestLens automatically tracks SETEX and GET commands and masks sensitive token keys. ```typescript @Injectable() export class SessionService { constructor( @InjectRedis() private redis: Redis ) {} async createSession(userId: number, token: string) { // Token key is automatically masked by NestLens await this.redis.setex( `session:token:${token}`, 86400, // 24 hours JSON.stringify({ userId, createdAt: new Date() }) ); } async getSession(token: string) { // Tracked and masked const data = await this.redis.get(`session:token:${token}`); return data ? JSON.parse(data) : null; } } ``` -------------------------------- ### Query Entry Payload Example (JSON) Source: https://nestlens-docs.vercel.app/docs/configuration/storage Example JSON structure for a query entry, including the SQL query, parameters, duration, and source of the query. ```json { "query": "SELECT * FROM users WHERE id = $1", "parameters": [123], "duration": 12, "slow": false, "source": "typeorm" } ``` -------------------------------- ### Example of Buffered Log Collection Source: https://nestlens-docs.vercel.app/docs/integrations/custom-integrations Demonstrates how to use the collect method to track a 'log' entry with level, message, and context. ```typescript await this.collector.collect('log', { level: 'info', message: 'User logged in', context: 'AuthService', }); ``` -------------------------------- ### Batch Status Examples Source: https://nestlens-docs.vercel.app/docs/watchers/batch These examples illustrate how batch statuses are determined based on processed and failed items. ```javascript { totalItems: 100, processed: 100, failed: 0 } // status: 'completed' ``` ```javascript { totalItems: 100, processed: 80, failed: 20 } // status: 'partial' ``` ```javascript { totalItems: 100, processed: 0, failed: 100 } // status: 'failed' ``` -------------------------------- ### IP Whitelisting Pattern Examples Source: https://nestlens-docs.vercel.app/docs/security/ip-whitelisting Examples of wildcard patterns for matching IP ranges, including Class C, Class B, and specific subnets. ```plaintext // Office network (Class C) '192.168.1.*' // 192.168.1.0 - 192.168.1.255 // Office networks (Class B) '192.168.*.*' // 192.168.0.0 - 192.168.255.255 // Data center '10.0.*.*' // 10.0.0.0 - 10.0.255.255 // Specific subnet '172.16.5.*' // 172.16.5.0 - 172.16.5.255 ``` -------------------------------- ### Manually Setup Prisma Client Watcher Source: https://nestlens-docs.vercel.app/docs/faq Alternatively, manually set up the Prisma client watcher using the ModelWatcher service. ```typescript const modelWatcher = this.moduleRef.get(ModelWatcher); modelWatcher.setupPrismaClient(this.prisma); ``` -------------------------------- ### NestLens Module Setup Source: https://nestlens-docs.vercel.app/docs Configure NestLens by importing NestLensModule.forRoot() in your AppModule. Ensure it's only enabled in non-production environments. ```typescript import { Module } from '@nestjs/common'; import { NestLensModule } from 'nestlens'; @Module({ imports: [ NestLensModule.forRoot({ enabled: process.env.NODE_ENV !== 'production', }), ], }) export class AppModule {} ``` -------------------------------- ### Structured Logging as an Alternative to NestLens Source: https://nestlens-docs.vercel.app/docs/security/production-usage Example of replacing NestLens with detailed structured logging for debugging requests in production. ```javascript // Replace NestLens with structured logging logger.debug('Request', { method: req.method, path: req.path, duration: requestDuration, statusCode: res.statusCode, }); ``` -------------------------------- ### Structured Logging Examples Source: https://nestlens-docs.vercel.app/docs/watchers/log Demonstrates different ways to structure log messages for improved searchability. Including identifiers in logs is recommended for better context. ```typescript // GOOD: Structured this.logger.log(`User ${userId} updated profile field: ${field}`); // BETTER: Include identifiers this.logger.log( `User ${userId} updated profile`, JSON.stringify({ field, oldValue, newValue }) ); // BAD: Vague this.logger.log('Profile updated'); ``` -------------------------------- ### Production Security Setup with Environment Variables Source: https://nestlens-docs.vercel.app/docs/security/access-control Configure NestLens for production using environment variables for dynamic control over enabled status, allowed environments, IP whitelists, and required roles. This setup ensures sensitive configurations are managed externally. ```typescript NestLensModule.forRoot({ // Only enable if needed in production enabled: process.env.NESTLENS_ENABLED === 'true', authorization: { // Strict environment control allowedEnvironments: process.env.NESTLENS_ENVIRONMENTS?.split(','), // IP whitelist for office/VPN allowedIps: process.env.NESTLENS_ALLOWED_IPS?.split(','), // Require authentication canAccess: async (req) => { const user = await authService.authenticate(req); return user ? { id: user.id, roles: user.roles, } : false; }, // Admin only requiredRoles: ['admin', 'super-admin'], }, }) ``` ```dotenv # .env.production NESTLENS_ENABLED=false NESTLENS_ENVIRONMENTS=production NESTLENS_ALLOWED_IPS=192.168.1.0/24,10.0.0.0/8 ``` -------------------------------- ### Request Entry Payload Example (JSON) Source: https://nestlens-docs.vercel.app/docs/configuration/storage Example JSON structure for a request entry, detailing HTTP method, URL, status code, duration, IP address, user agent, and controller action. ```json { "method": "GET", "url": "http://localhost:3000/api/users", "path": "/api/users", "statusCode": 200, "duration": 45, "ip": "127.0.0.1", "userAgent": "Mozilla/5.0...", "controllerAction": "UserController.findAll" } ``` -------------------------------- ### Setup Cache Module Source: https://nestlens-docs.vercel.app/docs/watchers/cache Configures the `@nestjs/cache-manager` module with specified TTL and maximum item count. ```typescript import { Module } from '@nestjs/common'; import { CacheModule } from '@nestjs/cache-manager'; @Module({ imports: [ // Install: npm install @nestjs/cache-manager cache-manager CacheModule.register({ ttl: 60, // seconds max: 100, // maximum number of items }), ], }) export class AppModule {} ``` -------------------------------- ### Configure NestLens for Debugging in Non-Production Source: https://nestlens-docs.vercel.app/docs/security/production-usage Configuration examples for enabling NestLens in a dedicated debug environment while ensuring it remains disabled in actual production. ```typescript // production.config.ts NestLensModule.forRoot({ enabled: false, // Never in production }) // production-debug.config.ts NestLensModule.forRoot({ enabled: true, // All security measures // Debug-specific configuration }) ``` -------------------------------- ### Multi-Channel Notifications Example Source: https://nestlens-docs.vercel.app/docs/watchers/notification Demonstrates sending multiple types of notifications to a user for a single event, such as an order shipment. This service utilizes the `NotificationService`. ```typescript @Injectable() export class UserNotificationService { constructor(private notifications: NotificationService) {} async notifyUserOrderShipped(userId: string, orderId: string) { const user = await this.userService.findOne(userId); // Send email notification await this.notifications.sendEmail({ to: user.email, subject: 'Your order has shipped!', body: `Order #${orderId} is on its way.`, }); // Send push notification await this.notifications.sendPush({ to: user.deviceToken, title: 'Order Shipped', message: `Order #${orderId} is on its way!`, }); // Send WebSocket notification await this.notifications.sendSocket({ to: userId, event: 'order.shipped', data: { orderId }, }); } } ``` -------------------------------- ### Prisma Query Entry Data Example Source: https://nestlens-docs.vercel.app/docs/integrations/prisma Illustrates the structure of data captured for Prisma query operations, including the query type, parameters, and execution duration. ```json { type: 'query', payload: { query: 'User.findMany', // Prisma operation parameters: [{ where: { ... } }], // Operation arguments duration: 12, // milliseconds slow: false, source: 'prisma', connection: undefined // Prisma doesn't expose connection name } } ``` -------------------------------- ### Configure NestLensModule with filterBatch Source: https://nestlens-docs.vercel.app/docs/advanced/filtering-entries Configure the NestLensModule with a `filterBatch` function to process entries in batches. This example demonstrates removing duplicate queries. ```typescript NestLensModule.forRoot({ filterBatch: (entries: Entry[]) => { // Remove duplicate queries const seenQueries = new Set(); return entries.filter(entry => { if (entry.type === 'query') { const key = entry.payload.query; if (seenQueries.has(key)) { return false; // Skip duplicate } seenQueries.add(key); } return true; }); }, }) ``` -------------------------------- ### Implement Custom Storage with StorageInterface Source: https://nestlens-docs.vercel.app/docs/api Provides an example of implementing the StorageInterface for custom data persistence, including CRUD, counting, statistics, and tag operations. ```typescript import { StorageInterface, Entry, STORAGE } from 'nestlens'; @Injectable() export class CustomStorage implements StorageInterface { // Basic CRUD async save(entry: Entry): Promise { /* ... */ } async saveBatch(entries: Entry[]): Promise { /* ... */ } async find(filter: EntryFilter): Promise { /* ... */ } async findById(id: number): Promise { /* ... */ } async findWithCursor(type: EntryType | undefined, params: CursorPaginationParams): Promise> { /* ... */ } // Counting & Sequence async count(type?: EntryType): Promise { /* ... */ } async getLatestSequence(type?: EntryType): Promise { /* ... */ } async hasEntriesAfter(sequence: number, type?: EntryType): Promise { /* ... */ } // Statistics async getStats(): Promise { /* ... */ } async getStorageStats(): Promise { /* ... */ } // Data Management async prune(before: Date): Promise { /* ... */ } async pruneByType(type: EntryType, before: Date): Promise { /* ... */ } async clear(): Promise { /* ... */ } async close(): Promise { /* ... */ } // Tag Operations async addTags(entryId: number, tags: string[]): Promise { /* ... */ } async removeTags(entryId: number, tags: string[]): Promise { /* ... */ } async getEntryTags(entryId: number): Promise { /* ... */ } async getAllTags(): Promise { /* ... */ } async findByTags(tags: string[], logic?: 'AND' | 'OR', limit?: number): Promise { /* ... */ } // Resolution async resolveEntry(id: number): Promise { /* ... */ } async unresolveEntry(id: number): Promise { /* ... */ } // Family Hash (Grouping) async updateFamilyHash(id: number, familyHash: string): Promise { /* ... */ } async findByFamilyHash(familyHash: string, limit?: number): Promise { /* ... */ } } // Register custom storage @Module({ providers: [ { provide: STORAGE, useClass: CustomStorage, }, ], }) ``` -------------------------------- ### Setup EventEmitter in NestJS Module Source: https://nestlens-docs.vercel.app/docs/watchers/event Basic setup for EventEmitter within a NestJS module. Ensure the '@nestjs/event-emitter' package is installed. ```typescript // Install: npm install @nestjs/event-emitter import { EventEmitterModule } from '@nestjs/event-emitter'; @Module({ imports: [EventEmitterModule.forRoot()], }) export class AppModule {} ``` -------------------------------- ### Register Bull Queue with NestLens JobWatcher Source: https://nestlens-docs.vercel.app/docs/watchers/job Inject the Bull queue and JobWatcher into a module and use `setupQueue` to start tracking jobs. ```typescript import { Injectable, OnModuleInit } from '@nestjs/common'; import { InjectQueue } from '@nestjs/bull'; import { Queue } from 'bull'; import { JobWatcher } from 'nestlens'; @Injectable() export class EmailModule implements OnModuleInit { constructor( @InjectQueue('email') private emailQueue: Queue, private jobWatcher: JobWatcher, ) {} onModuleInit() { // Setup tracking for this queue this.jobWatcher.setupQueue(this.emailQueue, 'email'); } } ``` -------------------------------- ### Setup NestJS Mailer Module Source: https://nestlens-docs.vercel.app/docs/watchers/mail Configure the `@nestjs-modules/mailer` package with transport details and default sender address. Ensure you have installed the necessary packages: `npm install @nestjs-modules/mailer nodemailer`. ```typescript // Install: npm install @nestjs-modules/mailer nodemailer import { MailerModule } from '@nestjs-modules/mailer'; @Module({ imports: [ MailerModule.forRoot({ transport: { host: 'smtp.example.com', port: 587, auth: { user: 'user@example.com', pass: 'password', }, }, defaults: { from: '"App" ', }, }), ], }) export class AppModule {} ``` -------------------------------- ### Setup CQRS Module in AppModule Source: https://nestlens-docs.vercel.app/docs/watchers/command Install the @nestjs/cqrs package and import CqrsModule into your AppModule. ```typescript // Install: npm install @nestjs/cqrs import { CqrsModule } from '@nestjs/cqrs'; @Module({ imports: [CqrsModule], }) export class AppModule {} ``` -------------------------------- ### Example of Immediate Exception Collection Source: https://nestlens-docs.vercel.app/docs/integrations/custom-integrations Shows how to use collectImmediate to track an 'exception' entry, capturing error details like name, message, and stack trace. ```typescript const entry = await this.collector.collectImmediate('exception', { name: 'PaymentError', message: 'Payment gateway timeout', stack: error.stack, }); ``` -------------------------------- ### Prisma Model Entry Data Example Source: https://nestlens-docs.vercel.app/docs/integrations/prisma Shows the data structure for model-level operations tracked by NestLens, including action, entity, duration, and record count. ```json { type: 'model', payload: { action: 'create', // find, create, update, delete, save entity: 'User', // Prisma model name source: 'prisma', duration: 18, recordCount: 1, data: { /* captured if captureData: true */ }, where: { id: 123 } } } ``` -------------------------------- ### Setup Prisma Client in PrismaService Source: https://nestlens-docs.vercel.app/docs/integrations/prisma Ensure the Prisma client is correctly set up within your `PrismaService` by calling `setupPrismaClient` if a `ModelWatcher` is available. This is part of troubleshooting missing queries. ```typescript // In PrismaService const modelWatcher = this.moduleRef.get(ModelWatcher); if (modelWatcher) { modelWatcher.setupPrismaClient(this); } ``` -------------------------------- ### Verify TypeORM Installation Source: https://nestlens-docs.vercel.app/docs/faq Check if TypeORM is installed in your project using npm. ```bash npm list typeorm ``` -------------------------------- ### Prisma Client Setup Source: https://nestlens-docs.vercel.app/docs/watchers/model Set up a PrismaService that extends PrismaClient and implements OnModuleInit. This service should inject and utilize the ModelWatcher to set up Prisma tracking upon module initialization. ```typescript import { Injectable, OnModuleInit } from '@nestjs/common'; import { PrismaClient } from '@prisma/client'; import { ModelWatcher } from 'nestlens'; @Injectable() export class PrismaService extends PrismaClient implements OnModuleInit { constructor(private modelWatcher: ModelWatcher) { super(); } async onModuleInit() { await this.$connect(); // Setup Prisma tracking this.modelWatcher.setupPrismaClient(this); } } ``` -------------------------------- ### Environment File Examples for IP Whitelisting Source: https://nestlens-docs.vercel.app/docs/security/ip-whitelisting Define IP ranges and specific IPs in .env files for different environments. Supports wildcard matching for IP ranges. ```dotenv # .env.development NESTLENS_ALLOWED_IPS=127.0.0.1,localhost # .env.staging NESTLENS_ALLOWED_IPS=192.168.1.*,10.0.0.* # .env.production NESTLENS_ALLOWED_IPS=192.168.1.100,192.168.1.101 ``` -------------------------------- ### Verify Prisma Global Instance in Console Source: https://nestlens-docs.vercel.app/docs/integrations/prisma Troubleshoot queries not appearing by verifying if the Prisma global instance is correctly set up and accessible. Use this console log in your application. ```javascript // Verify in console console.log('Prisma global:', (global as any).prisma); ``` -------------------------------- ### Set Up Error Monitoring Alerts Source: https://nestlens-docs.vercel.app/docs/watchers/exception Utilize the Exception Watcher data to implement monitoring and alerting for high error rates. This example checks for more than 100 exceptions in the last 5 minutes. ```javascript // Example: Check for error rate spike const recentExceptions = await getExceptions({ since: Date.now() - 5 * 60 * 1000, // Last 5 minutes }); if (recentExceptions.length > 100) { // Alert: High error rate! await sendAlert('High exception rate detected'); } ``` -------------------------------- ### N+1 Query Detection Example Source: https://nestlens-docs.vercel.app/docs/watchers/graphql Example structure of a potential N+1 query warning detected by the GraphQL Watcher. This helps identify performance bottlenecks. ```json { "potentialN1": [ { "field": "posts", "parentType": "User", "count": 50, "suggestion": "Consider using DataLoader for User.posts field" } ] } ``` -------------------------------- ### Implement Progressive Rate Limits by Environment Source: https://nestlens-docs.vercel.app/docs/configuration/rate-limiting Configure rate limits dynamically based on the deployment environment (e.g., development, staging, production). This allows for more lenient limits in non-production environments and stricter limits in production. ```javascript const limits = { development: false, test: false, staging: { windowMs: 60000, maxRequests: 200 }, production: { windowMs: 60000, maxRequests: 100 }, }; NestLensModule.forRoot({ rateLimit: limits[process.env.NODE_ENV], }); ``` -------------------------------- ### Exception Entry Payload Example (JSON) Source: https://nestlens-docs.vercel.app/docs/configuration/storage Example JSON structure for an exception entry, containing exception name, message, stack trace, and an optional error code. ```json { "name": "BadRequestException", "message": "Invalid input", "stack": "Error: Invalid input\n at UserController.create...", "code": 400 } ``` -------------------------------- ### Sensitive Data Masking Example Source: https://nestlens-docs.vercel.app/docs/watchers/model When `captureData` is set to true, sensitive fields like passwords and tokens are automatically masked in the dashboard. This example shows a user being saved with a masked password. ```javascript // With captureData: true const user = await userRepository.save({ email: 'user@example.com', password: 'secret123', // Shown as: '***MASKED***' name: 'John Doe', // Shown normally }); ``` -------------------------------- ### Custom Cache Keys Example Source: https://nestlens-docs.vercel.app/docs/watchers/cache Illustrates creating custom cache keys based on dynamic parameters like category and page number to manage cache entries effectively. ```typescript @Injectable() export class ProductService { async getProductsByCategory(category: string, page: number) { const cacheKey = `products:${category}:page:${page}`; // Check cache const cached = await this.cacheManager.get(cacheKey); if (cached) return cached; // Fetch and cache const products = await this.fetchProducts(category, page); await this.cacheManager.set(cacheKey, products, 600); return products; } } ``` -------------------------------- ### Redis Key Structure Examples Source: https://nestlens-docs.vercel.app/docs/configuration/storage Illustrates the key naming conventions used by NestLens within Redis for storing different types of data. Understanding this structure can aid in debugging and monitoring. ```plaintext {prefix}entries:{id} # Entry data (Hash) {prefix}entries:all # All entry IDs (Sorted Set) {prefix}entries:type:{type} # Entry IDs by type (Sorted Set) {prefix}entries:request:{id} # Entry IDs by request (Set) {prefix}tags:{entryId} # Tags for entry (Set) {prefix}tags:index:{tag} # Entry IDs by tag (Set) {prefix}family:{hash} # Entry IDs by family hash (Set) ``` -------------------------------- ### Implement Database Connection Pooling Source: https://nestlens-docs.vercel.app/docs/advanced/extending-storage Optimize database performance by implementing connection pooling. This example configures a pool with a maximum of 20 connections, a minimum of 5, and an idle timeout of 30 seconds. ```typescript private pool = new Pool({ max: 20, min: 5, idleTimeoutMillis: 30000, }); ``` -------------------------------- ### Common Cron Patterns Source: https://nestlens-docs.vercel.app/docs/watchers/schedule Examples of common cron patterns used with the @Cron decorator. ```typescript // Every minute @Cron('* * * * *') // Every hour at minute 0 @Cron('0 * * * *') // Every day at 2:30 AM @Cron('30 2 * * *') // Every Monday at 9 AM @Cron('0 9 * * 1') // First day of every month at midnight @Cron('0 0 1 * *') ``` -------------------------------- ### NestLens Production Configuration with Redis Source: https://nestlens-docs.vercel.app/docs/configuration/storage Configure NestLens for production using Redis for storage. This example also shows how to enable the module based on an environment variable and configure data pruning. ```typescript NestLensModule.forRoot({ enabled: process.env.NESTLENS_ENABLED === 'true', storage: { driver: 'redis', redis: { url: process.env.REDIS_URL }, }, pruning: { enabled: true, maxAge: 24, }, }) ``` -------------------------------- ### Example Filter Badges Source: https://nestlens-docs.vercel.app/docs/dashboard/filtering Active filters are displayed as badges. Click the 'x' to remove individual filters. ```text Status: 500 × Method: POST × Slow: true × ``` -------------------------------- ### Setup HTTP Module in NestJS Source: https://nestlens-docs.vercel.app/docs/watchers/http-client Import and include the HttpModule in your AppModule to enable HTTP request capabilities. ```typescript import { HttpModule } from '@nestjs/axios'; @Module({ imports: [HttpModule], }) export class AppModule {} ``` -------------------------------- ### Configure TypeORM in AppModule Source: https://nestlens-docs.vercel.app/docs/integrations/typeorm Standard TypeORM setup within your AppModule. Ensure NestLensModule.forRoot() is included for auto-detection. ```typescript // In your app.module.ts - Standard TypeORM setup import { TypeOrmModule } from '@nestjs/typeorm'; @Module({ imports: [ TypeOrmModule.forRoot({ type: 'postgres', host: 'localhost', port: 5432, username: 'user', password: 'password', database: 'mydb', entities: [User, Product], synchronize: false, }), NestLensModule.forRoot(), // NestLens auto-detects TypeORM ], }) export class AppModule {} ``` -------------------------------- ### Good vs. Bad Redis Key Patterns Source: https://nestlens-docs.vercel.app/docs/integrations/redis Illustrates effective and ineffective key naming conventions for Redis to improve debugging and organization. ```text // Good 'user:123:profile' 'cache:product:456' 'session:token:abc' // Bad 'u123' 'p456' 'sabc' ``` -------------------------------- ### Configure SQLite Storage Source: https://nestlens-docs.vercel.app/docs/faq Configure NestLens to use SQLite for persistent storage. Requires installing the `better-sqlite3` package. ```typescript // SQLite (requires: npm install better-sqlite3) NestLensModule.forRoot({ storage: { driver: 'sqlite', sqlite: { filename: '/var/data/nestlens.db' }, }, }) ``` -------------------------------- ### Dynamic IP Whitelisting with Database Source: https://nestlens-docs.vercel.app/docs/security/ip-whitelisting Implement dynamic IP management by checking client IPs against a database within the 'canAccess' function. This example includes logging blocked attempts. ```typescript NestLensModule.forRoot({ authorization: { canAccess: async (req) => { const clientIp = req.ip; // Check against database const isAllowed = await ipWhitelistService.isAllowed(clientIp); if (isAllowed) { return true; } // Log blocked attempt await auditLog.log({ action: 'blocked_ip', ip: clientIp, timestamp: new Date(), }); return false; }, }, }) ``` -------------------------------- ### Access NestLens Dashboard Source: https://nestlens-docs.vercel.app/docs/getting-started/quick-start After starting your NestJS application, access the NestLens dashboard by navigating to http://localhost:3000/nestlens in your browser. ```plaintext http://localhost:3000/nestlens ``` -------------------------------- ### Elasticsearch Storage Implementation Source: https://nestlens-docs.vercel.app/docs/advanced/extending-storage An example of a custom storage implementation using Elasticsearch. This class connects to Elasticsearch, initializes the index if it doesn't exist, and provides methods for saving and finding entries. ```typescript // elasticsearch.storage.ts import { Injectable } from '@nestjs/common'; import { Client } from '@elastic/elasticsearch'; import { StorageInterface, Entry } from 'nestlens'; @Injectable() export class ElasticsearchStorage implements StorageInterface { private client: Client; private index = 'nestlens-entries'; constructor() { this.client = new Client({ node: process.env.ELASTICSEARCH_URL, }); } async initialize(): Promise { const exists = await this.client.indices.exists({ index: this.index, }); if (!exists) { await this.client.indices.create({ index: this.index, body: { mappings: { properties: { type: { type: 'keyword' }, payload: { type: 'object', enabled: true }, requestId: { type: 'keyword' }, familyHash: { type: 'keyword' }, createdAt: { type: 'date' }, tags: { type: 'keyword' }, }, }, }, }); } } async save(entry: Entry): Promise { const result = await this.client.index({ index: this.index, body: { ...entry, createdAt: new Date().toISOString(), }, }); return { ...entry, id: result._id, createdAt: new Date().toISOString(), }; } async find(filter: EntryFilter): Promise { const must: any[] = []; if (filter.type) { must.push({ term: { type: filter.type } }); } if (filter.requestId) { must.push({ term: { requestId: filter.requestId } }); } if (filter.from || filter.to) { const range: any = {}; if (filter.from) range.gte = filter.from; if (filter.to) range.lte = filter.to; must.push({ range: { createdAt: range } }); } const result = await this.client.search({ index: this.index, body: { query: { bool: { must }, }, sort: [{ createdAt: 'desc' }], size: filter.limit || 100, from: filter.offset || 0, }, }); return result.hits.hits.map(hit => ({ id: hit._id, ...hit._source, } as Entry)); } // Implement remaining methods... } ``` -------------------------------- ### Emit Domain Events Source: https://nestlens-docs.vercel.app/docs/watchers/event Examples of emitting domain-specific events for user and order domains, following a consistent naming convention. ```typescript // User domain this.eventEmitter.emit('user.registered', userData); this.eventEmitter.emit('user.verified', { userId }); this.eventEmitter.emit('user.deleted', { userId }); // Order domain this.eventEmitter.emit('order.placed', orderData); this.eventEmitter.emit('order.shipped', { orderId }); this.eventEmitter.emit('order.delivered', { orderId }); ``` -------------------------------- ### IP Whitelist Service Implementation Source: https://nestlens-docs.vercel.app/docs/security/ip-whitelisting A sample implementation of an 'IpWhitelistService' using TypeORM repositories to manage allowed IPs in a database. Includes methods to check, add, and remove IPs. ```typescript @Injectable() export class IpWhitelistService { constructor( @InjectRepository(AllowedIp) private ipRepository: Repository, ) {} async isAllowed(ip: string): Promise { const allowed = await this.ipRepository.findOne({ where: { ip }, cache: true, }); return !!allowed; } async addIp(ip: string): Promise { await this.ipRepository.insert({ ip }); } async removeIp(ip: string): Promise { await this.ipRepository.delete({ ip }); } } ``` -------------------------------- ### Apply Entry Filtering Source: https://nestlens-docs.vercel.app/docs/faq Reduce the amount of data collected by applying a filter function. This example shows how to track only exceptions. ```javascript filter: (entry) => { // Only track errors return entry.type === 'exception'; } ``` -------------------------------- ### Configure Global Prisma Instance for NestLens Source: https://nestlens-docs.vercel.app/docs/integrations/prisma Set up a global Prisma instance in your `PrismaService` to be detected by NestLens. This ensures that all Prisma operations are accessible for monitoring. ```typescript import { Injectable, OnModuleInit } from '@nestjs/common'; import { PrismaClient } from '@prisma/client'; @Injectable() export class PrismaService extends PrismaClient implements OnModuleInit { async onModuleInit() { await this.$connect(); // Make Prisma client globally available for NestLens (global as any).prisma = this; } } ``` -------------------------------- ### Implement Authentication for Production Source: https://nestlens-docs.vercel.app/docs/security/access-control Secure your NestLens instance in production by implementing strict authentication. This example shows how to conditionally enable NestLens and define a custom access check using an authentication service. ```typescript // BAD - No authentication NestLensModule.forRoot({ enabled: true, authorization: { allowedEnvironments: null, // Allows all }, }) // GOOD - Strict authentication NestLensModule.forRoot({ enabled: process.env.NODE_ENV !== 'production', authorization: { canAccess: async (req) => { return await authService.isAdmin(req); }, }, }) ``` -------------------------------- ### Wildcard IP Pattern Examples Source: https://nestlens-docs.vercel.app/docs/security/ip-whitelisting Illustrates correct and incorrect usage of wildcard patterns for IP whitelisting. Wildcards match single segments, and CIDR notation should not be used with wildcards. ```typescript allowedIps: ['192.168.1.*'] // ✓ allowedIps: ['192.168.*.*'] // ✓ ``` ```typescript allowedIps: ['192.168.1.0/24'] // ✗ Use custom function allowedIps: ['192.168.1.%'] // ✗ Use * ``` -------------------------------- ### Using Appropriate Log Levels Source: https://nestlens-docs.vercel.app/docs/watchers/log Shows how to use debug logs in development and configure production log levels to ignore debug messages. Set `minLevel` in `NestLensModule.forRoot` to control log verbosity. ```typescript // Development this.logger.debug(`Cache key: ${key}`); // Production (won't be captured if minLevel is 'log') NestLensModule.forRoot({ watchers: { log: { minLevel: 'log', // debug logs are ignored }, }, }) ``` -------------------------------- ### Emit 'order.created' and 'order.cancelled' Events Source: https://nestlens-docs.vercel.app/docs/watchers/event Example of emitting custom events 'order.created' and 'order.cancelled' with associated payloads using EventEmitter2 in a service. ```typescript import { Injectable } from '@nestjs/common'; import { EventEmitter2 } from '@nestjs/event-emitter'; @Injectable() export class OrderService { constructor(private eventEmitter: EventEmitter2) {} async createOrder(data: CreateOrderDto) { const order = await this.orderRepository.save(data); // Emit event (automatically tracked) this.eventEmitter.emit('order.created', { orderId: order.id, userId: order.userId, total: order.total, }); return order; } async cancelOrder(id: string) { const order = await this.orderRepository.update(id, { status: 'cancelled' }); // Emit cancellation event this.eventEmitter.emit('order.cancelled', { orderId: id }); return order; } } ``` -------------------------------- ### Basic Filter Function Example Source: https://nestlens-docs.vercel.app/docs/advanced/filtering-entries Use the `filter` function to determine if an entry should be collected. Return `true` to collect, `false` to skip. ```typescript NestLensModule.forRoot({ filter: (entry: Entry) => { // Return true to collect, false to skip return shouldCollectEntry(entry); }, }) ``` -------------------------------- ### Handle Large Payloads with Compression Source: https://nestlens-docs.vercel.app/docs/advanced/extending-storage Manage large data payloads by compressing them before saving. This example compresses payloads exceeding 100KB. ```typescript async save(entry: Entry): Promise { let payload = entry.payload; // Compress large payloads const size = JSON.stringify(payload).length; if (size > 100000) { // 100KB payload = await this.compress(payload); } return this.db.save({ ...entry, payload }); } ``` -------------------------------- ### Configure Connection Pooling Source: https://nestlens-docs.vercel.app/docs/advanced/performance Implement connection pooling for custom storage backends to manage database connections efficiently. Adjust 'max', 'min', and 'idleTimeoutMillis' for optimal performance. ```javascript // For custom storage backends const pool = new Pool({ max: 20, // Maximum connections min: 5, // Minimum connections idleTimeoutMillis: 30000, }); ``` -------------------------------- ### TypeORM Subscriber Setup Source: https://nestlens-docs.vercel.app/docs/watchers/model Configure a TypeORM entity subscriber to integrate with NestLens. This involves implementing the EntitySubscriberInterface and providing it as a NESTLENS_MODEL_SUBSCRIBER in your AppModule. ```typescript import { NESTLENS_MODEL_SUBSCRIBER } from 'nestlens'; import { EntitySubscriberInterface, EventSubscriber } from 'typeorm'; @EventSubscriber() export class NestLensEntitySubscriber implements EntitySubscriberInterface { // Implement TypeORM subscriber methods } @Module({ providers: [ { provide: NESTLENS_MODEL_SUBSCRIBER, useClass: NestLensEntitySubscriber, }, ], }) export class AppModule {} ```