Built-in Middleware
@gvray/logger 内置多种实用中间件,开箱即用。所有中间件通过 logger.use(middleware) 添加,按注册顺序执行。
prefixMiddleware / suffixMiddleware
给每条日志添加前缀或后缀。前缀支持字符串或返回字符串的函数。
import { Logger, LogLevel, prefixMiddleware, suffixMiddleware } from '@gvray/logger';
const logger = new Logger({ level: LogLevel.DEBUG, timestamp: 'time' });
logger.use(prefixMiddleware('[SYSTEM]'));
logger.use(suffixMiddleware('✓'));
logger.info('Task completed');
logger.debug('Processing finished');
logger.warning('Slow query detected');
(no output)
redactMiddleware
自动脱敏敏感信息。匹配字符串或正则,命中后替换为 [REDACTED]。
import { Logger, LogLevel, redactMiddleware } from '@gvray/logger';
const logger = new Logger({ level: LogLevel.DEBUG });
logger.use(
redactMiddleware([
'password123',
'secret-key',
/\d{4}-\d{4}-\d{4}-\d{4}/, // 信用卡号
/\w+@\w+\.\w+/, // 邮箱
]),
);
logger.info('User login: password=password123');
logger.info('API Key: secret-key');
logger.info('Card: 1234-5678-9012-3456');
logger.info('Email: user@example.com');
(no output)
jsonMiddleware
将日志输出为结构化 JSON,便于调试或喂给其他进程内工具解析。建议配合 colors: false 使用以保持 payload 干净。
import { Logger, LogLevel, jsonMiddleware } from '@gvray/logger';
// colors: false 让 JSON 输出更干净(避免 ANSI 转义码混入)
const logger = new Logger({ level: LogLevel.DEBUG, colors: false });
logger.use(jsonMiddleware());
logger.info('Structured log entry', { userId: 123, action: 'login' });
logger.error('Error occurred', { code: 500, message: 'Internal error' });
(no output)
filterLevel
在中间件层再次过滤日志级别。即使 Logger 的 level 设为 TRACE,也能用 filterLevel 在管道中拦截。
import { Logger, LogLevel, filterLevel } from '@gvray/logger';
// 即使 logger 的级别是 TRACE,filterLevel 中间件也能在中间件层再过滤一次
const logger = new Logger({ level: LogLevel.TRACE, timestamp: 'time' });
logger.use(filterLevel(LogLevel.WARNING));
logger.trace('不会显示');
logger.debug('不会显示');
logger.info('不会显示');
logger.warning('会显示(>= WARNING)');
logger.error('会显示');
logger.fatal('会显示');
(no output)
throttleMiddleware
限流:在指定时间窗口内最多输出 N 条日志,防止日志洪泛。
import { Logger, LogLevel, throttleMiddleware } from '@gvray/logger';
const logger = new Logger({ level: LogLevel.DEBUG, timestamp: 'time' });
// 1 秒内最多输出 2 条
logger.use(throttleMiddleware({ limit: 2, interval: 1000 }));
console.log('发送 5 条日志,但只有前 2 条会输出(1 秒内限流):');
for (let i = 1; i <= 5; i++) {
logger.info(`Message ${i}`);
}
setTimeout(() => {
console.log('1 秒后可以再次输出:');
logger.info('After throttle period');
}, 1100);
(no output)
samplingMiddleware
随机采样:按概率保留日志,适合高吞吐场景下的成本控制。
import { Logger, LogLevel, samplingMiddleware } from '@gvray/logger';
const logger = new Logger({ level: LogLevel.DEBUG, timestamp: 'time' });
// 只随机采样约 50% 的日志
logger.use(samplingMiddleware(0.5));
console.log('发送 10 条日志,约 50% 会被输出:');
for (let i = 1; i <= 10; i++) {
logger.info(`Sampled message ${i}`);
}
(no output)
errorStackMiddleware
自动展开 Error 对象的堆栈信息,便于调试。
import { Logger, LogLevel, errorStackMiddleware } from '@gvray/logger';
const logger = new Logger({ level: LogLevel.DEBUG, timestamp: 'time' });
logger.use(errorStackMiddleware());
const error = new Error('Something went wrong');
error.code = 'RUNTIME_ERROR';
logger.error('Error occurred:', error);
logger.fatal('Critical failure:', new Error('Database connection lost'));
(no output)
batchMiddleware
批量收集日志,达到阈值或刷新间隔后统一输出。
import { Logger, LogLevel, batchMiddleware } from '@gvray/logger';
const logger = new Logger({ level: LogLevel.DEBUG, timestamp: 'time' });
// 每 3 条日志触发一次批量刷新
logger.use(
batchMiddleware({
maxSize: 3,
maxWait: 2000,
onFlush: (contexts) => {
console.log(`📦 Flushed batch of ${contexts.length} logs`);
},
}),
);
console.log('发送 5 条日志,每 3 条触发一次批量刷新:');
logger.info('Log 1');
logger.info('Log 2');
logger.info('Log 3'); // 触发刷新
logger.info('Log 4');
logger.info('Log 5');
// 剩余未满 3 条的会在 maxWait 后刷新
setTimeout(() => {
console.log('(剩余日志已刷新)');
}, 2100);
(no output)