Skip to content

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');
Console

(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');
Console

(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' });
Console

(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('会显示');
Console

(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);
Console

(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}`);
}
Console

(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'));
Console

(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);
Console

(no output)

Released under the MIT License.