logdrive
Simple Node.js logger with request context.
Links
Creator
Install
npm install logdrive
Everything You Can Import
import {
initLogger,
Log,
requestContextMiddleware,
getContext,
contextStore
} from 'logdrive'
Exports from package:
initLogger(config)
Log (error, warning, notice, info, debug)
requestContextMiddleware
getContext()
contextStore
Quick Start (Express)
import express from 'express'
import { initLogger, requestContextMiddleware, Log } from 'logdrive'
const app = express()
app.use(requestContextMiddleware)
initLogger({
defaultMeta: { service: 'user-service' },
enableConsole: false,
logDir: 'logs',
maxFiles: '1d'
})
app.get('/health', (_req, res) => {
Log.info('health check ok', { route: '/health' }, 'HEALTH_01')
res.send('ok')
})
app.listen(3000)
Required Order
- Register
app.use(requestContextMiddleware) before routes.
- Call
initLogger(...) before any Log.* call.
- Use
Log.* anywhere after initialization.
If logger is not initialized, Log.* throws:
Logger not initialized. Call initLogger() first.
initLogger(config) - All Params
initLogger({
logLevel: 'debug',
logDir: 'logs',
maxSize: '20m',
maxFiles: '1d',
enableConsole: process.env.NODE_ENV === 'local',
defaultMeta: {}
})
Config fields:
logLevel?: string
- Default:
process.env.LOG_LEVEL || 'debug'
- Used for both logger level and file transport level.
logDir?: string
- Default:
'logs'
- Folder where rotated log files are written.
maxSize?: string
- Default:
'20m'
- Max file size before rotate.
maxFiles?: string
- Default:
'1d'
- Retention for rotated files.
enableConsole?: boolean
- Default:
process.env.NODE_ENV === 'local'
true adds console transport, false only writes file logs.
defaultMeta?: Record<string, unknown>
- Default:
{}
- Added to every log entry.
Built-in file transport behavior:
filename: app-%DATE%.log
datePattern: YYYY-MM-DD
- file format: JSON
- timestamp format:
YYYY-MM-DD HH:mm:ss
Log - All Methods And Params
Every method has same signature:
(message: string, data?: unknown, code?: string | number)
import { Log } from 'logdrive'
Log.error('failed to save user', new Error('db timeout'), 'USR_5001')
Log.warning('slow query detected', { ms: 900 }, 'PERF_1001')
Log.notice('job started', { job: 'daily-sync' }, 'JOB_0001')
Log.info('login success', { userId: 'u_123' }, 'AUTH_2001')
Log.debug('payload', { body: { name: 'Sam' } }, 'DBG_0001')
Method list:
Log.error(...)
Log.warning(...)
Log.notice(...)
Log.info(...)
Log.debug(...)
What data supports:
- plain values
- objects and arrays
Error objects (serialized to message, name, stack, cause)
- circular objects (safe, circular refs become
"[Circular]")
requestContextMiddleware
import { requestContextMiddleware } from 'logdrive'
app.use(requestContextMiddleware)
What it sets per request context:
requestId
- from header
x-request-id if present
- otherwise generated with
crypto.randomUUID()
ip from request-ip
method from req.method
url from req.originalUrl
userAgent from request header
Those values are automatically merged into every Log.* call in that request.
getContext() And contextStore
getContext()
import { getContext } from 'logdrive'
app.use((req, _res, next) => {
const ctx = getContext()
if (ctx) {
ctx.userId = 'u_123'
}
next()
})
Return type:
RequestContext | undefined
RequestContext shape:
interface RequestContext {
requestId: string
ip: string
method: string
url: string
userId?: string
userAgent?: string
}
contextStore
import { contextStore } from 'logdrive'
contextStore.run(
{
requestId: 'manual-id',
ip: '127.0.0.1',
method: 'GET',
url: '/manual'
},
() => {
}
)
Full Example With All Main Imports
import express from 'express'
import {
initLogger,
requestContextMiddleware,
Log,
getContext
} from 'logdrive'
const app = express()
app.use(requestContextMiddleware)
app.use((req, _res, next) => {
const ctx = getContext()
if (ctx) {
ctx.userId = req.headers['x-user-id'] as string | undefined
}
next()
})
initLogger({
defaultMeta: { service: 'user-service', env: process.env.NODE_ENV },
enableConsole: false,
logDir: 'logs',
maxFiles: '1d',
maxSize: '20m',
logLevel: 'debug'
})
app.get('/users', (_req, res) => {
Log.info('list users', { ok: true }, 'USR_2000')
res.json({ ok: true })
})
app.listen(3000, () => {
Log.notice('server started', { port: 3000 }, 'SRV_0001')
})
Notes
- Works in Node.js.
- Express middleware typing is used in
requestContextMiddleware.
- File logging is always enabled. Console logging is optional.
Keywords
- logger
- logging
- nodejs
- typescript
- winston
- express
- middleware
- request-context
- async-local-storage
- structured-logging
- json-logs
- daily-rotate-file
- observability
- tracing
- request-id