@igniter-js/logger
v0.1.0
Published
Pino-based logger abstraction for Igniter.js
Readme
@igniter-js/logger
High-performance logging for Igniter.js applications powered by Pino.
Note: HTTP transport currently uses a fallback implementation. For production HTTP logging, use external Pino transports like @axiomhq/pino or @logtail/pino.
Features
- ✅ Zero Pino API exposure - Work with Igniter abstractions
- ✅ High performance - Built on Pino (5-10x faster than alternatives)
- ✅ Built-in transports - Console, File, HTTP out of the box
- ✅ External transport support - Use any Pino transport (pino-pretty, @logtail/pino, etc.)
- ✅ Type-safe child loggers - Scoped context with full type inference
- ✅ Pretty dev logging - Colorized, human-readable logs by default
- ✅ Production-ready - File rotation, batching, remote logging
- ✅ Server-only - Protected from browser imports
Installation
npm install @igniter-js/logger
# or
pnpm add @igniter-js/logger
# or
yarn add @igniter-js/logger
# or
bun add @igniter-js/loggerQuick Start
import { IgniterLogger } from "@igniter-js/logger";
// Create logger (default: pretty console logging)
const logger = IgniterLogger.create().build();
// Log messages
logger.info("Application started");
logger.error("Something went wrong", { errorCode: 500 });
logger.success("Deployment completed");Why @igniter-js/logger
- Consistent log structure across Igniter packages
- Transport-first design with safe defaults for development
- Context everywhere with base context, scoped children, and payloads
- Server-only safety to prevent accidental browser usage
Core Concepts
Builder (IgniterLogger)
-> Transport configuration
-> Context and level defaults
-> build()
|
v
Manager (IgniterLoggerManager)
-> Log methods (info/warn/error/etc.)
-> Child loggers
-> Runtime controls (setLevel/flush)Builder API
Basic Configuration
import { IgniterLogger, IgniterLogLevel } from "@igniter-js/logger";
const logger = IgniterLogger.create()
.withLevel(IgniterLogLevel.Debug)
.withAppName("my-api")
.withComponent("auth")
.withContext({ version: "1.0.0" })
.build();Built-in Transports
Console Transport
const logger = IgniterLogger.create()
.addTransport({
target: "console",
options: {
pretty: true, // Pretty formatting (default: true)
colorize: true, // Colors (default: true)
},
})
.build();File Transport
const logger = IgniterLogger.create()
.addTransport({
target: "file",
options: {
path: "/var/log/app.log",
mkdir: true, // Create directory if missing
rotation: {
maxSizeBytes: 10_000_000,
maxFiles: 10,
intervalMs: 86_400_000,
},
},
})
.build();HTTP Transport
const logger = IgniterLogger.create()
.addTransport({
target: "http",
options: {
url: "https://logs.myapp.com/ingest",
headers: { "X-API-Key": process.env.LOG_API_KEY ?? "" },
batchSize: 100,
timeoutMs: 10_000,
},
})
.build();Note: The current HTTP transport resolver maps to a Pino file target internally. HTTP delivery is not implemented yet. Track updates in AGENTS.md.
External Transports
Use any Pino transport from the ecosystem:
// npm install pino-pretty
const logger = IgniterLogger.create()
.addTransport({
target: "pino-pretty",
options: {
colorize: true,
translateTime: "SYS:standard",
},
})
.build();Type-Safe Scoped Loggers
const logger = IgniterLogger.create()
.defineScopes<{
http: { requestId: string; method: string };
jobs: { jobId: string; queueName: string };
}>()
.build();
// ✅ Type-safe
const httpLogger = logger.child("http", {
requestId: "req-123",
method: "POST",
});
// ❌ Type error: missing "method"
const invalid = logger.child("http", { requestId: "req-123" });Manager API
Log Levels
logger.fatal("Critical system failure");
logger.error("Request failed", { statusCode: 500 });
logger.warn("Deprecated API usage");
logger.info("User logged in", { userId: "123" });
logger.debug("Cache hit", { key: "user:123" });
logger.trace("Function entry", { args: [1, 2, 3] });Custom Methods
// Success logging
logger.success("Deployment completed");
// Grouping
logger.group("Processing batch");
logger.info("Item 1");
logger.info("Item 2");
logger.groupEnd();
// Separator
logger.separator();Child Loggers
const httpLogger = logger.child("http", {
requestId: "req-123",
method: "POST",
});
httpLogger.info("Request received");
// Logs: { component: "http", requestId: "req-123", method: "POST", msg: "Request received" }Runtime Controls
import { IgniterLogLevel } from "@igniter-js/logger";
// Change log level at runtime
logger.setLevel(IgniterLogLevel.Debug);
// Update app name (does not retroactively update Pino base)
logger.setAppName("new-name");
// Flush buffered logs
await logger.flush();API Reference
Builder Methods
IgniterLogger.create()withLevel(level: IgniterLogLevel)withAppName(appName: string)withComponent(component: string)withContext(context: Record<string, unknown>)addTransport(transport: IgniterTransportConfig)defineScopes<T>()build()
Manager Methods
log(level, message, context?, error?)fatal(message, error?)error(message, error?)warn(message, ...args)info(message, ...args)debug(message, ...args)trace(message, ...args)success(message, ...args)group(name?)groupEnd()separator()child(componentName, context?)setLevel(level)setAppName(appName)setComponent(componentName)flush()
Types
IgniterLogLevel(enum)IgniterTransportTarget("console" | "file" | "http" | string)IgniterTransportConfig<TOptions>ConsoleTransportOptionsFileTransportOptionsHttpTransportOptions
Log Level Enum
import { IgniterLogLevel } from "@igniter-js/logger";
const level = IgniterLogLevel.Info;Transport Options
| Transport | Option | Type | Description | | --- | --- | --- | --- | | Console | colorize | boolean | ANSI colors for output | | Console | pretty | boolean | Pretty-print JSON output | | Console | destination | string | stdout/stderr or custom stream | | File | path | string | Output file path | | File | mkdir | boolean | Create directories when missing | | File | rotation | boolean | object | File rotation options | | HTTP | url | string | Ingest endpoint | | HTTP | headers | Record<string, string> | Request headers | | HTTP | batchSize | number | Entries per batch | | HTTP | timeoutMs | number | Timeout in ms |
Examples
The examples folder is scaffolded but currently contains placeholders only. It will be populated alongside export wiring.
Production Best Practices
Disable pretty printing in production:
const logger = IgniterLogger.create() .addTransport({ target: "console", options: { pretty: false } }) .build();Use file transport with rotation:
const logger = IgniterLogger.create() .addTransport({ target: "file", options: { path: "/var/log/app.log", mkdir: true, }, }) .build();Never log PII:
// ❌ Bad logger.info("User logged in", { email, password }); // ✅ Good logger.info("User logged in", { userId: user.id });Use child loggers for context:
const requestLogger = logger.child("http", { requestId });
Troubleshooting
TRANSPORT_INVALID
Cause: Invalid transport target specified.
Solution: Use "console", "file", "http", or a valid Pino transport name.
LEVEL_INVALID
Cause: Invalid log level.
Solution: Use IgniterLogLevel values: fatal, error, warn, info, debug, trace.
File logs not appearing
Cause: Buffered writes not flushed.
Solution: Call await logger.flush() before process exit.
Note: Error codes above exist in the registry but are not thrown yet in v0.0.1. Validation will be added alongside export wiring.
Testing
pnpm test --filter @igniter-js/loggerFramework Integration
Next.js (API Route)
import { IgniterLogger } from "@igniter-js/logger";
const logger = IgniterLogger.create().withComponent("api").build();
export default function handler(req, res) {
const requestLogger = logger.child("http", { requestId: req.headers["x-request-id"] });
requestLogger.info("Incoming request", { method: req.method, path: req.url });
res.status(200).json({ ok: true });
}Express
import express from "express";
import { IgniterLogger } from "@igniter-js/logger";
const app = express();
const logger = IgniterLogger.create().withComponent("http").build();
app.get("/health", (req, res) => {
logger.info("Health check", { requestId: req.header("x-request-id") });
res.json({ ok: true });
});Fastify
import Fastify from "fastify";
import { IgniterLogger } from "@igniter-js/logger";
const app = Fastify();
const logger = IgniterLogger.create().withComponent("http").build();
app.get("/health", async (request) => {
logger.info("Health check", { requestId: request.headers["x-request-id"] });
return { ok: true };
});Documentation
- AGENTS.md - Complete technical reference
- Igniter.js Docs
- Examples
License
MIT © Felipe Barcelos
