koatty_logger
v2.8.4
Published
Logger for koatty.
Maintainers
Readme
koatty_logger
企业级日志组件,专为 koatty 框架设计,具备强大的安全防护和性能优化特性。
✨ 特性
🔒 安全特性
- 路径遍历防护: 防止恶意路径访问系统敏感文件
- 日志注入防护: 自动过滤控制字符,防止日志伪造攻击
- 数据脱敏: 支持敏感字段自动脱敏,保护隐私数据
- 输入验证: 严格验证日志路径和内容的安全性
⚡ 性能优化
- 异步写入: 默认采用异步日志写入,避免阻塞主线程
- 批量写入: 高并发场景下的批量日志写入,显著提升性能
- 内存管理: 智能内存清理,防止内存泄漏
- 递归限制: 防止深层对象导致的性能问题
- 高效克隆: 优化对象克隆算法,提升脱敏性能
- 日志轮转: 基于时间和大小的智能日志轮转
📦 安装
npm install koatty_logger🚀 快速开始
基础使用
import { Logger } from 'koatty_logger';
// 创建logger实例
const logger = new Logger();
// 基础日志输出
logger.info('应用启动成功');
// 输出 [2022-11-18 16:04:00.011] [INFO] 应用启动成功
logger.error('发生错误', new Error('示例错误'));
// 输出 [2022-11-18 16:04:00.011] [ERROR] 发生错误: Error: 示例错误
logger.debug('调试信息', { userId: 123, action: 'login' });
// 输出 [2022-11-18 16:04:00.011] [DEBUG] 调试信息: { userId: 123, action: 'login' }
logger.Log('Koatty', '', 'LoadAllComponents completed');
// 输出 [2022-11-18 16:04:00.011] [KOATTY] LoadAllComponents completed安全配置
import { Logger } from 'koatty_logger';
const logger = new Logger({
logLevel: 'info',
logFilePath: './logs/app.log',
sensFields: new Set(['password', 'token', 'secret'])
});
// 敏感数据会自动脱敏
logger.info('用户登录', {
username: 'john',
password: 'secret123', // 会被脱敏为 sec***23
email: '[email protected]'
});高级用法
// 异步日志写入(默认行为)
// Winston本身就是异步的,koatty_logger进一步优化了异步处理
logger.info('这条日志会异步写入,不会阻塞主线程');
logger.error('错误日志也是异步的');
// 批量写入模式 vs 异步单条写入模式
const asyncLogger = new Logger({
logLevel: 'info',
logFilePath: './logs/async.log'
// 默认不启用批量写入,使用异步单条写入
});
const batchLogger = new Logger({
logLevel: 'info',
logFilePath: './logs/batch.log',
batchConfig: {
enabled: true, // 启用批量写入
maxSize: 100, // 缓冲区最大100条日志
flushInterval: 1000, // 每秒检查一次是否需要刷新
maxWaitTime: 5000 // 最多等待5秒就强制刷新
}
});
// 动态管理敏感字段
logger.setSensFields(['creditCard', 'ssn']);
logger.clearSensFields(); // 清空敏感字段
logger.resetSensFields(['newSensitiveField']); // 重置敏感字段
// 安全的日志文件路径设置
try {
logger.setLogFilePath('app.log'); // ✅ 安全路径
logger.setLogFilePath('../../../etc/passwd'); // ❌ 会抛出安全异常
} catch (error) {
console.error('路径不安全:', error.message);
}
// 高性能批量写入配置
const highPerfLogger = new Logger({
logLevel: 'info',
logFilePath: './logs/high-perf.log',
batchConfig: {
enabled: true, // 启用批量写入
maxSize: 100, // 缓冲区最大100条日志
flushInterval: 1000, // 每秒检查一次是否需要刷新
maxWaitTime: 5000 // 最多等待5秒就强制刷新
}
});
// 批量写入控制
highPerfLogger.enableBatch(true); // 启用批量写入
await highPerfLogger.flushBatch(); // 立即异步刷新缓冲区
// 获取批量写入状态
const status = highPerfLogger.getBatchStatus();
console.log('缓冲区大小:', status.bufferSize);
console.log('距离上次刷新时间:', status.timeSinceLastFlush);
// 动态调整批量写入配置
highPerfLogger.setBatchConfig({
maxSize: 200, // 调整缓冲区大小
flushInterval: 500 // 调整检查间隔
});
// 优雅关闭(确保所有日志都被写入)
process.on('SIGINT', async () => {
console.log('正在关闭应用...');
await highPerfLogger.flushBatch(); // 等待所有日志写入完成
logger.destroy(); // 释放所有资源
process.exit(0);
});
// 资源清理
logger.destroy(); // 释放所有资源Log 装饰器(与 koatty-container 集成)
通过 @Log() 属性装饰器注入日志实例,适用于 Controller、Service 等类。需配合 koatty_container 使用,容器会在初始化时自动注册 "Log" 装饰器。
使用前:应用若使用 koatty_container,PropertyDecoratorManager 首次创建时会自动注册;若未使用容器,可手动调用一次:
import { registerLogDecorator } from 'koatty_logger';
import { decoratorManager } from 'koatty_container';
registerLogDecorator(decoratorManager.property);注入全局 DefaultLogger(推荐):
import { Controller, GetMapping, QueryParam } from 'koatty_router'; // 或你的路由包
import { Log } from 'koatty_logger';
@Controller('/api/users')
export class UserController {
app: App;
ctx: any;
@Log()
logger: any;
@GetMapping('/')
async getUsers(
@QueryParam('page') page: number = 1,
@QueryParam('limit') limit: number = 10
): Promise<any> {
this.logger.info(`获取用户列表: page=${page}, limit=${limit}`);
const result = await this.userService.findAll(page, limit);
return { code: 200, message: '获取成功', data: result };
}
}注入自定义 Logger 实例:
import { Log } from 'koatty_logger';
class MyService {
@Log() logger: any; // 全局 DefaultLogger
@Log({ logLevel: 'debug', logFilePath: './logs/service.log' })
debugLogger: any; // 独立 Logger 实例,按类+属性缓存
}| 用法 | 说明 |
|------|------|
| @Log() | 属性赋值为全局 DefaultLogger 单例 |
| @Log(options) | 属性赋值为 new Logger(options) 的实例,同一类+属性共享同一实例 |
说明:未使用 koatty_container 时,@Log() 会静默不生效,不会影响现有代码。
🔧 API 文档
Logger 类
构造函数
new Logger(options?: LoggerOpt)主要方法
| 方法 | 描述 | 特性 |
|------|------|------|
| info(...args) | 输出信息日志 | 异步写入,自动过滤注入字符 |
| error(...args) | 输出错误日志 | 异步写入,自动过滤注入字符 |
| debug(...args) | 输出调试日志 | 异步写入,自动过滤注入字符 |
| warn(...args) | 输出警告日志 | 异步写入,自动过滤注入字符 |
| setLogFilePath(path) | 设置日志文件路径 | 路径遍历防护 |
| setSensFields(fields) | 设置敏感字段 | 数据脱敏 |
| clearSensFields() | 清空敏感字段 | 内存清理 |
| enableBatch(enabled) | 启用/禁用批量写入 | 高并发性能优化 |
| setBatchConfig(config) | 设置批量写入配置 | 动态性能调优 |
| flushBatch() | 立即刷新缓冲区 | 异步操作,返回Promise |
| getBatchStatus() | 获取批量写入状态 | 性能监控 |
| destroy() | 销毁实例 | 资源释放,异步刷新剩余日志 |
配置选项
interface LoggerOpt {
logLevel?: 'debug' | 'info' | 'warning' | 'error';
logFilePath?: string; // 安全验证的日志路径
sensFields?: Set<string>; // 敏感字段集合
batchConfig?: BatchConfig; // 批量写入配置
}
interface BatchConfig {
enabled?: boolean; // 是否启用批量写入
maxSize?: number; // 最大缓冲区大小(条目数)
flushInterval?: number; // 刷新间隔检查(毫秒)
maxWaitTime?: number; // 最大等待时间(毫秒)
}Log 装饰器 API
| 导出 | 描述 |
|------|------|
| Log(options?: LoggerOpt) | 属性装饰器。无参时注入 DefaultLogger,有参时注入 new Logger(options) 的缓存实例 |
| registerLogDecorator(propertyManager) | 向 koatty_container 的 property 管理器注册 "Log" 装饰器,通常由容器自动调用 |
| unregisterLogDecorator() | 清除已注册的 property 管理器(多用于测试) |
🛡️ 安全最佳实践
1. 路径安全
// ✅ 推荐:使用相对路径
logger.setLogFilePath('logs/app.log');
// ❌ 避免:绝对路径或路径遍历
logger.setLogFilePath('/var/log/app.log'); // 可能失败
logger.setLogFilePath('../../../sensitive.log'); // 会抛出异常2. 敏感数据保护
// 设置敏感字段
logger.setSensFields([
'password', 'token', 'secret', 'key',
'creditCard', 'ssn', 'phone', 'email'
]);
// 敏感数据会自动脱敏
const userData = {
name: 'John',
password: 'mySecret123', // 会显示为 myS****123
phone: '1234567890' // 会显示为 123***7890
};
logger.info('用户数据', userData);3. 注入防护
日志组件会自动过滤以下危险字符:
- 换行符 (
\n,\r) - 制表符 (
\t) - 控制字符 (
\x00-\x1f,\x7f)
4. 异步日志最佳实践
// ✅ 推荐:默认使用异步日志(无需特殊配置)
const logger = new Logger({
logLevel: 'info',
logFilePath: './logs/app.log'
// 默认就是异步写入,性能最优
});
// ✅ 推荐:高并发场景使用批量写入
const highConcurrencyLogger = new Logger({
batchConfig: {
enabled: true,
maxSize: 100, // 根据应用负载调整
flushInterval: 1000, // 平衡性能和实时性
maxWaitTime: 3000 // 确保日志不会丢失
}
});
// ✅ 推荐:关键操作后手动刷新批量日志
await logger.flushBatch(); // 确保重要日志立即写入
// ✅ 推荐:优雅关闭,等待所有日志写入完成
process.on('SIGTERM', async () => {
console.log('接收到关闭信号,正在刷新日志...');
await logger.flushBatch();
logger.destroy();
process.exit(0);
});
// ⚠️ 注意:批量模式的权衡
// 批量写入:更高性能,但可能延迟写入
// 异步单条:实时性更好,适合错误日志
logger.enableBatch(false); // 关键错误日志立即写入
logger.error('Critical system error');
logger.enableBatch(true); // 重新启用批量写入5. 批量写入最佳实践
// ✅ 推荐:应用关闭前手动刷新
process.on('SIGINT', async () => {
await logger.flushBatch();
logger.destroy();
process.exit(0);
});
// ⚠️ 注意:实时性要求高的日志禁用批量写入
logger.enableBatch(false); // 错误日志等需要立即写入
logger.error('Critical error occurred');
logger.enableBatch(true); // 重新启用批量写入🔍 测试
# 运行所有测试
npm test
# 运行安全测试
npm test -- --testNamePattern="Security"
# 运行性能测试
npm test -- --testNamePattern="Performance"📊 性能指标
- 异步写入: 相比同步写入,CPU阻塞时间减少 95%
- 批量写入: 高并发场景下性能提升 200-500%
- 1000条/秒:性能提升 200%
- 10000条/秒:性能提升 500%
- 缓冲区命中率:95%+
- 内存使用: 优化后减少 30% 内存占用
- CPU开销: 脱敏算法优化,减少 40% CPU使用
- 处理速度: 大批量日志处理速度提升 50%
🤝 贡献
欢迎提交 Issue 和 Pull Request!
📄 许可证
BSD-3-Clause License
