Package Exports
- mm_logs
- mm_logs/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (mm_logs) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
mm_logs
企业级Node.js日志模块,提供完善的日志记录、分布式追踪、敏感信息脱敏等功能,适用于生产环境和复杂系统架构。
特性
- ✅ 多级别日志:支持trace、debug、info、warn、error、fatal、success、http等日志级别
- ✅ 分布式追踪:内置请求链路追踪,支持全局和局部追踪ID管理
- ✅ 敏感信息脱敏:自动识别并脱敏常见敏感数据(密码、手机号、邮箱、身份证等)
- ✅ 性能统计:提供日志计数和各级别统计功能
- ✅ 灵活配置:支持自定义日志级别、输出格式、文件轮转等
- ✅ 跨平台兼容:完善的路径处理和文件编码支持
- ✅ 错误处理:健壮的异常捕获和处理机制
- ✅ 对象格式化:自动处理复杂对象、循环引用和错误对象
- ✅ 事件驱动架构:基于EventEmitter,支持事件订阅与监控,便于实现熔断等高级功能
安装
npm install mm_logs --save基本用法
// 引入日志模块
const { log } = require('mm_logs');
// 基本日志输出
log.debug('App', '应用启动');
log.info('User', '用户登录成功');
log.warn('System', '磁盘空间不足');
log.error('Auth', '认证失败');
log.success('Task', '任务完成');
log.http('API', '请求处理完成');
log.trace('Performance', '性能追踪信息');
log.fatal('Database', '数据库连接失败');
// 输出对象和错误
const user = { name: '张三', age: 25 };
log.info('User', '用户信息:', user);
try {
// 代码...
} catch (error) {
log.error('Error', error);
}高级特性
1. 分布式追踪
// 设置全局追踪ID
log.setGlobalTraceId('request-123456');
log.info('API', '这行日志将包含全局追踪ID');
// 开始新的追踪上下文(嵌套)
const traceId = log.startTrace();
log.info('Service', '这行日志将使用本地追踪ID');
// 嵌套追踪
log.startTrace('child-context-789');
log.info('SubTask', '这行日志将使用嵌套追踪ID');
// 结束追踪上下文
log.endTrace(); // 回到外层追踪ID
log.info('Service', '回到外层上下文');
log.endTrace(); // 回到全局追踪ID
log.info('API', '回到全局上下文');
// 获取当前追踪ID
const currentTraceId = log.getCurrentTraceId();2. 敏感信息脱敏
// 创建带脱敏配置的日志实例
const { Log } = require('mm_logs');
const secureLog = new Log({
sensitiveFields: ['password', 'phone', 'email', 'idCard']
});
// 动态添加敏感字段
secureLog.addSensitiveFields(['creditCard', 'secretKey']);
// 输出包含敏感信息的数据
const userData = {
name: '张三',
password: 'secret123',
phone: '13812345678',
email: 'zhangsan@example.com',
idCard: '110101199001011234',
address: '北京市朝阳区'
};
secureLog.info('UserInfo', userData);
// 敏感字段将自动脱敏,例如: password -> ******, phone -> 138****56783. 自定义配置
const customLog = new Log({
level: 'info', // 日志级别
logDir: './logs/custom', // 日志目录
showTimestamp: true, // 显示时间戳
showConsole: true, // 输出到控制台
sensitiveFields: ['password'], // 敏感字段
globalTraceId: 'app-global', // 全局追踪ID
log4jsConfig: { // 自定义log4js配置
// 自定义配置...
}
});4. 性能统计
// 获取统计信息
const stats = log.getStats();
$.log.debug('日志总数:', stats.logCount);
$.log.debug('各级别数量:', stats.levelStats);
// 重置统计
log.resetStats();5. 事件驱动架构
// 订阅日志事件
log.on('logOutput', (data) => {
$.log.debug(`收到日志: ${data.level} - ${data.tag}`);
});
// 订阅错误事件
log.on('applicationError', (error) => {
$.log.error(`应用错误: ${error.tag} - ${error.message}`);
});
// 订阅警告事件
log.on('warning', (warning) => {
$.log.warn(`警告: ${warning.tag}`);
});
// 订阅统计更新事件
log.on('statsUpdated', (stats) => {
$.log.debug(`统计更新: ${stats.logCount}条日志`);
});
// 订阅追踪相关事件
log.on('traceStarted', (traceInfo) => {
$.log.debug(`追踪开始: ${traceInfo.traceId}`);
});
log.on('traceEnded', () => {
$.log.debug('追踪结束');
});
// 订阅配置变更事件
log.on('configChanged', (config) => {
$.log.debug(`配置变更: ${JSON.stringify(config)}`);
});6. 熔断机制集成示例
// 熔断模块集成
const circuitBreaker = {
errors: 0,
errorThreshold: 3,
state: 'CLOSED',
init: function(log) {
// 订阅错误事件
log.on('applicationError', this.handleError.bind(this));
log.on('statsUpdated', this.updateStats.bind(this));
},
handleError: function(error) {
this.errors++;
if (this.errors >= this.errorThreshold && this.state === 'CLOSED') {
this.state = 'OPEN';
$.log.debug('熔断器打开,触发降级策略');
// 实现降级逻辑
}
},
updateStats: function(stats) {
const errorRate = stats.levelStats.error / stats.logCount * 100 || 0;
$.log.debug(`当前错误率: ${errorRate.toFixed(2)}%`);
}
};
// 初始化熔断监控
circuitBreaker.init(log);API参考
日志级别方法
log.trace(tag, ...args)- 输出跟踪级别日志log.debug(tag, ...args)- 输出调试级别日志log.info(tag, ...args)- 输出信息级别日志log.warn(tag, ...args)- 输出警告级别日志log.error(tag, ...args)- 输出错误级别日志log.fatal(tag, ...args)- 输出致命错误级别日志log.success(tag, ...args)- 输出成功日志log.http(tag, ...args)- 输出HTTP请求日志
配置方法
log.setLevel(level)- 设置日志级别,返回设置是否成功log.getLevel()- 获取当前日志级别log.toggleConsole(show)- 切换控制台输出log.toggleTimestamp(show)- 切换时间戳显示
追踪方法
log.setGlobalTraceId(traceId)- 设置全局追踪IDlog.startTrace(traceId)- 开始新的追踪上下文,返回追踪IDlog.endTrace()- 结束当前追踪上下文,返回结束的追踪IDlog.getCurrentTraceId()- 获取当前活跃的追踪ID
安全方法
log.addSensitiveFields(fields)- 添加敏感字段
统计方法
log.getStats()- 获取日志统计信息log.resetStats()- 重置日志统计信息
事件系统
Log类继承自EventEmitter,支持所有EventEmitter的标准方法:
log.on(event, listener)- 订阅事件log.once(event, listener)- 订阅单次事件log.emit(event, ...args)- 触发事件log.removeListener(event, listener)- 移除事件监听
配置选项
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| level | string | 'debug' | 日志级别 |
| logDir | string | './log' | 日志目录 |
| showTimestamp | boolean | true | 是否显示时间戳 |
| showConsole | boolean | true | 是否输出到控制台 |
| sensitiveFields | string[] | [] | 需要脱敏的敏感字段名数组 |
| globalTraceId | string | null | 全局追踪ID |
| log4jsConfig | object | {} | 自定义log4js配置 |
支持的事件
| 事件名称 | 触发时机 | 事件数据 |
|---|---|---|
| initialized | 日志实例初始化完成 | { config: 配置对象 } |
| logOutput | 任意级别的日志输出 | { level: 级别, tag: 标签, message: 消息 } |
| applicationError | 应用错误日志输出 | { tag: 标签, message: 消息, error: 错误对象 } |
| warning | 警告日志输出 | { tag: 标签, message: 消息 } |
| statsUpdated | 日志统计信息更新 | { logCount: 总数, levelStats: 级别统计 } |
| traceStarted | 开始追踪 | { traceId: 追踪ID } |
| traceEnded | 结束追踪 | - |
| configChanged | 配置变更 | { change: 变更内容 } |
| globalTraceIdChanged | 全局追踪ID变更 | { newId: 新ID } |
| statsReset | 统计重置 | - |
支持的日志级别
- trace: 最详细的日志信息
- debug: 调试信息
- info: 一般信息
- warn: 警告信息
- error: 错误信息
- fatal: 致命错误信息
注意事项
- 日志目录:确保应用对日志目录有写权限,模块会自动创建不存在的目录
- 敏感信息:根据项目需要合理配置敏感字段,确保数据安全
- 性能优化:在生产环境中,可关闭控制台输出以提高性能
- 日志轮转:默认配置为2MB一个文件,最多保留3个备份
版本历史
- 1.5.0: 新增事件驱动架构,支持事件订阅与监控
- 1.4.0: 企业级特性增强,添加分布式追踪、敏感信息脱敏、跨平台路径处理
- 1.3.0: 参数格式化、错误处理优化、配置灵活性提升
- 1.2.0: 基本日志功能实现
作者
邱文武 - http://qww.elins.cn
许可证
ISC