# MyLogs **Repository Path**: endport/my-logs ## Basic Information - **Project Name**: MyLogs - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-08-27 - **Last Updated**: 2025-08-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # MyLogEx - JSON Log Parser ## 项目说明 这个项目实现了一个日志批处理器,使用 nlohmann/json 库来解析特定格式的 JSON 日志数据。 ## 日志格式 日志格式为:`表名:{"records":[...]}` 例如: ``` ma_auditautorun:{"records":[{"atDesc":"Microsoft Edge Update","atName":"Microsoft Edge Update","atState":1,"atType":0,"uKey":3004886977,"uValue":2212294583}]} ``` ## 实现功能 ### CLogBatchCreater::CreateLogBatch 该方法解析日志字符串并创建 `CLogBatch` 对象: 1. **解析表名**:提取冒号前的表名 2. **解析 JSON 数据**:使用 nlohmann/json 解析冒号后的 JSON 数据 3. **处理记录数组**:遍历 "records" 数组中的每个记录 4. **创建字段**:为每个记录创建相应的 `CLogField` 对象 ### 支持的字段类型 - **字符串字段**:`atDesc`, `atName` - **数值字段**:`atState`, `atType`, `uKey`, `uValue` ## 依赖项 - **nlohmann/json**: JSON 解析库 (版本 3.11.3) - **Boost**: 用于 variant 类型支持 ## 使用方法 ```cpp #include "CLogBatchCreater.h" CLogBatchCreater creator; std::string logData = "ma_auditautorun:{\"records\":[...]}"; auto logBatch = creator.CreateLogBatch(logData); // 获取表名 std::string tableName = logBatch->GetTableName(); // 获取记录数量 size_t recordCount = logBatch->GetRecords().size(); // 访问记录字段 for (const auto& record : logBatch->GetRecords()) { for (const auto& field : record->GetFields()) { std::cout << field.GetName() << ": " << field.GetValue() << std::endl; } } ``` ## 构建说明 项目使用 Visual Studio 2022 和 MSBuild。确保已安装: 1. Visual Studio 2022 2. C++ 开发工具 3. NuGet 包管理器 构建命令: ```bash msbuild MyLogEx.sln /p:Configuration=Debug /p:Platform=x64 /restore ``` ## 错误处理 - 如果 JSON 格式无效,方法返回空的 `CLogBatch` - 如果缺少冒号分隔符,返回空的 `CLogBatch` - 如果字段不存在,该字段将被跳过 # MyLogEx 一个高效的日志管理系统,支持多种表类型和自动清理功能。 ## 主要功能 ### 日志清理服务 (CLeanServer) `CLeanServer` 类提供了自动清理过期日志记录的功能,具有以下特点: #### 清理规则 - **只清理特定类型的表**:`append`、`upappend`、`AppendWithCounter` 三种类型 - **已上传日志**:保留5天(通过记录ID与上传游标比较判断) - **未上传日志**:保留30天(通过记录ID与上传游标比较判断) - **智能判断**:自动检测每条记录的ID与上传游标的关系,智能选择清理策略 #### 使用方法 ```cpp #include "CLeanServer.h" #include "CTableManager.h" // 创建清理服务 CLeanServer cleanServer; // 初始化(传入表管理器) CTableManager* tableManager = /* 获取表管理器实例 */; cleanServer.Initialize(tableManager); // 执行清理 int cleanedCount = cleanServer.CleanExpiredLogs(); if (cleanedCount >= 0) { std::cout << "成功清理 " << cleanedCount << " 条过期记录" << std::endl; } else { std::cerr << "清理失败" << std::endl; } ``` #### 定时清理服务 `CLeanServer` 支持定时自动清理,默认每隔1分钟执行一次: ```cpp // 启动定时清理服务 int result = cleanServer.StartScheduledCleanup(); if (result == 0) { std::cout << "定时清理服务启动成功" << std::endl; } else { std::cerr << "定时清理服务启动失败" << std::endl; } // 检查定时清理服务状态 if (cleanServer.IsScheduledCleanupRunning()) { std::cout << "定时清理服务正在运行" << std::endl; } // 停止定时清理服务 cleanServer.StopScheduledCleanup(); ``` #### 特性 - **简单易用**:无需复杂配置,直接调用即可 - **自动识别**:自动识别需要清理的表类型 - **智能清理**:通过游标自动判断上传状态,采用不同的保留策略 - **游标感知**:自动检测表的 `getUploadedCursor()` 状态 - **时间字段**:使用表的 `ltm` 字段进行时间判断 - **分批处理**:为了性能考虑,每次筛选1000条记录,通过ID删除 - **定时执行**:支持定时自动清理,默认1分钟间隔 - **线程安全**:使用独立线程执行清理任务,不阻塞主程序 - **优雅停止**:支持优雅停止定时清理服务 - **空间回收**:清理后自动执行VACUUM回收数据库空间 - **错误处理**:完善的异常处理和错误日志 #### 注意事项 - 确保数据库表包含 `ltm` 字段(用于时间判断) - 表需要正确实现 `getUploadedCursor()` 方法 - 定时清理服务会在后台线程中运行,不会阻塞主程序 - 在程序退出前应调用 `StopScheduledCleanup()` 停止服务 - 清理操作会锁定数据库,建议在系统负载较低时执行 - 清理策略会根据表的游标状态自动调整 #### 分批清理策略 为了性能考虑,清理过程采用分批处理方式: 1. **时间筛选阶段**:每次从数据库筛选出1000条过期的记录(ID和时间),利用ID自增特性无需额外排序 2. **智能判断阶段**:通过记录ID与上传游标比较,判断记录是否已上传,采用不同的保留策略 3. **批量删除阶段**:通过 `WHERE id IN (...)` 语句批量删除记录 4. **定时执行**:通过外部定时器定期调用,每次处理一批过期记录 5. **性能优化**:避免一次性删除大量记录导致的锁表问题 **优势**: - 减少数据库锁定时间 - 降低内存占用 - 提高清理过程的响应性 - 支持大表的渐进式清理 #### 定时清理配置 - **清理间隔**:默认1分钟,可通过 `CLEANUP_INTERVAL_MINUTES` 常量调整 - **线程管理**:使用独立线程执行清理任务 - **状态监控**:提供运行状态查询接口 - **优雅停止**:支持立即停止和等待完成两种模式 ## 表类型说明 - **AppendTable**: 追加表,记录按时间顺序追加 - **UpAppendTable**: 上传追加表,支持批量上传 - **AppendWithCounterTable**: 带计数器的追加表 - **UpdateTable**: 更新表,支持记录更新 - **OverTable**: 覆盖表,新记录覆盖旧记录 ## 上传游标管理 ### 功能说明 `CTableBase` 类提供了完整的上传游标管理功能,用于跟踪每个表的日志上传进度。 ### 核心方法 #### `initUploadCursor()` - **功能**: 从数据库初始化上传游标 - **实现**: 从 `nonius` 表读取当前表的最后一次成功上传的游标 - **返回值**: 0表示成功,负值表示错误代码 - **自动调用**: 在 `InitTable()` 方法中自动调用 #### `getUploadedCursor()` - **功能**: 获取当前的上传游标值 - **返回值**: 当前上传游标的时间戳 #### `updateUploadCursor(uint64_t newCursor)` - **功能**: 手动更新上传游标 - **参数**: `newCursor` - 新的游标值 - **返回值**: 0表示成功,负值表示错误代码 - **用途**: 可用于手动设置游标位置或重置上传状态 ### 游标存储 - 游标信息存储在 `nonius` 表中 - 包含字段:`stm`(开始时间)、`ltm`(最后时间)、`name`(表名)、`table_id`(表ID) - 支持增量上传和断点续传 ### 增量上传机制 - **`getUploadBatch()`**: 只获取ID大于当前上传游标的记录,实现真正的增量上传 - **游标更新**: 上传成功后自动更新游标位置,确保下次只获取新记录 - **避免重复**: 通过游标机制避免重复上传已处理的记录 - **ID序列**: 表ID从1开始,确保第一条记录的ID为1,便于游标管理 ### 使用示例 ```cpp // 获取当前上传游标 uint64_t currentCursor = table->getUploadedCursor(); // 手动更新上传游标 int result = table->updateUploadCursor(newTimestamp); if (result == 0) { std::cout << "游标更新成功" << std::endl; } else { std::cerr << "游标更新失败,错误代码: " << result << std::endl; } ``` ## 编译要求 - C++11 或更高版本 - SQLite3 - Boost库(用于线程安全) - 支持Windows平台