
Security News
PolinRider: North Korea-Linked Supply Chain Campaign Expands Across Open Source Ecosystems
PolinRider expands across npm, Packagist, Go modules, and Chrome extensions, using hidden loaders to target developer environments.
@blue.ts/logging
Advanced tools
Structured logging for blue.ts. Pino-compatible JSON output with child loggers, pluggable transports, and per-request scoped context via the DI container.
Structured logging for blue.ts. Pino-compatible JSON output with child loggers, pluggable transports, and per-request scoped context via the DI container.
bun add @blue.ts/logging
import { LoggingModule, ConsoleTransport } from '@blue.ts/logging';
app.registerProvider(
new LoggingModule({
transports: [new ConsoleTransport()],
level: 'info',
fields: { service: 'api', version: '1.0.0' },
})
);
Logger writes structured JSON entries across six severity levels.
import { Logger, ConsoleTransport } from '@blue.ts/logging';
const logger = new Logger({
transports: [new ConsoleTransport()],
level: 'info', // minimum level to emit (default: 'info')
fields: { service: 'api' } // merged into every entry
});
logger.trace('Verbose detail');
logger.debug('Debug info');
logger.info('Server started', { port: 3000 });
logger.warn('Slow query', { durationMs: 320, query: 'SELECT ...' });
logger.error('Request failed', { error: err.message });
logger.fatal('Unrecoverable error');
| Level | Numeric | Use |
|---|---|---|
trace | 10 | Highly verbose debugging |
debug | 20 | Development debugging |
info | 30 | Normal operational events |
warn | 40 | Unexpected but recoverable |
error | 50 | Failures that need attention |
fatal | 60 | Process-ending errors |
Child loggers inherit parent transports, level, and fields — and merge in their own:
const reqLogger = logger.child({ reqId: crypto.randomUUID(), userId: 'u123' });
reqLogger.info('Processing request');
// → { "level": 30, "msg": "Processing request", "service": "api", "reqId": "...", "userId": "u123" }
LoggingModule is a ConfigProvider that wires the logger into the DI container.
It registers two tokens:
| Token | Lifetime | Description |
|---|---|---|
LoggerToken | singleton | Root logger — same instance for the process lifetime |
RequestLoggerToken | scoped | Child logger with a unique reqId per request |
import { LoggingModule, ConsoleTransport, LoggerToken, RequestLoggerToken } from '@blue.ts/logging';
import type { ILogger } from '@blue.ts/logging';
app.registerProvider(
new LoggingModule({
transports: [new ConsoleTransport()],
level: 'debug',
fields: { service: 'my-api', env: process.env.NODE_ENV },
})
);
// Inject into a class-based handler
class MyHandler {
constructor(private readonly log: ILogger) {}
handle(ctx) {
this.log.info('Handling request', { path: ctx.req.url });
return Context.json({ ok: true });
}
}
app.registerDependency(MyHandler, {
lifetime: 'transient',
factory: async (c) => new MyHandler(await c.get(RequestLoggerToken)),
});
Writes JSON entries to stdout. Best for development and containerised deployments.
import { ConsoleTransport } from '@blue.ts/logging';
new ConsoleTransport()
// → {"level":30,"time":1712345678901,"pid":12345,"hostname":"host","msg":"..."}
Appends newline-delimited JSON to a file. Rotates when the file exceeds maxBytes.
import { FileTransport } from '@blue.ts/logging';
new FileTransport({
path: './logs/app.log',
maxBytes: 10 * 1024 * 1024, // 10 MB — rotate after this size
});
Offloads all I/O to a Bun Worker thread so the main thread is never blocked.
import { BunWorkerTransport } from '@blue.ts/logging';
const transport = new BunWorkerTransport({
path: './logs/app.log',
maxBytes: 10 * 1024 * 1024,
});
// At graceful shutdown — flush and close the worker
await transport.flush();
await transport.close();
new LoggingModule({
transports: [
new ConsoleTransport(),
new BunWorkerTransport({ path: './logs/app.log' }),
],
level: 'info',
});
Implement the Transport interface to write to any backend:
import type { Transport, LogEntry } from '@blue.ts/logging';
class DatadogTransport implements Transport {
write(entry: LogEntry): void {
fetch('https://http-intake.logs.datadoghq.com/api/v2/logs', {
method: 'POST',
body: JSON.stringify(entry),
headers: { 'DD-API-KEY': process.env.DD_API_KEY! },
});
}
async flush(): Promise<void> { /* wait for in-flight requests */ }
}
All entries follow the pino JSON format:
{
"level": 30,
"time": 1712345678901,
"pid": 12345,
"hostname": "api-server-1",
"msg": "Request completed",
"service": "api",
"reqId": "a1b2c3d4",
"method": "GET",
"path": "/users",
"durationMs": 12
}
Compatible with pino-pretty for human-readable local development output:
bun run index.ts | bunx pino-pretty
FAQs
Structured logging for blue.ts. Pino-compatible JSON output with child loggers, pluggable transports, and per-request scoped context via the DI container.
The npm package @blue.ts/logging receives a total of 17 weekly downloads. As such, @blue.ts/logging popularity was classified as not popular.
We found that @blue.ts/logging demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
PolinRider expands across npm, Packagist, Go modules, and Chrome extensions, using hidden loaders to target developer environments.

Security News
Open source attacks are accelerating as AI coding agents pull in dependencies faster, with less human review.

Research
/Security News
Malicious Chrome and Firefox extensions posed as free VPNs while stealing clipboard data through later extension updates.