Frequently Asked Questions
Common questions and answers about NestLens.
General
Does NestLens work in production?
Short answer: It can, but it's not recommended by default.
NestLens is primarily designed for development and staging environments. If you need it in production:
- Use strict security: Enable IP whitelisting, authentication, and role-based access
- Minimize data capture: Disable body/response capture
- Aggressive pruning: Keep data for 1-2 hours maximum
- Consider alternatives: Use APM tools (New Relic, Datadog) for production monitoring
See Production Usage for detailed guidance.
How much does NestLens impact performance?
Typical overhead:
- Request tracking: 0.5-1ms per request
- Query tracking: 0.1-0.5ms per query
- Memory: Less than 50MB with default buffering
- CPU: Less than 2% in most applications
The impact is minimal in development but should be monitored in production. See Performance Optimization.
Is my data secure?
NestLens includes multiple security features:
- Environment restrictions: Only runs in specific environments by default
- IP whitelisting: Restrict access to specific IPs
- Authentication: Custom auth functions
- Data masking: Automatic masking of sensitive headers and fields
- Access control: Role-based access control
See Security section for full details.
Configuration
How do I disable NestLens?
// Disable completely
NestLensModule.forRoot({
enabled: false,
})
// Disable in production only
NestLensModule.forRoot({
enabled: process.env.NODE_ENV !== 'production',
})
// Remove the module entirely
@Module({
imports: [
// NestLensModule.forRoot(), // Comment out or remove
],
})
How do I disable specific watchers?
NestLensModule.forRoot({
watchers: {
request: true, // Keep
query: true, // Keep
exception: true, // Keep
log: false, // Disable
cache: false, // Disable
// Set any watcher to false to disable
},
})
Can I change the dashboard path?
NestLensModule.forRoot({
path: '/my-custom-path', // Default is '/nestlens'
})
Access at: http://localhost:3000/my-custom-path
How do I configure TypeORM integration?
TypeORM integration is automatic - just install TypeORM and enable the query watcher:
NestLensModule.forRoot({
watchers: {
query: true,
},
})
No additional configuration needed. See TypeORM Integration.
How do I configure Prisma integration?
Prisma requires manual setup:
// 1. Enable query watcher
NestLensModule.forRoot({
watchers: {
query: true,
},
})
// 2. Make Prisma client globally available
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
(global as any).prisma = this;
}
}
See Prisma Integration.
Data Management
Can I use a different database?
Yes! Implement the StorageInterface to use any database:
import { StorageInterface, STORAGE } from 'nestlens';
@Injectable()
export class MyCustomStorage implements StorageInterface {
// Implement required methods
}
@Module({
providers: [
{
provide: STORAGE,
useClass: MyCustomStorage,
},
],
})
See Extending Storage.
How do I export data?
Use the storage API:
@Injectable()
export class ExportService {
constructor(@Inject(STORAGE) private storage: StorageInterface) {}
async exportAllEntries() {
const entries = await this.storage.find({
limit: 10000,
});
return entries;
}
}
Or use the dashboard's export functionality (coming soon).
How do I clear old entries?
NestLens automatically prunes old entries:
NestLensModule.forRoot({
pruning: {
enabled: true,
maxAge: 24, // Hours (default: 24)
interval: 60, // Minutes (default: 60)
},
})
Manual clearing:
@Injectable()
export class CleanupService {
constructor(@Inject(STORAGE) private storage: StorageInterface) {}
async clearAll() {
await this.storage.clear();
}
async clearOlderThan(hours: number) {
const before = new Date(Date.now() - hours * 60 * 60 * 1000);
await this.storage.prune(before);
}
}
Where is data stored?
NestLens supports three storage drivers:
| Driver | Location | Persistence |
|---|---|---|
| Memory (default) | RAM | Lost on restart |
| SQLite | .cache/nestlens.db | Persistent |
| Redis | Redis server | Persistent |
You can customize the storage:
// In-memory (default)
NestLensModule.forRoot({})
// SQLite (requires: npm install better-sqlite3)
NestLensModule.forRoot({
storage: {
driver: 'sqlite',
sqlite: { filename: '/var/data/nestlens.db' },
},
})
// Redis (requires: npm install ioredis)
NestLensModule.forRoot({
storage: {
driver: 'redis',
redis: { url: process.env.REDIS_URL },
},
})
Filtering
How do I filter sensitive data?
Use the filter function:
NestLensModule.forRoot({
filter: (entry) => {
// Don't track auth endpoints
if (entry.type === 'request' &&
entry.payload.path.startsWith('/auth/')) {
return false;
}
// Mask passwords in request bodies
if (entry.type === 'request' && entry.payload.body?.password) {
entry.payload.body.password = '***MASKED***';
}
return true;
},
})
See Entry Filtering and Data Masking.
How do I ignore specific routes?
NestLensModule.forRoot({
watchers: {
request: {
ignorePaths: [
'/health',
'/metrics',
'/status',
],
},
},
})
Or use filtering:
NestLensModule.forRoot({
filter: (entry) => {
if (entry.type === 'request') {
const ignoredPaths = ['/health', '/metrics'];
return !ignoredPaths.some(path =>
entry.payload.path.startsWith(path)
);
}
return true;
},
})
How do I track only errors?
NestLensModule.forRoot({
filter: (entry) => {
// Only track exceptions
if (entry.type === 'exception') {
return true;
}
// Only track error requests
if (entry.type === 'request') {
return entry.payload.statusCode >= 400;
}
// Only track error logs
if (entry.type === 'log') {
return entry.payload.level === 'error';
}
// Skip everything else
return false;
},
})
Dashboard
Can I customize the dashboard?
The dashboard is served as a static React application. While you can't easily customize the UI, you can:
- Use custom path: Change the dashboard URL
- Add custom authentication: Control who can access
- Brand with reverse proxy: Add your branding via nginx/Apache
Full customization requires forking the repository.
How do I access the dashboard remotely?
-
SSH Tunnel (recommended):
ssh -L 3000:localhost:3000 user@serverAccess at
http://localhost:3000/nestlens -
VPN: Connect to server's VPN
-
IP Whitelist: Add your IP to allowedIps
-
Authentication: Use custom auth with public access
Never expose the dashboard publicly without authentication!
Can I embed the dashboard in my app?
Not directly, but you can:
-
iframe: Embed in an authenticated admin panel
<iframe src="/nestlens" width="100%" height="800px"></iframe> -
Reverse Proxy: Serve under your domain
location /admin/monitoring {
proxy_pass http://localhost:3000/nestlens;
}
Debugging
Entries not appearing in dashboard
Check these in order:
-
Is NestLens enabled?
enabled: true -
Is the watcher enabled?
watchers: { request: true } -
Are you accessing the correct path?
- Default:
http://localhost:3000/nestlens - Check your
pathconfig
- Default:
-
Is data being collected?
// Check storage directly
const count = await storage.count();
console.log('Total entries:', count); -
Are filters blocking entries?
- Temporarily remove filter function
- Check filter logic
-
Check browser console for errors
"Access Denied" error
-
Check environment:
allowedEnvironments: ['development', 'local', 'test']Make sure
NODE_ENVmatches -
Check IP whitelist:
allowedIps: ['127.0.0.1', 'localhost'] -
Check custom auth:
canAccess: (req) => {
console.log('Auth check:', req.headers);
return true; // Test with always true
} -
Check browser console and network tab for specific error
Slow performance
-
Disable body/response capture:
watchers: {
request: {
captureBody: false,
captureResponse: false,
},
} -
Increase slow query threshold:
watchers: {
query: {
slowThreshold: 1000, // 1 second
},
} -
Disable unused watchers:
watchers: {
log: false,
cache: false,
event: false,
} -
Add filtering:
filter: (entry) => {
// Only track errors
return entry.type === 'exception';
} -
Check pruning is enabled:
pruning: {
enabled: true,
maxAge: 1, // 1 hour
}
Integration Issues
TypeORM queries not tracked
-
Enable query watcher:
watchers: { query: true } -
Verify TypeORM is installed:
npm list typeorm -
Check initialization order: NestLens should be imported after TypeORM
-
Check console logs for "TypeORM query logging initialized"
Prisma queries not tracked
-
Enable query watcher:
watchers: { query: true } -
Make Prisma client global:
(global as any).prisma = this.prisma; -
Or use manual setup:
const modelWatcher = this.moduleRef.get(ModelWatcher);
modelWatcher.setupPrismaClient(this.prisma);
See Prisma Integration.
Bull/BullMQ jobs not tracked
-
Enable job watcher:
watchers: { job: true } -
Register your queues:
this.jobWatcher.setupQueue(this.emailQueue, 'email');
See Bull Integration.
Redis commands not tracked
-
Enable Redis watcher:
watchers: { redis: true } -
Provide Redis client:
{
provide: NESTLENS_REDIS_CLIENT,
useExisting: RedisService,
}
See Redis Integration.
Advanced
Can I create custom entry types?
Not directly, but you can use existing types creatively:
// Use 'event' type for custom events
collector.collect('event', {
name: 'custom-business-event',
payload: { /* your data */ },
listeners: [],
duration: 0,
});
// Use 'log' type for custom logs
collector.collect('log', {
level: 'info',
message: 'Custom metric',
metadata: { /* your data */ },
});
Can I send data to external services?
Yes, implement custom storage:
@Injectable()
export class ExternalServiceStorage implements StorageInterface {
async save(entry: Entry) {
// Send to external service
await this.http.post('https://api.example.com/events', entry);
// Also save locally
return this.localStorage.save(entry);
}
// Implement other methods...
}
See Extending Storage.
How do I add custom tags?
Use the TagService:
@Injectable()
export class MyService {
constructor(
private collector: CollectorService,
private tagService: TagService,
) {}
async doSomething() {
// Collect entry
const entry = await this.collector.collectImmediate('event', {
name: 'something-happened',
payload: {},
listeners: [],
duration: 0,
});
// Add tags
if (entry?.id) {
await this.tagService.addTags(entry.id, ['important', 'business']);
}
}
}
Can I access the API programmatically?
Yes, NestLens exposes a REST API:
# Get entries
GET /nestlens/__nestlens__/api/entries?type=request&limit=50
# Get specific entry
GET /nestlens/__nestlens__/api/entries/:id
# Get stats
GET /nestlens/__nestlens__/api/stats
# Get tags
GET /nestlens/__nestlens__/api/tags
All API endpoints require the same authentication as the dashboard.
Support
Where can I get help?
- Documentation: Read the full docs at NestLens Docs
- GitHub Issues: Report bugs or request features
- GitHub Discussions: Ask questions and share ideas
- Stack Overflow: Tag questions with
nestlens
How do I report a bug?
- Check GitHub Issues for existing reports
- Create a new issue with:
- NestLens version
- NestJS version
- Node version
- Minimal reproduction example
- Expected vs actual behavior
- Error messages/logs
How do I request a feature?
- Check GitHub Discussions
- Search for similar requests
- Create a new discussion with:
- Clear description of the feature
- Use case / problem it solves
- Example of how it would work
- Willingness to contribute
Can I contribute?
Yes! Contributions are welcome:
- Code: Submit pull requests
- Documentation: Improve docs
- Bug Reports: Report issues
- Feature Ideas: Suggest enhancements
- Testing: Test beta features
See CONTRIBUTING.md in the repository.