# microLog **Repository Path**: galaxy_0/micro-log ## Basic Information - **Project Name**: microLog - **Description**: 专为 ARM Linux 嵌入式设备、工业网关、数据采集器设计的日志库。自定义格式保存性能实测300万/s - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-07-02 - **Last Updated**: 2026-07-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # microLog — 嵌入式日志库 专为 ARM Linux 嵌入式设备、工业网关、数据采集器设计的日志库。 **命名空间**:`microLog` 软件依赖:cppMisc (https://gitee.com/galaxy_0/cpp-misc) ## 定位 不是通用日志库(如 spdlog / glog),而是面向 **资源受限 + 掉电风险 + Flash 寿命敏感** 场景的专用日志解决方案。 ## 核心特性 - **9 种后端**:文件、管道、UnixSocket、UDP、TCP、终端、SQLite3、MySQL、PostgreSQL - **tinySeqFile**:自研环形文件引擎,嵌入式 Flash 友好,掉电安全 - **mmap 优化**(可选):减少系统调用,提升写入性能 - **AES 加密**(可选):AES-128/AES-256 数据加密 - **线程池**:异步写入,不阻塞业务线程 - **零核心依赖**:核心模块仅依赖 C++ 标准库 - **log_reader**:日志读取共享库 + 命令行工具,支持加密解密 - **全文检索**:基于倒排索引的二级索引,支持内存/SQLite3/文件三种索引类型 - **布隆过滤器**:快速过滤不存在的关键词,减少无效查询 - **热词缓存**:LRU策略缓存高频查询结果 ## 支持的后端 | 后端 | 说明 | 适用场景 | |------|------|---------| | **LOCAL** | tinySeqFile 环形文件 | 嵌入式本地持久化 | | **UDP** | UDP 广播/单播 | 局域网内快速传输 | | **TCP** | TCP 客户端 | 可靠网络传输 | | **PIPE** | 命名管道 | 进程间通信 | | **UNIXSOCK** | Unix Domain Socket | 同主机高性能 IPC | | **TERMINAL** | 标准输出 | 开发调试 | | **SQLITE3** | SQLite3 数据库 | 单机应用,复杂查询 | | **MYSQL** | MySQL 数据库 | Web 应用 | | **POSTGRESQL** | PostgreSQL 数据库 | 企业级应用 | ## 版本 版本号采用四元组格式:`功能版本.设计版本.编译版本.Bug修复次数` - **功能版本**:功能不兼容时递增 - **设计版本**:功能兼容的架构/设计变更时递增 - **编译版本**:**每次编译自动随机 0-9**,由 `cmake/version.cmake` 管理 - **Bug 修复次数**:每次 Bug 修复后手动递增 ## 编译 ### 依赖 | 依赖 | 用途 | 必需 | |------|------|------| | C++11 | 编译器 | 是 | | CMake 3.16+ | 构建工具 | 是 | | SQLite3 | SQLite3 后端 | 否 | | MySQL Client | MySQL 后端 | 否 | | libpq | PostgreSQL 后端 | 否 | | OpenSSL | AES 加密 | 否 | ### 本地编译 ```bash mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Debug cmake --build . ./bin/debug/test_terminal ``` ### 交叉编译(ARM) ```bash # ARMv7 (hard-float) mkdir build-arm && cd build-arm cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/arm-linux-gnueabihf.cmake \ -DCMAKE_BUILD_TYPE=Release \ -DWITH_SQLITE3=ON # ARM64 (AArch64) mkdir build-arm64 && cd build-arm64 cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/aarch64-linux-gnu.cmake \ -DCMAKE_BUILD_TYPE=Release ``` ### 编译选项 | 选项 | 说明 | |------|------| | `-DWITH_SQLITE3=ON` | 启用 SQLite3 后端 | | `-DWITH_MYSQL=ON` | 启用 MySQL 后端 | | `-DWITH_POSTGRESQL=ON` | 启用 PostgreSQL 后端 | | `-DWITH_OPENSSL=ON` | 启用 AES 加密 | | `-DWITH_MMAP=ON` | 启用 mmap 优化(Linux) | | `-DBUILD_TESTS=ON` | 启用测试程序(默认 ON) | ### 独立编译(仅核心) ```bash g++ -std=c++11 -I./include -o test test.cpp \ src/logDetail/tinySeqFile.cpp \ src/logDetail/terminal.cpp ``` ## 使用示例 ### 基本用法 ```cpp #include "log.hpp" #include "microLog/version.hpp" // 自动生成 int main() { // 创建终端日志 auto log = microLog::createLog( 4 ); log->info("microLog %s 启动", TINYLOG_VERSION_STRING); log->warn("内存使用率: %d%%", 85); log->error("连接失败: %s", "timeout"); return 0; } ``` ### 本地文件日志(tinySeqFile) ```cpp auto log = microLog::createLog(4, "/data/app.log", 4096, 1000); log->info("系统启动, 版本: %s", "1.0.0"); ``` ### TCP 远程日志 ```cpp auto log = microLog::createLog(4, "192.168.1.100", 12345); log->info("传感器数据: %.2f", 25.6); ``` ### SQLite3 数据库日志 ```cpp auto log = microLog::createLog(4, "/var/log/app.db"); log->info("用户登录: %s", "admin"); ``` ### MySQL 日志 ```cpp auto log = microLog::createLog(4, "localhost", 3306, "logdb", "root", "password"); log->error("数据库错误: %s", "connection refused"); ``` ### tinySeqFile 直接使用(嵌入式) ```cpp #include "tinySeqFile.hpp" int main() { // 路径, 最大条数, 每条最大字节 tinySeqFile file("/flash/log.dat", 1000, 2048); file.push("sensor reading: temp=%.1f", 23.5); file.sync(); // 刷盘 std::string data; file.front(data); // 读最新一条 return 0; } ``` ### 日志读取工具(log_reader) ```cpp #include "read/log_reader.hpp" int main() { microLog::log_reader reader; // 打开日志文件(自动检测配置) reader.open("./app.log"); // 设置加密密钥(可选,用于解密加密日志) reader.set_crypto(microLog::log_reader::crypto_type::AES256, key, iv); // 方式1: 回调读取 reader.read_with_callback([](uint64_t idx, const std::string& content) { std::cout << "[" << idx << "] " << content; return true; // 返回 false 可中断读取 }); // 方式2: 读取到 vector std::vector records; reader.read_all(records); // 方式3: 输出到文件 reader.read_to_file("./output.txt"); return 0; } ``` ### 全文检索功能 ```cpp #include "read/log_reader.hpp" int main() { microLog::log_reader reader; reader.open("./app.log"); // 设置索引类型(MEMORY / SQLITE3 / FILE) reader.set_index_type(microLog::log_reader::emIndexType::FILE); // 构建搜索索引(离线/定时执行) reader.build_search_index(); // 搜索关键词(返回匹配的记录索引) std::vector indices; if (reader.search("error", indices)) { std::cout << "找到 " << indices.size() << " 条匹配记录\n"; } // 搜索关键词并获取完整记录 std::vector results; if (reader.search_records("warning", results)) { for (const auto& rec : results) { std::cout << "[" << rec.index << "] " << rec.content; } } return 0; } ``` **索引类型对比:** | 类型 | 说明 | 检索速度 | 内存占用 | 持久化 | 适用场景 | |------|------|---------|---------|--------|---------| | **MEMORY** | 内存哈希表 + 布隆过滤器 | 最快 | 高 | 否 | 临时查询 | | **SQLITE3** | SQLite3 数据库 + 布隆过滤器 | 中等 | 中等 | 是 | 长期存储 | | **FILE** | 倒排索引文件 + mmap + 布隆过滤器 | 快 | 低 | 是 | 嵌入式/资源受限 | ## 工具程序 ### log_reader — 命令行日志读取工具 ```bash # 读取日志到终端(带索引) ./log_reader -f ./app.log # 读取加密日志 ./log_reader -f ./app.log \ -k "0123456789abcdef0123456789abcdef" \ -i "0123456789abcdef" # 输出到文本文件 ./log_reader -f ./app.log -t ./output.txt -m text ``` **参数说明:** | 参数 | 说明 | |------|------| | `-f ` | 日志文件路径(必需) | | `-t ` | 输出文本文件路径 | | `-m ` | 读取模式:`terminal`(带索引)或 `text`(纯文本) | | `-k ` | AES密钥(AES-128: 16字节,AES-256: 32字节) | | `-i ` | AES初始化向量(16字节) | | `-h` | 显示帮助信息 | ## 项目结构 ``` . ├── CMakeLists.txt # 主构建文件 ├── cmake/ │ ├── version.cmake # 版本管理脚本(每次 configure 随机 BUILD) │ ├── arm-linux-gnueabihf.cmake # ARMv7 交叉编译工具链 │ └── aarch64-linux-gnu.cmake # ARM64 交叉编译工具链 ├── include/ │ ├── log.hpp # 主入口,LOG<> 模板,工厂函数 │ ├── logDetail/ # 日志后端模块 │ │ ├── itfc.hpp # microLog 基类 │ │ ├── tinySeqFile.hpp # 环形文件引擎(核心) │ │ ├── local.hpp # LOCAL 后端 │ │ ├── terminal.hpp # TERMINAL 后端 │ │ ├── tcp.hpp # TCP 后端 │ │ ├── udp.hpp # UDP 后端 │ │ ├── pipe.hpp # PIPE 后端 │ │ ├── unixSock.hpp # UNIXSOCK 后端 │ │ ├── sqlite3_log.hpp # SQLite3 后端 │ │ ├── mysql_log.hpp # MySQL 后端 │ │ └── postgresql_log.hpp # PostgreSQL 后端 │ └── read/ # 日志读取与检索模块 │ ├── log_reader.hpp # 日志读取工具库 │ ├── search_index_itfc.hpp # 索引抽象接口 │ ├── memory_search_index.hpp # 内存索引实现 │ ├── sqlite3_search_index.hpp # SQLite3索引实现 │ ├── file_search_index.hpp # 文件倒排索引实现 │ ├── trie.hpp # 前缀树(Trie)数据结构 │ ├── bloom_filter.hpp # 布隆过滤器 │ └── hot_word_cache.hpp # 热词缓存 ├── src/ │ ├── log.cpp # 工厂入口 │ ├── logDetail/ # 各后端实现 │ └── read/ # 读取与检索模块实现 │ ├── log_reader.cpp # 日志读取工具实现 │ ├── search_index_factory.cpp # 索引工厂 │ ├── memory_search_index.cpp │ ├── sqlite3_search_index.cpp │ ├── file_search_index.cpp │ ├── trie.cpp │ ├── bloom_filter.cpp │ └── hot_word_cache.cpp ├── tools/ │ └── log_reader.cpp # 命令行日志读取工具 └── test/ ├── test_terminal.cpp # 终端后端测试 ├── test_local.cpp # 本地后端测试 ├── test_tcp.cpp # TCP 后端测试 ├── test_udp.cpp # UDP 后端测试 ├── test_pipe.cpp # PIPE 后端测试 ├── test_unixSock.cpp # UnixSocket 后端测试 ├── test_sqlite3.cpp # SQLite3 后端测试 ├── test_mysql.cpp # MySQL 后端测试 ├── test_postgresql.cpp # PostgreSQL 后端测试 └── test_performance.cpp # 性能测试 ``` ## 架构设计 ### 写日志架构 ``` LOG 门面层:持有 mutex + threadPool │ vlog() ▼ microLog::logItfc 基类:level_t, error/warn/info/debug │ vlog() ▼ 各 BACKEND::vlog() 调用线程格式化 → threadPool 异步写入 ``` **va_list 跨线程安全**:格式化在调用线程完成,lambda 只传递 `std::string`,彻底避免栈指针问题。 ### 全文检索架构 ``` log_reader 日志读取器(统一入口) │ ├── search_index_itfc 索引抽象接口 │ │ │ ├── memory_search_index 内存索引(哈希表 + 布隆过滤器) │ ├── sqlite3_search_index SQLite3索引(数据库 + 布隆过滤器) │ └── file_search_index 文件索引(倒排索引 + mmap + 布隆过滤器) │ │ │ ├── .dict 词典文件(关键词元信息) │ └── .posting 倒排列表文件(差值编码 + Varint压缩) │ └── hot_word_cache 热词缓存(LRU策略) ``` **倒排索引原理**:将日志内容分词后,构建"关键词 → 日志ID列表"的映射关系,支持快速全文检索。 详细架构文档见 [doc/ARCHITECTURE.md](doc/ARCHITECTURE.md),包含完整的系统架构图、调用时序图、存储格式设计和性能数据。 ## tinySeqFile vs 其他方案 | 特性 | tinySeqFile | spdlog | glog | SQLite3 | |------|------------|--------|------|---------| | **嵌入式友好** | ✅ | ❌ | ❌ | ✅ | | **掉电安全** | ✅ | ❌ | ❌ | ✅ | | **Flash 寿命保护** | ✅ | ❌ | ❌ | ❌ | | **数据库后端** | ✅ | ❌ | ❌ | — | | **异步写入** | ✅ | ✅ | ✅ | ✅ | | **mmap 优化** | ✅ | ❌ | ❌ | ❌ | | **AES 加密** | ✅ | ❌ | ❌ | ❌ | | **零核心依赖** | ✅ | ❌ | ❌ | ❌ | ## 测试 ### 性能测试 - 测试环境: ``` 测试环境: WSL2 设备名称 USER-20260105RT 处理器 Intel(R) Core(TM) i7-14700HX (2.30 GHz) 机带 RAM 32.0 GB (31.8 GB 可用) 图形卡 NVIDIA GeForce RTX 4090 (16 GB) 存储 已使用 932 GB 中的 364 GB 内存详情 内存1名称 4800 MHz 厂商 JUHOR 大小 16 GB 频率 4800 MHz 插槽 Controller0-ChannelA-DIMM0 数据宽度 64 内存2名称 4800 MHz 厂商 JUHOR 大小 16 GB 频率 4800 MHz 插槽 Controller1-ChannelA-DIMM0 数据宽度 64 ``` - 本地文件后端 ```bash root@USER-20260105RT:/mnt/e/work/rocktech/dev/log/build/bin/debug# ./test_performance -t 8000000 -b local === test_performance === Backend: local Messages: 8000000 Results: Time: 2736 ms Rate: 2.92398e+06 msg/s Avg latency: 0.342 us PASS ``` --- ```bash root@USER-20260105RT:/home# ./test_performance -t 200000000 -b local === test_performance === Backend: local Messages: 200000000 Results: Time: 77241 ms Rate: 2.5893e+06 msg/s Avg latency: 0.386205 us PASS ``` - 终端后端 ```bash root@USER-20260105RT:/mnt/e/work/rocktech/dev/log/build/bin/debug# ./test_performance -t 40000 -b terminal === test_performance === Backend: terminal Messages: 40000 Results: Time: 221 ms Rate: 180995 msg/s Avg latency: 5.525 us PASS ``` - TCP 后端 - UDP 后端 ```bash root@USER-20260105RT:/mnt/e/work/rocktech/dev/log/build/bin/debug# ./test_performance -t 40000 -b udp === test_performance === Backend: udp Messages: 40000 Results: Time: 72 ms Rate: 555556 msg/s Avg latency: 1.8 us PASS ``` - UNIXSOCK 后端 - MySQL 后端(双连接 + 事务批量提交) ``` === test_performance === Backend: mysql Messages: 100000 Results: Time: 1941 ms Rate: 51519.8 msg/s Avg latency: 19.41 us PASS ``` - PostgreSQL 后端 - SQLite3 后端 ```bash root@USER-20260105RT:/mnt/e/work/rocktech/dev/log/build/bin/debug# ./test_performance -t 40000 -b sqlite3 === test_performance === Backend: sqlite3 Messages: 40000 Results: Time: 419 ms Rate: 95465.4 msg/s Avg latency: 10.475 us PASS ``` ### 内存测试 - 本地文件后端 - 终端后端 - TCP 后端 - UDP 后端 - UNIXSOCK 后端 - MySQL 后端 - PostgreSQL 后端 - SQLite3 后端 ```bash root@USER-20260105RT:/mnt/e/work/rocktech/dev/log/build/bin/debug# valgrind --leak-check=full ./test_performance -t 40000 -b sqlite3 e3 ==3289120== Memcheck, a memory error detector ==3289120== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al. ==3289120== Using Valgrind-3.22.0 and LibVEX; rerun with -h for copyright info ==3289120== Command: ./test_performance -t 40000 -b sqlite3 ==3289120== === test_performance === Backend: sqlite3 Messages: 40000 Results: Time: 489115 ms Rate: 81.7804 msg/s Avg latency: 12227.9 us PASS ==3289120== ==3289120== HEAP SUMMARY: ==3289120== in use at exit: 0 bytes in 0 blocks ==3289120== total heap usage: 18,336,460 allocs, 18,336,460 frees, 1,210,106,458 bytes allocated ==3289120== ==3289120== All heap blocks were freed -- no leaks are possible ==3289120== ==3289120== For lists of detected and suppressed errors, rerun with: -s ==3289120== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ``` ## 许可证 MIT License ## 作者 宋炜