Back to docs
sdk
@nihal/flowlens-node
Backend span collection SDK for correlating server-side events with frontend traces. Supports Express, Fastify, and raw node:http.
Install
bash
npm install @nihal/flowlens-nodeExpress
Use flowlens() middleware for Express-style applications. CORS must allow the X-FlowLens-Trace-Id header.
typescript
import express from 'express'
import cors from 'cors'
import { flowlens } from '@nihal/flowlens-node'
const app = express()
app.use(cors({
origin: true,
allowedHeaders: ['Content-Type', 'X-FlowLens-Trace-Id']
}))
app.use(flowlens({
serviceName: 'my-api'
}))
app.get('/api/users', (req, res) => {
res.json({ users: [] })
})
app.listen(3000)Fastify
Use flowlensFastify() plugin for Fastify servers.
typescript
import Fastify from 'fastify'
import { flowlensFastify } from '@nihal/flowlens-node'
const app = Fastify()
app.register(flowlensFastify({
serviceName: 'my-api'
}))
app.get('/api/users', async () => {
return { users: [] }
})
app.listen({ port: 3000 })Raw HTTP
Use wrapHandler() for raw node:http servers.
typescript
import { createServer } from 'node:http'
import { wrapHandler } from '@nihal/flowlens-node'
const handler = (req, res) => {
res.writeHead(200)
res.end('OK')
}
const server = createServer(
wrapHandler(handler, { serviceName: 'my-api' })
)
server.listen(3000)Config
typescript
interface FlowLensNodeConfig {
serviceName: string // required
collectorUrl?: string // default: "http://localhost:9229"
enabled?: boolean // default: true
headerName?: string // default: "x-flowlens-trace-id"
}| Option | Default | Description |
|---|---|---|
serviceName | required | Name identifying your service in traces |
collectorUrl | "http://localhost:9229" | FlowLens span collector endpoint |
enabled | true | Enable/disable span reporting |
headerName | "x-flowlens-trace-id" | Header name for trace ID propagation |
How It Works
FlowLens auto-injects a X-FlowLens-Trace-Id header into all outgoing fetch/XHR requests from the embedded page. When a request hits your backend:
- 1. Reads the
X-FlowLens-Trace-Idheader. - 2. If no trace ID, passes through with zero overhead.
- 3. Captures stacks at: request (ingress), handler (execution), response (egress).
- 4. Sends the span payload fire-and-forget POST to the collector on
:9229.
Span Payload
typescript
// Fields sent to the collector
{
traceId: string
route: string
method: string
statusCode: number
duration: number
serviceName: string
timestamp: number
requestStack: string
handlerStack: string
responseStack: string
}The collector splits each span into three backend-span events with phases: request, handler, response.