@alkemic/logger-nextjs
v0.1.10
Published
π§ Sorry folks! This library is currently built for our internal services only. But donβt worry β weβre planning to release a public version in the future! π
Readme
@alkemic/logger-nextjs
π§ Sorry folks! This library is currently built for our internal services only. But donβt worry β weβre planning to release a public version in the future! π
β‘οΈ Powered by Pino and Winston, this logger runs smoothly on both the server π and client π» sides β no need to choose sides, it plays nice everywhere! π
π Table of Contents
- Installation
- Quick Start
- Usage Examples
- Testing
- Environment Variables
- Scripts
- Configuration
- Features
- Log Levels
- Architecture
π¦ Installation
npm install @alkemic/logger-nextjsοΏ½ Quick Start
- Create a shared logger using
createLogger()in a module likelib/logger.tsand export it for reuse. - Derive contextual child loggers with
logger.child({ ...metadata })inside API handlers, React components, and edge middleware. - Tune runtime behavior by setting the environment variables documented in βοΈ Configuration before booting your app.
- Validate the setup by running
npm test, which exercises Winston, Pino, and environment-specific flows end to end.
π Usage Examples
Basic Setup
// lib/logger.ts
import { createLogger } from '@alkemic/logger-nextjs';
export const logger = await createLogger();Server-side Usage
// app/api/users/route.ts
import { logger } from '@/lib/logger';
export async function GET() {
const requestLogger = logger.child({
module: 'users-api',
requestId: crypto.randomUUID()
});
requestLogger.info('Starting user list retrieval');
try {
const users = await fetchUsers();
requestLogger.info('User retrieval completed', { count: users.length });
return Response.json(users);
} catch (error) {
requestLogger.error('User retrieval failed', error);
return Response.json({ error: 'Server error' }, { status: 500 });
}
}Client-side Usage
// components/LoginForm.tsx
"use client"
import { logger } from '@/lib/logger';
import { useState } from 'react';
export default function LoginForm() {
const [loading, setLoading] = useState(false);
const formLogger = logger.child({ component: 'LoginForm' });
const handleSubmit = async (formData: FormData) => {
formLogger.info('Login attempt started');
setLoading(true);
try {
// Sensitive data is automatically masked
formLogger.debug('Login request data', {
username: formData.get('username'),
password: formData.get('password'), // Masked as [REDACTED]
timestamp: new Date().toISOString()
});
const result = await fetch('/api/auth/login', {
method: 'POST',
body: formData
});
if (result.ok) {
formLogger.info('Login successful');
} else {
formLogger.warn('Login failed', { status: result.status });
}
} catch (error) {
formLogger.error('Login error', error);
} finally {
setLoading(false);
}
};
return (
<form action={handleSubmit}>
{/* form fields */}
</form>
);
}Edge Runtime Usage
// middleware.ts
import { logger } from '@/lib/logger';
import { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const middlewareLogger = logger.child({
middleware: 'auth',
path: request.nextUrl.pathname
});
// Edge Runtime outputs in Pino JSON format
middlewareLogger.info('Middleware execution', {
method: request.method,
userAgent: request.headers.get('user-agent')
});
return NextResponse.next();
}π§ͺ Testing
# Run the full matrix (production β development β verbose β edge β winston features)
npm test
# Individual test execution
npm run test:prod # Production environment test (info level and above)
npm run test:dev # Development environment test (debug level enabled)
npm run test:verbose # Verbose level test (shows all logs)
npm run test:edge # Edge Runtime test (Pino JSON output)
npm run test:winston-features # Winston advanced features testπ Test Coverage
| File | Description |
|------|-------------|
| basic.test.ts | β
Basic log level testing (verbose, debug, info, warn, error, fatal)β
Child logger creation and nesting testsβ
Error handling and stack trace testsβ
Verbose level detailed testsβ
Environment variable combination tests (SERVER_ENV, LOG_LEVEL) |
| edge.test.ts | β
Pino JSON output format validationβ
Edge Runtime environment detectionβ
UTF-8 encoding support |
| winston-features.test.ts | β
File logging (daily logs saved in logs/ folder)β
Sensitive data masking ([REDACTED] processing)β
Single-line/multi-line object output formatsβ
Large dataset processingβ
Nested object and array sensitive data masking |
π§ Environment Variables
Environment variables supported in testing and actual usage:
| Variable | Values | Description |
|----------|--------|-------------|
| SERVER_ENV | development | production | Adjusts log levels based on the environment. |
| LOG_LEVEL | verbose | debug | info | warn | error | fatal | Sets the minimum log level to output. |
| NEXT_RUNTIME | edge | Triggers the Pino logger for Edge Runtime. |
| LOG_USE_FILE | true | false | Enables or disables logging to daily rotated files (Winston only). |
| LOG_SENSITIVE_KEYS | Comma-separated string | Specifies keys to mask (e.g., password,secret,token). |
| LOG_USE_SINGLE_LINE_OBJ | true | false | Toggles between single-line and multi-line object logging (Winston only). |
π§° Scripts
| Script | Description |
|--------|-------------|
| npm run build | Cleans the lib/ folder, compiles TypeScript, and rewrites path aliases with tsc-alias. |
| npm run watch | Rebuilds continuously via tsc-watch and re-applies tsc-alias on each successful compilation. |
| npm run clean | Removes all build artifacts under lib/. |
| npm test | Executes the full test matrix (test:prod β test:dev β test:verbose β test:edge β test:winston-features). |
| npm run test:prod | Runs basic.test.ts with SERVER_ENV=production. |
| npm run test:dev | Runs basic.test.ts with SERVER_ENV=development. |
| npm run test:verbose | Runs basic.test.ts with verbose logging enabled. |
| npm run test:edge | Runs edge.test.ts with NEXT_RUNTIME=edge to validate the Pino setup. |
| npm run test:winston-features | Runs winston-features.test.ts focusing on file logging, masking, and formatting. |
βοΈ Configuration
Environment Variables Setup
# .env.local (Next.js)
SERVER_ENV=development
LOG_LEVEL=debug
LOG_USE_FILE=true
LOG_SENSITIVE_KEYS=password,secret,token,apiKey,authorization
LOG_USE_SINGLE_LINE_OBJ=falseWinston File Logging
When file logging is enabled, daily log files are created in the logs/ folder:
logs/
βββ 2025-09-28-00.log # Logs from 00:00~23:59
βββ 2025-09-28-01.log
βββ ...Sensitive Data Masking
The following keys are automatically masked as [REDACTED]:
// Default sensitive keys
const defaultSensitiveKeys = ['password', 'secret', 'token', 'apiKey'];
// Additional configuration via environment variables
LOG_SENSITIVE_KEYS=password,secret,token,apiKey,authorization
// Recursive masking for nested objects and arrays
logger.info('User data', {
users: [
{ id: 1, name: 'User1', password: 'secret123' }, // password: '[REDACTED]'
{ id: 2, name: 'User2', token: 'jwt-token' } // token: '[REDACTED]'
]
});Character Encoding Issues
If you see garbled characters in PowerShell:
# Set PowerShell UTF-8 encoding
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
# Then run tests
npm test⨠Features
π Universal Compatibility
- Node.js Server: Winston-based formatted text output
- Edge Runtime: Pino-based high-performance JSON output
- Browser: Pino-based JSON output
π§ Advanced Architecture
- Adapter Pattern: Unified
Loggerinterface for both Winston and Pino - Fatal Level Support: Complete support for fatal(60) log level in Winston
- Stack Trace Preservation: Direct method binding for accurate call site tracking
- TypeScript-first API: Published with
.d.tsdefinitions for strong typing in editors and builds
π Child Logger System
- Context Binding: Trackable logs with
logger.child({ requestId, module }) - Nested Child Support: Create child loggers from existing child loggers
- Metadata Inheritance: Automatic inheritance of parent metadata
π‘οΈ Winston Advanced Features
- π File Logging: Automatic daily log file generation and rotation
- π Sensitive Data Masking: Auto
[REDACTED]for password, token, secret, etc. - π Output Format Control: Single-line or multi-line object output
- π Recursive Masking: Masks sensitive data within nested objects and arrays
π Log Levels
| Level | Priority | Usage | Example |
|-------|----------|-------|---------|
| verbose | 1 | Most detailed debug information | Function entry/exit, variable values |
| debug | 2 | Development stage debugging | Information needed only in dev environment |
| info | 3 | General application information | User actions, API requests |
| warn | 4 | Warning messages | Deprecated API usage |
| error | 5 | Error occurrences | Exception handling, failed operations |
| fatal | 6 | Critical errors | Application termination level |
π Environment-based Log Levels
development: Showsdebuglevel and aboveproduction: Showsinfolevel and aboveverbosesetting: Shows all levels
ποΈ Architecture
Adapter Pattern Implementation
βββββββββββββββββββββββββββββββββββββββ
β createLogger() β
βββββββββββββββ¬ββββββββββββββββββββββββ
β
βββββββββββΌββββββββββ
β Environment Check β
βββββββββββ¬ββββββββββ
β
ββββββββββΌβββββββββ
β NEXT_RUNTIME ? β
βββββββ¬ββββββ¬ββββββ
β β
ββββββββΌβββ ββΌβββββββββββ
β edge β β nodejs β
β β β β
β Pino β β Winston β
β JSON β β Formatted β
ββββββββ¬βββ ββ¬βββββββββββ
β β
βββββββΌββββββ
β AdapterLogger β
β β
β - verbose() β
β - debug() β
β - info() β
β - warn() β
β - error() β
β - fatal() β
β - child() β
βββββββββββββββFile Structure
src/
βββ index.ts # Main entry point
βββ defs.ts # Type definitions and Winston configuration
βββ adapter-logger.ts # Unified adapter class
βββ winston-server.ts # Winston server factory
βββ winston-formats.ts # Winston formatter and sensitive data masking
βββ pino-edge.ts # Pino Edge Runtime factory
βββ pino-browser.ts # Pino browser factory
tests/
βββ basic.test.ts # Basic functionality + environment variable tests
βββ edge.test.ts # Edge Runtime specific tests
βββ winston-features.test.ts # Winston advanced feature tests