@rezamirzapour/logger
v1.0.1
Published
Isomorphic, zero-dependency universal logger for Next.js with automatic sensitive data masking and optional server Winston file logger.
Maintainers
Readme
@rezamirzapour/logger 📜
An enterprise-grade, isomorphic, zero-dependency logger for Next.js applications with automatic sensitive data masking, latency metrics, and an optional server-side Winston file logger.
📑 Table of Contents
- Features
- Installation
- Usage with @rezamirzapour/http
- Universal Console Logger (Client & Server)
- Server-Only Winston Adapter
- Standalone Masking Utilities
- API Reference
- License
✨ Features
- 🌐 100% Isomorphic & Safe: Runs without issues in Client Components (
"use client"), Server Components (RSC), Server Actions, Route Handlers, and Edge Runtime (zerofscrashes in the browser). - 🔒 Automatic Sensitive Data Masking: Automatically masks tokens, passwords, cookies, authorization headers, and API keys (
Authorization: Bearer 1234******5678). - ⏱️ Latency & HTTP Metrics: Track request durations, HTTP status codes, method, and query parameters cleanly.
- 📁 Optional Server Winston Adapter: Zero client bundle footprint; import
@rezamirzapour/logger/serverto record structured JSON logs to files (log-info.txt,log-error.txt). - ⚡ Zero Runtime Dependencies (Core): Minimal overhead and lightweight bundle size.
📦 Installation
npm install @rezamirzapour/logger
# or
pnpm add @rezamirzapour/logger
# or
yarn add @rezamirzapour/loggerIf you plan to use file-based logging on the Node.js server with Winston:
npm install winston🚀 Usage with @rezamirzapour/http
@rezamirzapour/logger is designed to pair perfectly with @rezamirzapour/http to observe and log HTTP network calls securely.
1. Default Out-of-the-Box Logging
The @rezamirzapour/http package comes pre-configured with @rezamirzapour/logger metrics hooks:
// lib/http.ts
import { httpService } from '@rezamirzapour/http';
// Every request automatically logs metrics and errors with masked sensitive headers!
// Output: [NEXT-KIT] GET /api/users/1 [200] (42ms) { headers: { authorization: 'Bearer 1234******5678' } }
const user = await httpService.get('/api/users/1');2. Custom Client Metrics Hook
Configure custom before/after/error lifecycle hooks with @rezamirzapour/logger in your HTTP client:
// lib/http.ts
import { createNextHttp } from '@rezamirzapour/http';
import { defaultLogger, maskSensitiveData } from '@rezamirzapour/logger';
export const http = createNextHttp({
baseUrl: process.env.NEXT_PUBLIC_API_URL || 'https://api.example.com',
serviceName: 'user-service',
// Successful response hook
after: [
(context) => {
defaultLogger.info({
serviceName: context.serviceName,
method: context.method,
url: context.url,
durationMs: context.durationMs,
status: context.status,
headers: maskSensitiveData(context.headers),
params: context.params,
});
},
],
// Error handling hook
error: [
(context) => {
defaultLogger.error({
serviceName: context.serviceName,
method: context.method,
url: context.url,
durationMs: context.durationMs,
status: context.status,
error: context.error?.message || context.error,
response: context.response,
headers: maskSensitiveData(context.headers),
});
},
],
});3. Server-Side Winston File Logging (log-info.txt & log-error.txt)
In Next.js Server Components, Server Actions, or Route Handlers, write all HTTP requests to structured JSON log files:
// server/http.ts (Server-only context)
import { createNextHttp } from '@rezamirzapour/http';
import { RequestLogger } from '@rezamirzapour/logger/server';
// Create a server-side Winston file logger
const serverLogger = new RequestLogger({
infoLogPath: './applog/log-info.txt',
errorLogPath: './applog/log-error.txt',
version: process.env.APP_VERSION || '1.0.0',
});
export const serverHttp = createNextHttp({
baseUrl: process.env.BACKEND_INTERNAL_URL,
serviceName: 'backend-gateway',
after: [
(ctx) => {
serverLogger.info({
serviceName: ctx.serviceName,
method: ctx.method,
url: ctx.url,
durationMs: ctx.durationMs,
params: ctx.params,
headers: ctx.headers, // Auto-masked!
});
},
],
error: [
(ctx) => {
serverLogger.error({
serviceName: ctx.serviceName,
method: ctx.method,
url: ctx.url,
durationMs: ctx.durationMs,
params: ctx.params,
headers: ctx.headers,
response: ctx.response,
error: ctx.error,
});
},
],
});The resulting log-info.txt file will contain clean JSON records:
{"version":"1.0.0","type":"HTTP_REQUEST","service":{"name":"backend-gateway","method":"GET","url":"https://api.internal/users","queryParams":null,"headers":{"authorization":"Bearer 1234******5678"}},"durationMs":34,"level":"info","timestamp":"2026-09-04T12:00:00.000Z"}4. Custom Sensitive Field Masking
Mask proprietary custom keys (e.g. nationalId, creditCard, cvv, ssn) in HTTP payloads:
import { maskSensitiveData } from '@rezamirzapour/logger';
const rawPayload = {
username: 'reza',
token: 'jwt.token.secret1234',
creditCard: '4111222233334444',
cvv: '123',
};
// Mask default sensitive keys + custom keys
const safePayload = maskSensitiveData(rawPayload, ['creditCard', 'cvv']);
console.log(safePayload);
/*
Output:
{
username: 'reza',
token: 'jw********34',
creditCard: '4111********4444',
cvv: '****'
}
*/💻 Universal Console Logger (Client & Server)
The ConsoleLogger can be used directly for general logging across your Next.js application:
import { ConsoleLogger, defaultLogger } from '@rezamirzapour/logger';
// 1. Using the default instance
defaultLogger.info('Application started successfully');
defaultLogger.warn('Database connection latency high', { latencyMs: 350 });
defaultLogger.error('Failed to process payment', { orderId: '1092', error: 'Insufficient funds' });
// 2. Creating a custom logger with prefix
const customLogger = new ConsoleLogger({
prefix: '[AUTH-SERVICE]',
sensitiveKeys: ['refreshToken', 'privateKey'],
enabled: process.env.NODE_ENV !== 'production',
});
customLogger.info('User session created', {
userId: 'usr_882',
refreshToken: 'secret-refresh-token-value', // Masked automatically!
});🖥️ Server-Only Winston Adapter
Import from @rezamirzapour/logger/server to access the Winston file logger. Because this is placed in a separate export path, it will never leak fs or Node.js built-in modules into client bundles:
// app/api/example/route.ts
import { RequestLogger } from '@rezamirzapour/logger/server';
const logger = new RequestLogger({
infoLogPath: './applog/log-info.txt',
errorLogPath: './applog/log-error.txt',
version: '1.0.0',
enableConsole: true,
});
logger.info({
serviceName: 'orderService',
method: 'POST',
url: 'https://api.backend.com/orders',
durationMs: 95,
headers: { token: 'secret-token' },
});🔒 Standalone Masking Utilities
Use the standalone masking functions in any part of your code:
import { maskString, maskSensitiveData } from '@rezamirzapour/logger';
// 1. Mask a single string
maskString('my-secret-token');
// => "my-******en"
// 2. Custom visible characters
maskString('12345678901234', { showCharCount: 3 });
// => "123********234"
// 3. Short strings are completely masked
maskString('pass');
// => "****"
// 4. Recursive object masking
const cleanObject = maskSensitiveData({
user: 'admin',
password: 'superSecretPassword123',
apiKey: 'ak_live_abcdef123456',
});📜 API Reference
ConsoleLogger(options?: ConsoleLoggerOptions)
options.prefix: string prefix for log output (default:"[NEXT-KIT]").options.enabled: boolean flag to enable/disable logs (default:true).options.sensitiveKeys: array of additional sensitive keys to mask.
RequestLogger(options?: RequestLoggerOptions) (Server only)
options.infoLogPath: path to info log file (default:'./applog/log-info.txt').options.errorLogPath: path to error log file (default:'./applog/log-error.txt').options.version: application version tag.options.enableConsole: also print to terminal console (default:true).
maskSensitiveData(data: any, customKeys?: string[]): any
Recursively masks sensitive values in objects, arrays, and headers.
maskString(text: string, options?: MaskOptions): string
Masks characters in a string while preserving boundary characters for trace visibility.
📄 License
MIT © Reza
