@ngn-net/nestjs-telescope
v0.3.15
Published
Full-featured monitoring package for NestJS (inspired by Laravel Telescope) — uses MongoDB for zero-impact storage
Readme
@ngn-net/nestjs-telescope

A full-featured developer assistant and application monitoring suite for NestJS, inspired by Laravel Telescope. It monitors incoming HTTP requests, database queries, cache operations, background queue jobs, application events, outgoing mail, logs, unhandled exceptions, cron job schedules, Redis commands, CLI commands, ORM model lifecycle events, notifications, and authorization gate checks.
All telemetry records are persisted to a dedicated MongoDB (via Mongoose) and accessible via a modern, high-fidelity dark-themed single-page application dashboard. Telescope uses its own MongoDB connection — completely separate from your project's database.
Features
- HTTP Request Watcher: Captures request methods, URLs, IP addresses, payloads, headers, durations, and response status/bodies.
- HTTP Client Watcher: Patches both Node.js
http/httpsmodules and Axios to capture all outbound HTTP calls with full request/response data and timing. - Database Query Watcher: Hooks into TypeORM
DataSource.createQueryRunnerto record all SQL queries, parameters, durations, and success/failure status. - Cache Watcher: Wraps Cache Manager operations (
GET,SET,DEL) to trace cache activity. - Queue Watcher: Tracks BullMQ background jobs and captures completion values and job failures.
- Event Watcher: Intercepts
EventEmitter2events and lists firing metrics. - Mail Watcher: Proxies Nodemailer transports to log outgoing mail contents.
- Log Watcher: Integrates console logs (
log,warn,error,debug) directly into the dashboard. - Exception Watcher: Hooks into HTTP streams to catch and log request failures, statuses, and stack traces.
- Schedule Watcher: Monitors cron execution runtimes and statuses from
@nestjs/schedule. - Redis Watcher: Hooks into
ioredisto report Redis command durations and arguments. - Gate (Authorization) Watcher: Intercepts HTTP requests to record authorization decisions — successful auth checks and failed auth/forbidden errors with user context and requested roles.
- Command Watcher: Records CLI command executions (startup commands like
start,build,test, etc.) with arguments and PIDs. - Model Watcher: Subscribes to both TypeORM entity lifecycle events (
INSERT,UPDATE,REMOVE) and Mongoose document lifecycle (save,deleteOne) to record all ORM/ODM operations. - Notification Watcher: Intercepts
EventEmitter2events matching notification patterns (notification, mail, sms, push) and records them with channel and recipient details.
Storage: MongoDB (Zero Production Impact)
Telescope stores its telemetry data in a dedicated MongoDB collection (telescope_entries), completely separate from your application's production database.
Why MongoDB?
- No schema migrations or entity registration in your app
- No foreign key constraints or connection pool contention
- Automatic TTL-based cleanup
- High write throughput for telemetry workloads
- Zero impact on your production database performance
MongoDB Connection
Telescope connects to its own dedicated MongoDB using the TELESCOPE_MONGO_URI environment variable, or falls back to mongodb://localhost:27017/telescope.
# .env
TELESCOPE_MONGO_URI=mongodb://localhost:27017/telescopeOr pass the URI directly in configuration:
TelescopeModule.forRoot({
mongoUri: 'mongodb://your-mongo-host:27017/telescope',
// ... other options
})Installation
Install the package:
npm install @ngn-net/nestjs-telescope @nestjs/jwt @nestjs/passport passport-jwtNo need to install mongoose or configure MongooseModule — Telescope handles its own MongoDB connection internally.
Quick Start
import { Module } from '@nestjs/common';
import { TelescopeModule } from '@ngn-net/nestjs-telescope';
@Module({
imports: [
TelescopeModule.forRoot({
path: 'telescope',
jwtSecret: 'your-secret-key',
password: 'your-password',
// Telescope connects to its own MongoDB automatically
// Default: mongodb://localhost:27017/telescope
}),
],
})
export class AppModule {}Your app's database (TypeORM/Prisma/Sequelize/etc.) stays completely separate — Telescope never touches it.
All watchers are dynamically activated. If your application does not use certain modules, Telescope will safely boot without them. Simply install the peer dependencies for the watchers you want to enable:
| Watcher | Required Dependency | Entry Type |
|---|---|---|
| Cache Watcher | @nestjs/cache-manager & cache-manager | EntryType.CACHE |
| Queue Watcher | @nestjs/bullmq & bullmq | EntryType.JOB |
| Event Watcher | @nestjs/event-emitter | EntryType.EVENT |
| Schedule Watcher | @nestjs/schedule | EntryType.SCHEDULED_TASK |
| Mail Watcher | nodemailer & @types/nodemailer | EntryType.MAIL |
| Redis Watcher | ioredis | EntryType.REDIS |
Built-in watchers (always available, no extra dependencies):
| Watcher | Entry Type | What It Captures |
|---|---|---|
| HTTP Request | EntryType.REQUEST | Incoming HTTP requests and responses |
| HTTP Client | EntryType.HTTP_CLIENT | Outbound HTTP calls (Node http/https + Axios) |
| Query | EntryType.QUERY | TypeORM SQL queries |
| Log | EntryType.LOG | Console log/warn/error/debug output |
| Exception | EntryType.EXCEPTION | Unhandled HTTP exceptions |
| Gate | EntryType.GATE | Authorization checks (success + failure) |
| Command | EntryType.COMMAND | CLI command executions |
| Model | EntryType.MODEL | TypeORM + Mongoose entity lifecycle events |
| Notification | EntryType.NOTIFICATION | Notification events via EventEmitter2 |
Configuration Reference
You can pass configuration options into TelescopeModule.forRoot(options):
| Option | Type | Default | Description |
|---|---|---|---|
| path | string | 'telescope' | Base path for the UI and API. |
| jwtSecret | string | 'telescope-change-me' | JWT secret used to sign UI authentication tokens. |
| password | string | 'password' | Password for dashboard login (can also be set via TELESCOPE_PASSWORD env). |
| maxEntries | number | 1000 | Maximum number of entries to retain before pruning. |
| enabledEntryTypes | EntryType[] | all | Specific entry types to record. If undefined, all types are recorded. |
| ignorePaths | string[] | [] | Request path prefixes to ignore (e.g. ['/health', '/metrics']). |
| ignoreCommands | string[] | [] | Redis command names to ignore (e.g. ['ping', 'info']). |
| uiMiddleware | any[] | [] | Custom middleware to apply to Telescope routes. |
| enableDashboard | boolean | true | Enable/disable the dashboard UI. |
| mongoUri | string | 'mongodb://localhost:27017/telescope' | MongoDB connection URI. |
Usage
Synchronous Configuration
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TelescopeModule, EntryType } from '@ngn-net/nestjs-telescope';
@Module({
imports: [
// Your project database — completely separate from Telescope
TypeOrmModule.forRoot({
type: 'postgres',
database: 'myapp_db',
}),
TelescopeModule.forRoot({
path: 'telescope',
password: 'my-secure-password',
jwtSecret: 'my-jwt-secret',
maxEntries: 500,
// Telescope uses its own MongoDB: mongodb://localhost:27017/telescope
}),
],
})
export class AppModule {}Async Configuration
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TelescopeModule } from '@ngn-net/nestjs-telescope';
@Module({
imports: [
ConfigModule.forRoot(),
TelescopeModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService) => ({
path: configService.get('TELESCOPE_PATH', 'telescope'),
password: configService.get('TELESCOPE_PASSWORD', 'password'),
jwtSecret: configService.get('TELESCOPE_JWT_SECRET', 'my-secret'),
maxEntries: 1000,
}),
}),
],
})
export class AppModule {}Dashboard Access
- Run your NestJS application.
- Open your browser and navigate to
http://localhost:3000/telescope(or your configured path). - Enter the configured password (or defaults to
password). - Monitor requests, logs, queries, and errors in real-time.
Entry Types
All available entry types for filtering and configuration:
import { EntryType } from '@ngn-net/nestjs-telescope';
EntryType.REQUEST // Incoming HTTP requests
EntryType.HTTP_CLIENT // Outbound HTTP calls (http/https/Axios)
EntryType.QUERY // Database queries (TypeORM)
EntryType.CACHE // Cache operations
EntryType.JOB // Background queue jobs (BullMQ)
EntryType.EVENT // Application events (EventEmitter2)
EntryType.MAIL // Outgoing emails
EntryType.LOG // Console log output
EntryType.EXCEPTION // Unhandled exceptions
EntryType.SCHEDULED_TASK // Cron/scheduled task executions
EntryType.REDIS // Redis commands
EntryType.GATE // Authorization gate checks
EntryType.COMMAND // CLI command executions
EntryType.MODEL // ORM model lifecycle events
EntryType.NOTIFICATION // Notification events
EntryType.DUMP // Debug dump outputAPI Endpoints
All endpoints are prefixed with your configured path (default: /telescope).
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/login | Authenticate with password, returns JWT |
| GET | /api/stats | Get entry counts by type |
| GET | /api/entries | Query entries with filters (type, search, batchId, page, perPage) |
| GET | /api/entries/:uuid | Get a single entry by UUID |
| DELETE | /api/entries | Clear all entries |
Development & Test
To build the package:
npm run buildTo run Jest tests:
npm run testMigration from v0.2.x
If upgrading from v0.2.x (which used TypeORM/SQL):
Update the package:
npm install @ngn-net/nestjs-telescope@latestEnsure MongoDB is available at
mongodb://localhost:27017/telescope(or configuremongoUri).Remove the old
TypeOrmModuleimport if it was only added for Telescope.The old
telescope_entriesSQL table can be dropped after migration.
License
MIT
