You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+32-3Lines changed: 32 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -54,7 +54,7 @@ Start your app and open:
54
54
http://localhost:<your-port>/__debug
55
55
```
56
56
57
-
That's it. Hit any endpoint of your API and watch it appear in the dashboard (it refreshes every 2 seconds). If the list stays empty, make sure `NODE_ENV` isn't `production`, or pass `enabled: true` explicitly.
57
+
That's it. Hit any endpoint of your API and watch it appear in the dashboard (it refreshes every 2 seconds). If the list stays empty, make sure `NODE_ENV` isn't `production`, pass `enabled: true` explicitly, or set `NEST_DEBUG_PANEL_ENABLED=true` in your environment (see [Enabling & disabling](#enabling--disabling)).
58
58
59
59
Works with Node.js 18+, NestJS 9/10/11, and both Express and Fastify. No runtime dependencies.
60
60
@@ -70,6 +70,17 @@ On top of that:
70
70
-**Exceptions** with name, message, stack trace, and how long the request ran before failing
71
71
-**Memory**: heap and RSS deltas per request, event-loop delay
72
72
-**A timeline** that lays all of the above in order, plus your own custom marks
73
+
-**Socket.io events** — inbound `@SubscribeMessage` handlers captured like a request, with all the SQL/Redis/HTTP they run (see below)
74
+
75
+
## Socket.io events
76
+
77
+
If your app uses NestJS WebSocket gateways (`@WebSocketGateway` + `@SubscribeMessage`), every incoming event is captured **automatically** — just like HTTP. You don't touch your gateways or add any decorator; `DebugModule.forRoot()` is all it takes. (NestJS doesn't apply global interceptors to gateways, so the panel attaches itself to each gateway at startup for you.)
78
+
79
+
Each event runs inside the same tracing context, so **every query it runs shows up automatically**, with N+1 detection, timeline and all — plus the event name, namespace, socket id, rooms, handshake (redacted), payload and acknowledgement.
80
+
81
+
Socket events appear in the **same list** as HTTP requests, tagged with a `WS` badge; use the **All / HTTP / Socket** filter at the top to narrow down. Set `sockets: false` in `forRoot()` to turn socket capture off.
82
+
83
+
> Capture is on by default. For rare cases the automatic attachment can't reach (e.g. a single handler, or a gateway created outside the module scan), the `@TrackSocketEvents()` decorator is exported as an explicit opt-in — normally you won't need it.
73
84
74
85
## Database, Redis and HTTP capture is automatic
75
86
@@ -94,7 +105,7 @@ Everything is optional. These are the defaults:
94
105
95
106
```ts
96
107
DebugModule.forRoot({
97
-
enabled: process.env.NODE_ENV!=='production',
108
+
enabled: process.env.NODE_ENV!=='production',// NEST_DEBUG_PANEL_ENABLED env var overrides this
98
109
maxRequests: 200, // how many profiles to keep; oldest are evicted
99
110
captureRequestBody: true,
100
111
captureResponseBody: true,
@@ -103,6 +114,8 @@ DebugModule.forRoot({
103
114
captureSql: true,
104
115
captureRedis: true,
105
116
captureHttp: true,
117
+
captureLogs: true, // capture console.* emitted during a request (Logs monitor)
autoInstrument: true, // scan providers and hook them automatically
107
120
slowQueryThreshold: 100, // ms; queries at or above get flagged
108
121
slowRequestThreshold: 500, // ms; requests at or above get flagged
@@ -121,6 +134,22 @@ DebugModule.forRoot({
121
134
122
135
`forRootAsync({ imports, useFactory, inject, routePrefix })` works too. Note that `routePrefix` must be static in async mode, because routes are registered before async factories run.
123
136
137
+
### Enabling & disabling
138
+
139
+
The panel resolves its on/off state with this precedence (first match wins):
140
+
141
+
1.**`NEST_DEBUG_PANEL_ENABLED` environment variable** — when set to a recognized boolean, it overrides everything below, so you can flip the panel on or off **without changing code**.
142
+
2.**The `enabled` option** passed to `forRoot()` / `forRootAsync()`.
143
+
3.**Default** — on when `NODE_ENV !== 'production'`, off otherwise.
144
+
145
+
```bash
146
+
NEST_DEBUG_PANEL_ENABLED=true # force ON anywhere — even in production
147
+
NEST_DEBUG_PANEL_ENABLED=false # force OFF anywhere — even in development
148
+
# (unset) # fall back to the `enabled` option, then NODE_ENV
149
+
```
150
+
151
+
Accepted values are case-insensitive: `true` / `1` / `yes` / `on` enable it, `false` / `0` / `no` / `off` disable it. Anything unrecognized (or an unset/empty var) is ignored, so the option and `NODE_ENV` default still apply. When disabled, the interceptor passes every request straight through, nothing is instrumented or stored, and the dashboard routes return 404.
152
+
124
153
To exclude routes from profiling, use the `ignore` option (`'/health'`, globs like `'/static/*'`, or RegExps) or put `@DebugIgnore()` on a controller or handler. The panel's own routes are always excluded.
125
154
126
155
## Works with any ORM, any database
@@ -258,7 +287,7 @@ Build your own frontend or tooling on top of it if you like.
258
287
259
288
## Security
260
289
261
-
- Off in production automatically, unless you explicitly set `enabled: true`. When off, the interceptor passes requests straight through and the debug routes return 404.
290
+
- Off in production automatically, unless you set `enabled: true` or `NEST_DEBUG_PANEL_ENABLED=true` (see [Enabling & disabling](#enabling--disabling)). When off, the interceptor passes requests straight through and the debug routes return 404.
262
291
- Sensitive body keys and headers are redacted before anything is stored.
263
292
- Gate the dashboard with `authorize: (req) => req.user?.isAdmin === true`.
264
293
- Profiles live in process memory by default and never leave your machine.
0 commit comments