### Run Example NestJS App Source: https://github.com/mogretici/nestlens/blob/main/CLAUDE.md Start the example NestJS application that integrates with NestLens. ```bash cd example && npm start ``` -------------------------------- ### Start Development Servers Source: https://github.com/mogretici/nestlens/blob/main/CONTRIBUTING.md Launch the example application with NestLens integrated and the dashboard in development mode. ```bash # Start the example app with NestLens cd example && npm run start:dev # Start the dashboard in dev mode cd dashboard && npm run dev ``` -------------------------------- ### Setup View Engine with Express Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/view.md Example of setting up the Handlebars view engine for a NestJS Express application. Ensure the view engine is installed and configured before proceeding. ```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 Redis Client Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/configuration/storage.md Install the ioredis package to enable Redis storage. ```bash npm install ioredis ``` -------------------------------- ### Install Bull or BullMQ Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/bull-bullmq.md 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 ``` -------------------------------- ### Setup Redis Client with 'redis' package Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/redis.md Installs and configures a Redis client using the 'redis' package, connecting to a local Redis instance. This client can then be provided to NestLens. ```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 {} ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/mogretici/nestlens/blob/main/docs/README.md Run this command in your project's root directory to install all necessary npm packages. ```bash npm install ``` -------------------------------- ### Start Local Development Server Source: https://github.com/mogretici/nestlens/blob/main/docs/README.md Starts a local development server for live previewing changes. The server automatically reloads most modifications. ```bash npm start ``` -------------------------------- ### Complete NestLens Configuration Example Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/configuration/basic-config.md A comprehensive example demonstrating how to configure NestLens with various 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 SQLite Driver Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/configuration/storage.md Install the 'better-sqlite3' package required for SQLite storage. ```bash npm install better-sqlite3 ``` -------------------------------- ### Simple GET Command Entry Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/redis.md Example of a logged entry for a Redis GET command. Shows the command, arguments, duration, key pattern, status, and the retrieved string result. ```typescript { command: 'get', args: ['session:abc123'], duration: 1, keyPattern: 'session:abc123', status: 'success', result: '{"userId": 456}' } ``` -------------------------------- ### Manual Prisma Client Setup Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/faq.md Alternatively, use manual setup to connect the Prisma client with NestLens's ModelWatcher. ```typescript const modelWatcher = this.moduleRef.get(ModelWatcher); modelWatcher.setupPrismaClient(this.prisma); ``` -------------------------------- ### Install NestLens Source: https://github.com/mogretici/nestlens/blob/main/README.md Install the NestLens package using npm. This command should be run in your project's root directory. ```bash npm install nestlens ``` -------------------------------- ### Make a GET Request Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/http-client.md Example of making a GET request to an external API with query parameters and custom headers. The response is processed using `firstValueFrom`. ```typescript await firstValueFrom( this.httpService.get('https://api.example.com/users', { params: { page: 1, limit: 10 }, headers: { 'X-API-Key': 'secret' }, // Masked in dashboard }) ); ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/mogretici/nestlens/blob/main/example/README.md Installs all the necessary packages for the NestJS project. ```bash $ npm install ``` -------------------------------- ### Verify NestLens Installation Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/getting-started/installation.md Run this command after installation to confirm that NestLens has been successfully added to your project's dependencies. ```bash npm ls nestlens ``` -------------------------------- ### Clone Repository and Install Dependencies Source: https://github.com/mogretici/nestlens/blob/main/CONTRIBUTING.md Clone your fork of the NestLens repository and install project dependencies, including those for the dashboard. ```bash git clone https://github.com/YOUR_USERNAME/nestlens.git cd nestlens npm install cd dashboard && npm install && cd .. ``` -------------------------------- ### Run Dashboard Development Server Source: https://github.com/mogretici/nestlens/blob/main/CLAUDE.md Start the React dashboard development server using Vite. ```bash cd dashboard && npm run dev ``` -------------------------------- ### Stack Trace Example Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/exception.md This is an example of a stack trace that appears for each exception, showing the sequence of function calls leading to the error. ```text Error: User not found at UserService.findOne (user.service.ts:45:13) at UserController.getUser (user.controller.ts:23:32) at ... ``` -------------------------------- ### NestLens Redis Watcher Configuration Example Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/redis.md Provides an example of how to configure the Redis watcher within the NestLens module. This includes enabling the watcher, listing commands to ignore, and setting a custom maximum result size. ```typescript NestLensModule.forRoot({ watchers: { redis: { enabled: true, ignoreCommands: ['ping', 'info', 'select'], maxResultSize: 2048, // 2KB }, }, }) ``` -------------------------------- ### Setup CQRS Module Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/command.md Install the @nestjs/cqrs package and import CqrsModule into your AppModule to enable CQRS functionality. ```typescript // Install: npm install @nestjs/cqrs import { CqrsModule } from '@nestjs/cqrs'; @Module({ imports: [CqrsModule], }) export class AppModule {} ``` -------------------------------- ### Cache Module Setup Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/cache.md Set up the CacheModule in your NestJS application. This example shows basic configuration for TTL and maximum items. ```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 {} ``` -------------------------------- ### Install TypeORM and @nestjs/typeorm Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/typeorm.md Install the necessary packages for TypeORM integration with NestJS. This is a prerequisite for NestLens to auto-detect TypeORM. ```bash npm install typeorm @nestjs/typeorm ``` -------------------------------- ### IP Pattern Examples Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/security/ip-whitelisting.md Examples of wildcard patterns for matching IP ranges, including Class C, Class B, and specific subnets. ```typescript // 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 ``` -------------------------------- ### Run NestJS Project Source: https://github.com/mogretici/nestlens/blob/main/example/README.md Commands to start the NestJS application in development, watch mode, or production. ```bash # development $ npm run start # watch mode $ npm run start:dev # production mode $ npm run start:prod ``` -------------------------------- ### Environment File Examples for IP Whitelisting Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/security/ip-whitelisting.md Define IP whitelisting rules in .env files for different environments. Supports CIDR notation and specific IPs. ```bash # .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 ``` -------------------------------- ### Setup BullMQ Queue with Job Watcher Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/bull-bullmq.md Use `setupBullMQQueue` for the simplest approach to auto-create QueueEvents with BullMQ. This method ensures proper integration with NestLens. ```typescript // Simplest approach - auto-creates QueueEvents await this.jobWatcher.setupBullMQQueue(this.emailQueue, 'email'); ``` -------------------------------- ### Generate Test Data for Example App Source: https://github.com/mogretici/nestlens/blob/main/CLAUDE.md Generate test data for the example NestJS app using a provided script. ```bash cd example && npm run seed ``` -------------------------------- ### Recommended Production Setup for NestLens Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/security/access-control.md Configure NestLens for production with environment variables for dynamic settings. This setup includes enabling/disabling the module, strict environment control, IP whitelisting, and role-based access. ```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'], }, }) ``` -------------------------------- ### N+1 Query Detection Example Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/graphql.md An example of the structure for an N+1 query warning. Configure N+1 detection by setting 'detectN1Queries' and 'n1Threshold' in the NestLensModule configuration. ```typescript // Example: N+1 warning { potentialN1: [{ field: 'posts', parentType: 'User', count: 50, suggestion: 'Consider using DataLoader for User.posts field' }] } ``` ```typescript NestLensModule.forRoot({ watchers: { graphql: { detectN1Queries: true, n1Threshold: 10, // Warn when a resolver is called 10+ times }, }, }) ``` -------------------------------- ### Deploy NestJS Application with Mau Source: https://github.com/mogretici/nestlens/blob/main/example/README.md Installs the Mau CLI and deploys the NestJS application to AWS. ```bash $ npm install -g @nestjs/mau $ mau deploy ``` -------------------------------- ### Implement Custom Storage with StorageInterface Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/faq.md To use a different database, implement the `StorageInterface`. This example shows the basic structure for a custom storage provider. ```typescript import { StorageInterface, STORAGE } from 'nestlens'; @Injectable() export class MyCustomStorage implements StorageInterface { // Implement required methods } @Module({ providers: [ { provide: STORAGE, useClass: MyCustomStorage, }, ], }) ``` -------------------------------- ### Error Monitoring Alert Example Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/exception.md Use the `getExceptions` function to retrieve recent exceptions and set up alerts for high error rates. This example checks for more than 100 exceptions in the last 5 minutes. ```typescript // 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'); } ``` -------------------------------- ### GraphQL Watcher Integration Example Source: https://github.com/mogretici/nestlens/blob/main/CLAUDE.md Demonstrates how to manually integrate the GraphQL watcher with Apollo Server by adding it as a plugin. ```typescript // NestLensModule must be in GraphQLModule.forRootAsync imports // GraphQLWatcher must be injected and added as Apollo plugin GraphQLModule.forRootAsync({ imports: [NestLensModule.forRoot({ watchers: { graphql: true } })], inject: [GraphQLWatcher], useFactory: (graphqlWatcher: GraphQLWatcher) => ({ plugins: [graphqlWatcher.getPlugin()], }), }); ``` -------------------------------- ### SQLite Filename Examples Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/configuration/storage.md Illustrates different ways to specify the SQLite database filename, including default, absolute paths, and environment-specific configurations. ```typescript // Default location (recommended) { filename: '.cache/nestlens.db' } // Absolute path { filename: '/var/lib/myapp/nestlens.db' } // Environment-specific { filename: `nestlens-${process.env.NODE_ENV}.db` } ``` -------------------------------- ### URL-Driven Filters Example Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/dashboard/filtering.md Shows how filters are represented in the URL query string, enabling bookmarking, sharing, and browser navigation. ```url /nestlens/requests?status=500&method=POST&path=/api/users ``` -------------------------------- ### Multi-Channel Notification Example Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/notification.md Example of a service that uses the `NotificationService` to send notifications across multiple channels (email, push, WebSocket) to a user. Each send operation will be tracked by NestLens. ```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 }, }); } } ``` -------------------------------- ### Structured Logging Examples Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/log.md Use structured log messages for better searchability. Include identifiers for more context. ```typescript // GOOD: Structured this.logger.log(`User ${userId} updated profile field: ${field}`); ``` ```typescript // BETTER: Include identifiers this.logger.log( `User ${userId} updated profile`, JSON.stringify({ field, oldValue, newValue }) ); ``` ```typescript // BAD: Vague this.logger.log('Profile updated'); ``` -------------------------------- ### Basic NestLens Module Setup Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/intro.md Configure the NestLens module in your application's root module. Ensure it's only enabled when not in production. ```typescript import { Module } from '@nestjs/common'; import { NestLensModule } from 'nestlens'; @Module({ imports: [ NestLensModule.forRoot({ enabled: process.env.NODE_ENV !== 'production', }), ], }) export class AppModule {} ``` -------------------------------- ### Run Tests Source: https://github.com/mogretici/nestlens/blob/main/CONTRIBUTING.md Execute backend and dashboard tests to ensure the project integrity. This includes running tests for the example application. ```bash npm test cd dashboard && npm test ``` -------------------------------- ### Descriptive Job Naming Examples Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/bull-bullmq.md Demonstrates the use of clear and descriptive names for jobs to improve debugging and understanding of queue operations. ```typescript // Good await queue.add('send-welcome-email', data); await queue.add('generate-monthly-report', data); ``` ```typescript // Bad await queue.add('job1', data); await queue.add('task', data); ``` -------------------------------- ### Provider Token for Bull Classic Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/bull-bullmq.md Configuration example for providing Bull (classic) queues using the `NESTLENS_BULL_QUEUES` token in your NestJS module. ```APIDOC ## Alternative: Provider Token (Bull Classic Only) Use the `NESTLENS_BULL_QUEUES` token to provide Bull (classic) queues: ```typescript import { NESTLENS_BULL_QUEUES } from 'nestlens'; import { getQueueToken } from '@nestjs/bull'; @Module({ providers: [ { provide: NESTLENS_BULL_QUEUES, useFactory: ( emailQueue: Queue, notificationQueue: Queue, ) => [ { queue: emailQueue, name: 'email' }, { queue: notificationQueue, name: 'notifications' }, ], inject: [ getQueueToken('email'), getQueueToken('notifications'), ], }, ], }) export class AppModule {} ``` ``` -------------------------------- ### Queue-Specific Job Naming Conventions Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/bull-bullmq.md Provides examples of naming conventions for jobs within different queues to enhance organization and clarity. ```plaintext // Queue: email 'email:welcome' 'email:reset-password' 'email:notification' // Queue: reports 'report:daily-sales' 'report:monthly-summary' ``` -------------------------------- ### Setup Bull Queue with NestJS Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/job.md Configure BullMQ with Redis connection details and register a specific queue named 'email'. ```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 {} ``` -------------------------------- ### BullMQ Job Active Event Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/bull-bullmq.md Example of a job event when a job has been picked up by a worker and processing has started. ```json { "type": "job", "payload": { "name": "send-email", "queue": "email", "data": { "to": "user@example.com" }, "status": "active", "attempts": 0 } } ``` -------------------------------- ### Setup EventEmitter Module Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/event.md Install and import the EventEmitterModule to enable event emission and listening capabilities in your NestJS application. ```typescript // Install: npm install @nestjs/event-emitter import { Module } from '@nestjs/common'; import { EventEmitterModule } from '@nestjs/event-emitter'; @Module({ imports: [EventEmitterModule.forRoot()], }) export class AppModule {} ``` -------------------------------- ### Setup HTTP Module in NestJS Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/http-client.md Demonstrates how to import the `HttpModule` from `@nestjs/axios` into your application's module. This is the initial step to enable HTTP request handling. ```typescript import { HttpModule } from '@nestjs/axios'; @Module({ imports: [HttpModule], }) export class AppModule {} ``` -------------------------------- ### Business Metrics Watcher Example Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/advanced/custom-watchers.md Implement a watcher to track business-related events such as sales, user signups, and feature usage. Requires a CollectorService dependency. ```typescript import { Injectable } from '@nestjs/common'; @Injectable() export class BusinessMetricsWatcher { constructor(private collector: CollectorService) {} async trackSale(sale: { amount: number; productId: string }) { await this.collector.collect('event', { name: 'sale_completed', payload: { amount: sale.amount, productId: sale.productId, timestamp: new Date(), }, listeners: [], duration: 0, }); } async trackUserSignup(userId: string, source: string) { await this.collector.collect('event', { name: 'user_signup', payload: { userId, source }, listeners: [], duration: 0, }); } async trackFeatureUsage(feature: string, userId: string) { await this.collector.collect('event', { name: 'feature_used', payload: { feature, userId }, listeners: [], duration: 0, }); } } ``` -------------------------------- ### Verify TypeORM Installation Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/faq.md Check if TypeORM is installed in your project using npm. ```bash npm list typeorm ``` -------------------------------- ### Build Static Documentation Source: https://github.com/mogretici/nestlens/blob/main/docs/README.md Generates the static content for the documentation website, typically placed in the 'build' directory. ```bash npm run build ``` -------------------------------- ### Test Locally and Publish Manually Source: https://github.com/mogretici/nestlens/blob/main/RELEASING.md Use this sequence to perform a version bump for testing purposes, build the project, and then manually publish. This is useful for verifying changes before a full release. ```bash npm run release:patch # Version bump only ``` ```bash npm run build # Build ``` ```bash git push --follow-tags && npm publish # Then publish ``` -------------------------------- ### Exception Entry Payload Example Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/configuration/storage.md Example JSON structure for an 'Exception' type entry, detailing error information. ```json { "name": "BadRequestException", "message": "Invalid input", "stack": "Error: Invalid input\n at UserController.create...", "code": 400 } ``` -------------------------------- ### Query Entry Payload Example Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/configuration/storage.md Example JSON structure for a 'Query' type entry, detailing database query information. ```json { "query": "SELECT * FROM users WHERE id = $1", "parameters": [123], "duration": 12, "slow": false, "source": "typeorm" } ``` -------------------------------- ### Testing IP Restrictions with cURL Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/security/ip-whitelisting.md Illustrates how to use cURL commands to test IP restrictions. It shows how to test from an allowed IP and how to simulate testing from a different IP address using the --interface option. ```bash # Test from allowed IP curl http://localhost:3000/nestlens/api/entries # Test from different IP (will fail if not whitelisted) curl --interface 192.168.1.200 http://your-server/nestlens/api/entries ``` -------------------------------- ### Request Entry Payload Example Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/configuration/storage.md Example JSON structure for a 'Request' type entry, detailing HTTP request information. ```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" } ``` -------------------------------- ### Configure Global Prisma Instance Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/prisma.md Set up a global Prisma instance by extending `PrismaClient` and assigning it to `global.prisma` in `onModuleInit`. ```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; } } ``` -------------------------------- ### Optimize Queries with SQL Indexes Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/advanced/extending-storage.md Create indexes on frequently queried columns to significantly speed up data retrieval. This example shows how to create indexes for common query patterns. ```sql CREATE INDEX idx_type_created ON entries(type, created_at); CREATE INDEX idx_request_id ON entries(request_id); CREATE INDEX idx_family_hash ON entries(family_hash); ``` -------------------------------- ### Setup Prisma Client with Model Tracking Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/prisma.md Integrate NestLens's ModelWatcher with your PrismaService by injecting it and calling `setupPrismaClient`. This allows NestLens to track model-specific operations. ```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); } } } ``` -------------------------------- ### Example NestLens Module Configuration for TypeORM Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/typeorm.md Demonstrates how to configure the NestLens module with TypeORM watchers, setting enabled states, slow query thresholds, and ignore patterns. ```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 }, }, }) ``` -------------------------------- ### Log Filtering Examples Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/log.md NestLens automatically filters its own internal logs to prevent recursion. These examples show logs that would typically be filtered. ```typescript // These won't be captured to avoid infinite loops this.logger.log('NestLens started'); // Context includes 'NestLens' this.logger.log('Collector processed entries'); // Context is 'Collector' ``` -------------------------------- ### Register Queue with Job Watcher Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/bull-bullmq.md Make sure the `setupQueue` method is called to register your queue with the job watcher. This is necessary for the watcher to monitor the queue. ```typescript // Make sure setupQueue was called this.jobWatcher.setupQueue(this.queue, 'queue-name'); ``` -------------------------------- ### Provide Redis Client with NESTLENS_REDIS_CLIENT Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/redis.md Provide your Redis client instance using the `NESTLENS_REDIS_CLIENT` token in your module. This example shows creating a new `ioredis` client. ```typescript import { NESTLENS_REDIS_CLIENT } from 'nestlens'; import Redis from 'ioredis'; @Module({ providers: [ { provide: NESTLENS_REDIS_CLIENT, useFactory: () => { return new Redis({ host: 'localhost', port: 6379, }); }, }, ], }) export class AppModule {} ``` -------------------------------- ### Implement Hybrid Storage with Multiple Backends Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/advanced/extending-storage.md Combine primary and archive storage solutions to manage data efficiently. This example demonstrates saving entries to a primary storage and archiving critical ones to a secondary storage. ```typescript import { Injectable, Optional, } from '@nestjs/common'; import { StorageInterface, Entry, EntryFilter, } from '@nestjs-storage/core'; import { SqliteStorage } from './sqlite-storage'; // Assuming these are custom storage implementations import { S3Storage } from './s3-storage'; @Injectable() export class HybridStorage implements StorageInterface { constructor( private primaryStorage: SqliteStorage, private archiveStorage: S3Storage, ) {} async save(entry: Entry): Promise { // Save to primary storage const saved = await this.primaryStorage.save(entry); // Archive critical entries if (entry.type === 'exception' || entry.type === 'request') { await this.archiveStorage.save(saved); } return saved; } async find(filter: EntryFilter): Promise { // Search primary first let entries = await this.primaryStorage.find(filter); // If not found and date is old, search archive if (entries.length === 0 && filter.from) { const age = Date.now() - filter.from.getTime(); if (age > 7 * 24 * 60 * 60 * 1000) { // 7 days entries = await this.archiveStorage.find(filter); } } return entries; } // Implement remaining methods... async remove(id: string): Promise { await this.primaryStorage.remove(id); await this.archiveStorage.remove(id); } async findById(id: string): Promise { const entry = await this.primaryStorage.findById(id); if (entry) { return entry; } return this.archiveStorage.findById(id); } } ``` -------------------------------- ### Tracked Job Events Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/bull-bullmq.md Examples of job events that NestLens monitors for Bull and BullMQ queues. ```APIDOC ## Tracked Events NestLens monitors all Bull/BullMQ queue events: ### 1. Waiting Job added to queue, waiting for processing ```typescript { type: 'job', payload: { name: 'send-email', queue: 'email', data: { to: 'user@example.com', subject: '...' }, status: 'waiting', attempts: 0 } } ``` ### 2. Active Job picked up by worker and processing started ```typescript { type: 'job', payload: { name: 'send-email', queue: 'email', data: { to: 'user@example.com' }, status: 'active', attempts: 0 } } ``` ### 3. Completed Job finished successfully ```typescript { type: 'job', payload: { name: 'send-email', queue: 'email', data: { to: 'user@example.com' }, status: 'completed', attempts: 0, duration: 1250, // milliseconds result: { messageId: 'abc123' } } } ``` ### 4. Failed Job processing failed ```typescript { type: 'job', payload: { name: 'send-email', queue: 'email', data: { to: 'user@example.com' }, status: 'failed', attempts: 1, duration: 500, error: 'SMTP connection failed' } } ``` ### 5. Delayed Job scheduled for later execution ```typescript { type: 'job', payload: { name: 'send-reminder', queue: 'notifications', data: { userId: 123 }, status: 'delayed', attempts: 0 } } ``` ``` -------------------------------- ### Configure GraphQL Watcher Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/graphql.md Enable and configure the GraphQL watcher by providing options to `NestLensModule.forRoot`. This example shows how to enable tracking, set the server type, capture variables and responses, ignore introspection, and configure N+1 query detection. ```typescript NestLensModule.forRoot({ watchers: { graphql: { enabled: true, server: 'auto', // 'apollo' | 'mercurius' | 'auto' captureVariables: true, captureResponse: false, ignoreIntrospection: true, ignoreOperations: ['HealthCheck'], detectN1Queries: true, n1Threshold: 10, traceFieldResolvers: false, subscriptions: { enabled: true, trackMessages: false, trackConnectionEvents: true, }, tags: async (ctx) => { return [ctx.operationType, ctx.operationName ?? 'anonymous']; }, }, }, }) ``` -------------------------------- ### Implement Custom Storage Interface Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/api/index.md Provides an example of implementing the StorageInterface for custom data persistence, including basic CRUD, counting, and data management 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, }, ], }) ``` -------------------------------- ### BullMQ Job Delayed Event Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/bull-bullmq.md Example of a job event when a job is scheduled for later execution. ```json { "type": "job", "payload": { "name": "send-reminder", "queue": "notifications", "data": { "userId": 123 }, "status": "delayed", "attempts": 0 } } ``` -------------------------------- ### BullMQ Job Waiting Event Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/bull-bullmq.md Example of a job event when a job is added to the queue and is waiting for processing. ```json { "type": "job", "payload": { "name": "send-email", "queue": "email", "data": { "to": "user@example.com", "subject": "..." }, "status": "waiting", "attempts": 0 } } ``` -------------------------------- ### Prisma Client Setup with NestLens Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/model.md Integrate NestLens model watching with Prisma by extending PrismaClient and calling setupPrismaClient within the onModuleInit lifecycle hook. Ensure PrismaService is provided in your NestJS module. ```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); } } ``` -------------------------------- ### Example Filter Badges Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/dashboard/filtering.md Displays active filters as badges. Each badge can be removed by clicking the 'x' icon. ```text Status: 500 × Method: POST × Slow: true × ``` -------------------------------- ### Configure Job Watcher Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/bull-bullmq.md Enable the job watcher in your NestLens configuration to start monitoring Bull/BullMQ jobs. ```typescript interface JobWatcherConfig { enabled?: boolean; } // In your NestLens config NestLensModule.forRoot({ watchers: { job: { enabled: true, }, }, }) ``` -------------------------------- ### Set Up Alerts for Security Events Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/security/production-usage.md This TypeScript example shows how to implement alert logic based on security events, such as multiple failed access attempts. Configure alerts for unauthorized access, high request volume, and unusual patterns. ```typescript // Example alert logic if (failedAttempts > 5) { await alertService.send({ severity: 'high', message: 'Multiple failed NestLens access attempts', ip: req.ip, }); } ``` -------------------------------- ### Filter for Redis Cache Misses Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/dashboard/filtering.md Identify instances where a 'get' operation on the Redis cache resulted in a miss. ```text Type: Cache Operation: get Hit: false ``` -------------------------------- ### Deep Linking with Filters and Pagination Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/dashboard/navigation.md Demonstrates how URLs can include query parameters for filtering and pagination, enabling bookmarking and sharing of specific views. ```plaintext /nestlens/requests?status=500&method=POST /nestlens/queries?slow=true /nestlens/exceptions?resolved=false ``` -------------------------------- ### Cron Patterns for Scheduling Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/schedule.md Examples of common cron patterns used with the `@Cron` decorator to define task schedules. ```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 * *') ``` -------------------------------- ### HTTP Request Header Masking Example Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/security/data-masking.md Shows how sensitive headers are masked before being stored. Sensitive headers are replaced with '********'. ```typescript // Original request headers: { 'authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...', 'x-api-key': 'sk_live_1234567890', 'cookie': 'session=abc123; token=xyz789' } // Stored in NestLens headers: { 'authorization': '********', 'x-api-key': '********', 'cookie': '********' } ``` -------------------------------- ### MongoDB Storage Initialization and Indexing Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/advanced/extending-storage.md Initializes the MongoDB client, database, and collection, and creates necessary indexes for efficient querying. ```typescript // mongodb.storage.ts import { Injectable } from '@nestjs/common'; import { MongoClient, Db, Collection } from 'mongodb'; import { StorageInterface, Entry } from 'nestlens'; @Injectable() export class MongoDBStorage implements StorageInterface { private client: MongoClient; private db: Db; private entries: Collection; async initialize(): Promise { this.client = await MongoClient.connect(process.env.MONGODB_URI); this.db = this.client.db('nestlens'); this.entries = this.db.collection('entries'); // Create indexes await this.entries.createIndex({ type: 1 }); await this.entries.createIndex({ requestId: 1 }); await this.entries.createIndex({ createdAt: -1 }); await this.entries.createIndex({ familyHash: 1 }); } async save(entry: Entry): Promise { const doc = { ...entry, createdAt: new Date(), }; const result = await this.entries.insertOne(doc); return { ...entry, id: result.insertedId.toString(), createdAt: doc.createdAt.toISOString(), }; } async saveBatch(entries: Entry[]): Promise { const docs = entries.map(entry => ({ ...entry, createdAt: new Date(), })); const result = await this.entries.insertMany(docs); return entries.map((entry, index) => ({ ...entry, id: result.insertedIds[index].toString(), createdAt: docs[index].createdAt.toISOString(), })); } async find(filter: EntryFilter): Promise { const query: any = {}; if (filter.type) { query.type = filter.type; } if (filter.requestId) { query.requestId = filter.requestId; } if (filter.from || filter.to) { query.createdAt = {}; if (filter.from) { query.createdAt.$gte = filter.from; } if (filter.to) { query.createdAt.$lte = filter.to; } } let cursor = this.entries.find(query).sort({ createdAt: -1 }); if (filter.limit) { cursor = cursor.limit(filter.limit); } if (filter.offset) { cursor = cursor.skip(filter.offset); } const docs = await cursor.toArray(); return docs.map(doc => ({ id: doc._id.toString(), type: doc.type, payload: doc.payload, requestId: doc.requestId, familyHash: doc.familyHash, resolvedAt: doc.resolvedAt, createdAt: doc.createdAt.toISOString(), tags: doc.tags, })); } async prune(before: Date): Promise { const result = await this.entries.deleteMany({ createdAt: { $lt: before }, }); return result.deletedCount; } async close(): Promise { await this.client.close(); } // Implement remaining methods... } ``` -------------------------------- ### Mercurius Integration with NestLens Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/graphql.md Integrate the GraphQLWatcher with Mercurius by passing its plugin to the Mercurius configuration. This example uses the Fastify adapter. ```typescript import { GraphQLWatcher } from 'nestlens'; // With Fastify adapter fastify.register(mercurius, { schema, hooks: graphqlWatcher.getPlugin(), }); ``` -------------------------------- ### BullMQ Job Completed Event Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/bull-bullmq.md Example of a job event when a job has finished successfully. Includes processing duration and result. ```json { "type": "job", "payload": { "name": "send-email", "queue": "email", "data": { "to": "user@example.com" }, "status": "completed", "attempts": 0, "duration": 1250, // milliseconds "result": { "messageId": "abc123" } } } ``` -------------------------------- ### Default Filter Combination (AND Logic) Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/dashboard/filtering.md Demonstrates the default AND logic for filter combinations, where all specified conditions must be met. ```text status=500 AND method=POST AND path=/api/* ``` -------------------------------- ### Cache Invalidation Example Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/cache.md Demonstrates how to invalidate related cache keys when user data changes to ensure data freshness. ```typescript async invalidateUser(userId: string) { // Invalidate all related cache keys await this.cacheManager.del(`user:${userId}`); await this.cacheManager.del(`user:${userId}:posts`); await this.cacheManager.del(`user:${userId}:settings`); } ``` -------------------------------- ### Role-Based Access Control (RBAC) Integration Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/gate.md This example demonstrates a basic RBAC implementation where permissions are checked against user roles. The comment indicates how NestLens would track this automatically. ```typescript @Injectable() export class RBACService { async can(action: string, subject: string, user: User): Promise { const permission = `${subject}:${action}`; const allowed = user.roles.some(role => role.permissions.includes(permission), ); // Tracked automatically return allowed; } } // Usage const canEdit = await this.rbac.can('edit', 'users', user); // Tracked as: gate: 'users', action: 'edit', allowed: true/false ``` -------------------------------- ### Setup NestJS Schedule Module Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/watchers/schedule.md Import and configure the `@nestjs/schedule` module in your `AppModule` to use cron jobs, intervals, and timeouts. ```typescript // Install: npm install @nestjs/schedule import { ScheduleModule } from '@nestjs/schedule'; @Module({ imports: [ScheduleModule.forRoot()], }) export class AppModule {} ``` -------------------------------- ### Build React Dashboard Source: https://github.com/mogretici/nestlens/blob/main/CLAUDE.md Build only the React-based dashboard for NestLens. ```bash npm run build:dashboard ``` -------------------------------- ### NestLens Environment Variables for Production Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/security/access-control.md Example environment variables for configuring NestLens in a production environment. These variables control the module's enabled state, allowed environments, and IP whitelisting. ```bash # .env.production NESTLENS_ENABLED=false NESTLENS_ENVIRONMENTS=production NESTLENS_ALLOWED_IPS=192.168.1.0/24,10.0.0.0/8 ``` -------------------------------- ### Test Custom Postgres Storage Implementation Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/advanced/extending-storage.md This snippet demonstrates how to test a custom PostgresStorage implementation using a testing framework. It covers initialization, saving, and retrieving entries. ```typescript describe('PostgresStorage', () => { let storage: PostgresStorage; beforeAll(async () => { storage = new PostgresStorage(); await storage.initialize(); }); afterAll(async () => { await storage.close(); }); it('should save and retrieve entry', async () => { const entry: Entry = { type: 'log', payload: { level: 'info', message: 'Test log', }, }; const saved = await storage.save(entry); expect(saved.id).toBeDefined(); const found = await storage.findById(saved.id); expect(found).toEqual(saved); }); }); ``` -------------------------------- ### Custom Prisma Middleware Setup Source: https://github.com/mogretici/nestlens/blob/main/docs/docs/integrations/prisma.md Manually attach NestLens middleware to a Prisma client instance for custom control. Ensure the Prisma client is made globally available. ```typescript import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); // Attach NestLens middleware prisma.$use(async (params, next) => { const start = Date.now(); const result = await next(params); const duration = Date.now() - start; // NestLens will intercept this if global.prisma is set console.log(`${params.model}.${params.action} took ${duration}ms`); return result; }); // Make globally available (global as any).prisma = prisma; ```