DEV Community

Cover image for I built a zero-config observability tool for Node.js that auto-detects N+1 queries
Vishal pathak
Vishal pathak

Posted on

I built a zero-config observability tool for Node.js that auto-detects N+1 queries

The problem
Every time I started a new Node.js project I faced the same choice:
Use Winston or Pino — simple, but I'm flying blind. No idea which routes are slow, which DB queries are killing performance, nothing.
Or set up Datadog — powerful, but $300/month and half a day of config just to see what's happening inside my app.
There had to be a middle ground.

What I built
DexterJS — an open source observability library for Node.js. One install, zero config, and you get:

  • Structured logging with automatic trace correlation
  • Auto instrumentation for Prisma, Drizzle, Mongoose, pg, Redis, axios and fetch
  • A live dashboard at localhost:4000
  • Automatic N+1 query detection

npm install @dexter.js/sdk


import express from 'express'
import 
{ createLogger, 
  monitor, 
  expressMiddleware
} from '@dexter.js/sdk'

const app = express()
app.use(expressMiddleware()) // must be first
app.use(express.json())

const logger = createLogger({
  level: 'debug',
  format: 'pretty',
  redact: ['password', 'token']
})

monitor({ app, logger })
// open localhost:4000 — your dashboard is live
Enter fullscreen mode Exit fullscreen mode

That's literally it. No config files. No cloud account. No API key.

The part I'm most proud of — N+1 detection
You know that bug where you fetch a list of users and then loop through them fetching their posts one by one? That's an N+1 query.

It's one of the most common performance killers in Node.js apps and normally you need a paid APM tool to catch it automatically.

DexterJS catches it for free. Hit a route that does N+1 queries and the Insights tab immediately flags it as CRITICAL:

  • CRITICAL — N+1 Query Detected
  • traceId abc123 issued 15 DB queries

Every DB call is traced and correlated with the request that triggered it. Click a log entry and see every Prisma query, Redis call, and outgoing HTTP request that happened during that request. All automatically.

How it works

The SDK is lightweight — it just collects and ships events via Unix socket to a sidecar process. The sidecar handles storage, aggregation and serves the dashboard. If your app crashes, the sidecar keeps running. If the sidecar crashes, your app is completely unaffected.

Auto instrumentation
Drop these in before your DB clients and everything gets traced automatically:

import {
  instrumentPg,
  instrumentPrisma,
  instrumentMongoose,
  instrumentRedis,
  instrumentDrizzle,
  instrumentHttp
} from '@dexter.js/sdk'

instrumentPg(Pool)
instrumentMongoose(mongoose)
instrumentHttp({ axios })

const redis = new Redis()
instrumentRedis(redis)

const prisma = instrumentPrisma(new PrismaClient())
const db = drizzle(instrumentDrizzle(pool))
Enter fullscreen mode Exit fullscreen mode

Every query gets: timing, traceId, target (e.g. GET cached:users, prisma.User.findMany), error if it fails.

Modular by design
Don't want the full stack? Use just what you need:
ts// just the logger

import { createLogger } from '@dexter.js/logger'

const logger = createLogger({
  level: 'info',
  format: 'pretty',
  redact: ['password'],
  file: {
    path: './logs',
    split: true,
    rotation: { maxSize: '10mb', maxFiles: 7, compress: true }
  }
})
Enter fullscreen mode Exit fullscreen mode

Honest comparison

What's next

v0.2.0 — hooks, alerts, request/response capture
v0.3.0 — TypeScript decorators (@trace, @log)
v1.0.0 — AI-powered analysis that tells you exactly why something is slow

Try it

npm install @dexter.js/sdk

Enter fullscreen mode Exit fullscreen mode

GitHub: github.com/dexter-js/dexterjs
I'm building this as a solo developer — feedback, issues, PRs all very welcome. If it saves you time, a ⭐ on GitHub means a lot.
What features would make you actually use this over your current setup? Drop a comment 👇

Top comments (0)