@ktuban/structured-logger
v1.1.1
Published
A fast, developer-friendly, production-ready simple structured logger for Node.js with JSON output, pretty console logs, request-ID correlation, deep error serialization, redaction, and optional Express integration.
Downloads
146
Maintainers
Readme
@ktuban/structured-logger
Fast, developer-friendly, production-ready structured logger for Node.js with JSON output, pretty console logs, request-ID correlation, deep error serialization, field redaction, and optional Express integration.
✨ Features
- Structured Logging — JSON output for machine parsing, pretty console for development
- Request Correlation — Automatic request-ID tracking using AsyncLocalStorage
- Deep Error Serialization — Stack traces, cause chains, and error context
- Field Redaction — Automatically mask sensitive fields (passwords, tokens, etc.)
- Express Integration — Middleware for automatic request/response logging
- Async Context Isolation — AsyncLocalStorage for request scoping
- Performance Optimized — Minimal overhead, lazy serialization
- TypeScript First — Full type definitions, strict mode
- ESM/CJS Compatible — Works with both module systems
📦 Installation
npm install @ktuban/structured-loggerRequires: Node.js 18+
🚀 Quick Start
Basic Logging
import { StructuredLogger } from "@ktuban/structured-logger";
const logger = new StructuredLogger({
environment: "production",
appName: "my-service",
});
logger.info("User created", { userId: 123, email: "[email protected]" });
logger.error("Payment failed", { error, amount: 99.99 });
logger.warn("High response time", { duration: 5000 });Express Integration
import express from "express";
import { StructuredLogger } from "@ktuban/structured-logger";
const app = express();
const logger = new StructuredLogger({
environment: "production",
appName: "api-service",
redactFields: ["password", "token", "apiKey"],
});
// Automatic request/response logging
app.use(logger.expressMiddleware());
app.post("/login", (req, res) => {
logger.info("Login attempt", { email: req.body.email });
// password field automatically redacted
res.json({ success: true });
});Request Correlation
import { StructuredLogger } from "@ktuban/structured-logger";
const logger = new StructuredLogger();
async function handleRequest(req) {
const requestId = req.headers["x-request-id"];
// All logs within this context automatically include requestId
return logger.withRequestId(requestId, async () => {
logger.info("Processing request"); // includes requestId
// Nested calls automatically inherit the requestId
await callInternalService();
});
}
async function callInternalService() {
logger.info("Internal service called"); // includes same requestId
}📖 API Reference
StructuredLogger Constructor
const logger = new StructuredLogger({
environment: "production", // "development" | "staging" | "production"
appName: "my-service", // Service name
version: "1.0.0", // Optional version
defaultLevel: "info", // "debug" | "info" | "warn" | "error"
redactFields: [ // Fields to automatically mask
"password",
"token",
"apiKey",
"creditCard"
],
prettyPrint: true, // Pretty console output in dev
outputFormat: "json", // "json" | "pretty"
});Logging Methods
logger.debug(message, data);
logger.info(message, data);
logger.warn(message, data);
logger.error(message, data);
// Example
logger.error("Payment processing failed", {
error: new Error("Timeout"),
amount: 99.99,
attempt: 3,
});Output (JSON):
{
"level": "error",
"message": "Payment processing failed",
"timestamp": "2024-01-15T10:30:45.123Z",
"amount": 99.99,
"attempt": 3,
"error": {
"message": "Timeout",
"stack": "Error: Timeout\n at...",
"name": "Error"
}
}Request Correlation
// Bind a request ID to async context
logger.withRequestId(id, callback);
// Inside the callback and all nested calls:
logger.info("message"); // automatically includes requestId
// Manual context:
logger.setContext({ userId: 123, requestId: "req-456" });
logger.info("message"); // includes userId and requestIdError Handling
// Automatic error serialization
logger.error("Operation failed", { error });
// Includes:
// - Error message
// - Full stack trace
// - Cause chain (if present)
// - Context data
// Error with context
try {
await riskyOperation();
} catch (error) {
logger.error("Risky operation failed", {
error,
userId: req.user.id,
endpoint: req.path,
});
}Express Middleware
const logger = new StructuredLogger();
// Automatic request/response logging
app.use(logger.expressMiddleware({
includeRequestBody: false, // Don't log request body
includeResponseBody: false, // Don't log response body
redactPaths: ["/login"], // Skip logging for these paths
}));
// Adds to each request:
// - requestId (generated if not provided)
// - method, path, statusCode
// - duration
// - userId (if available)🎯 Best Practices
Use structured data instead of string concatenation
// ✅ Good logger.info("User created", { userId: 123 }); // ❌ Bad logger.info(`User ${123} created`);Include context for debugging
logger.error("API call failed", { error, endpoint: url, method: "POST", statusCode: 500, });Use appropriate levels
debug— Development/diagnostic infoinfo— Normal application flowwarn— Potentially problematic situationserror— Error events that might still allow the app to continue
Redact sensitive fields
const logger = new StructuredLogger({ redactFields: ["password", "token", "ssn", "creditCard"], });Leverage request correlation
// All logs within the request automatically correlated logger.withRequestId(req.id, async () => { await service1(); await service2(); // All logs include the same requestId });
🔐 Security Notes
- Sensitive fields are automatically redacted based on configured patterns
- Passwords, tokens, API keys should be added to
redactFields - Error stacks may contain sensitive info — review before production
- Request bodies should generally not be logged in production
- PII (personally identifiable information) should be handled carefully
☕ Support the Project
If this library helps you build observable systems, consider supporting ongoing development:
📄 License
MIT © K Tuban
🤝 Contributing
Pull requests are welcome. Please include tests and documentation updates.
🧭 Roadmap
- [ ] CloudWatch integration
- [ ] Datadog support
- [ ] Log sampling strategies
- [ ] Performance metrics collection
- [ ] Custom serializers
