Skip to content
Install · free

Bun / Node.js

Send logs and errors from Node.js and Bun to LogNorth: Express, Hono, and Next.js middleware, and a Pino transport.

Terminal window
npm install lognorth
import LogNorth from 'lognorth'
LogNorth.config('https://logs.yoursite.com', 'your-api-key')
LogNorth.log('User signed up', { user_id: 123 })
LogNorth.error('Checkout failed', err, { order_id: 42 })

LogNorth sends nothing when NODE_ENV is development or test, so a local run stays quiet. Every other environment sends, and each event gets context.environment. Set both yourself:

LogNorth.config(url, key, {
environment: 'staging', // default: NODE_ENV
enabled: true, // default: off in development and test
})

To try it from your machine, pass enabled: true.

// Express
import { middleware } from 'lognorth/express'
app.use(middleware())
// Hono
import { middleware } from 'lognorth/hono'
app.use(middleware())
// Next.js
import { withLogger } from 'lognorth/next'
export const GET = withLogger()(handler)

The middleware automatically:

  • Generates a trace_id per request (or uses X-Trace-ID from the incoming header)
  • Sets X-Trace-ID on the response
  • Logs the request with duration_ms and trace_id as top-level fields
  • All LogNorth.log() and LogNorth.error() calls within the request automatically inherit the same trace_id
app.use(middleware())
app.post('/users', (req, res) => {
// This log automatically gets the same trace_id as the middleware request log
LogNorth.log('User signed up', { user_id: 123 })
res.status(201).json({ ok: true })
})

Name the signed-in user inside a request. Use an ID, never an email:

LogNorth.setUser(user.id)

The issue page then shows how many users an issue hit. Errors also carry the release, from the release option or from LOGNORTH_RELEASE, GIT_SHA, KAMAL_VERSION, or your host’s commit variable. At startup the SDK logs Release <version> started, and LogNorth draws each deploy as a dashed line on its charts.

Skip health checks and other noisy endpoints:

app.use(middleware({
ignorePaths: ['/healthz', '/_health', '/metrics']
}))

These paths won’t be logged by the middleware.

Keep your existing logger, add LogNorth as a transport:

import pino from 'pino'
import { transport } from 'lognorth/pino'
LogNorth.config('https://logs.yoursite.com', 'your-api-key')
const logger = pino({ level: 'info' }, transport())
logger.info({ user_id: 123 }, 'User signed up')

Pass your logger to middleware:

app.use(middleware(logger))
Method Behavior
LogNorth.log() Batched (10 events or 5s)
LogNorth.error() Sent immediately with stack trace
Middleware Logs requests with trace_id + duration_ms
Shutdown Auto-flush on SIGINT/SIGTERM

LogNorth.error() automatically captures the error class, file, line, caller function, and stack trace. LogNorth groups errors into issues by them.