base_logger_core --- 跨平台 C++ 日志核心库
·
base_logger_core —— 跨平台 C++ 日志核心库
跨平台 C++ 日志核心库,提供基于 mmap 的环形缓冲区文件写入,内置预设字典的 deflate 压缩。支持 Android、iOS、HarmonyOS NEXT 三端。
实现原理图:
架构概览
┌─────────────────────────────────────────────────────────────┐
│ 平台壳层 (Kotlin / Swift / ArkTS) │
│ ├── 异步队列、消费者线程、控制台输出 │
│ ├── 生命周期管理 │
│ └── Native 桥接 (JNI / 直接链接 / NAPI) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ mcd_logger_core (本库) │
│ ├── McdLogWriter — 统一门面 (open/write/flush/close) │
│ ├── GzipEncoder — zlib raw deflate + 预设字典压缩 │
│ └── CircularBuffer — mmap 环形缓冲区 + 文件头管理 │
└─────────────────────────────────────────────────────────────┘
核心功能
- 结构化日志写入:上层传入 timestampMs、level、tag、msg,核心层格式化为标准日志行
- 日志格式:[yyyy-MM-dd HH:mm:ss.SSS] [LEVEL] [tag] msg
- 压缩存储:使用预设字典的 raw deflate 压缩,显著减小日志体积
- mmap 环形缓冲区:崩溃安全,数据直接映射到文件,避免 write 系统调用开销
- 线程模型:核心层本身非线程安全,由平台壳层保证单线程/协程调用
API 接口
// 日志等级枚举
typedef enum McdLogLevel {
MCD_LOG_LEVEL_VERBOSE = 0,
MCD_LOG_LEVEL_DEBUG = 1,
MCD_LOG_LEVEL_INFO = 2,
MCD_LOG_LEVEL_WARNING = 3,
MCD_LOG_LEVEL_ERROR = 4
} McdLogLevel;
// 打开/创建 mmap 日志文件
McdLogWriter* mcd_log_writer_open(const char* filePath, int64_t maxDataSize);
// 写入一条结构化日志(内部自动格式化、压缩)
bool mcd_log_writer_write(McdLogWriter* writer,
int64_t timestampMs,
McdLogLevel level,
const uint8_t* tag, int32_t tagLen,
const uint8_t* msg, int32_t msgLen);
// 将 mmap 数据刷盘
void mcd_log_writer_flush(McdLogWriter* writer);
// 关闭并释放所有资源
void mcd_log_writer_close(McdLogWriter* writer);
调用示例
Kotlin (Android JNI):
val tag = "MyTag".toByteArray()
val msg = "这是一条测试日志".toByteArray()
McdLogWriterNative.nativeWrite(handle, System.currentTimeMillis(), McdLogLevel.WARNING.ordinal, tag, msg)
生成的日志行:
[2026-05-26 11:28:10.079] [WARNING] [MyTag] 这是一条测试日志
文件格式
文件布局
┌──────────────────────────────────────────────────┐
│ Metadata Header (64 bytes, Big-Endian) │
│ offset 0: magic (uint32) = 0x4D4C4F47 │
│ offset 4: version (uint32) = 1 │
│ offset 8: writePos (int64) │
│ offset 16: readPos (int64) │
│ offset 24: wrapFlag (int32) — 1=已回绕 │
│ offset 28: dictVersion (int32) │
│ offset 32: wrapCount (uint32) — 回绕计数 │
│ offset 36: reserved (28 bytes) │
├──────────────────────────────────────────────────┤
│ Data Region (maxDataSize bytes) │
│ [4B BE length][raw deflate data] ... │
└──────────────────────────────────────────────────┘
文件总大小 = 64 (header) + maxDataSize
环形缓冲区语义
- writePos / readPos 是文件绝对偏移量(包含 64 字节头部)
- 初始值:writePos = readPos = 64
- 当 writePos + entrySize > totalFileSize 时,writePos 回绕到 64,wrapCount++
- 回绕后 readPos 会被推进到写入区域之后,跳过被覆盖的旧条目
条目格式
每条日志条目:[4 字节大端序长度前缀][raw deflate 压缩数据]
压缩使用预设字典的 raw deflate(无 gzip/zlib header),相比标准 gzip:
- 短日志(<200 字节)压缩率提升 30~45%
- 同样磁盘空间可存储 60~70% 更多日志
日志阅读器
reader/index.html 是基于浏览器的可视化日志阅读器,用于读取和展示 mcd_log.dat 文件。
功能:
- 拖拽或点击加载 .dat 文件
- 按级别着色(VERBOSE 灰 / DEBUG 青 / INFO 绿 / WARNING 黄 / ERROR 红)
- 多维过滤:级别、Tag、关键字、时间范围
- 底部状态栏显示元数据:Version、Write Pos、Read Pos、Wrap 状态、Wrap Count、Data 大小、WPP(Write Pos Percent,writePos 在数据区域中的位置百分比)
- 支持刷新(Cmd+R 或点击刷新按钮)
详见 reader/README.md。
效果图如下:
构建要求
CMake
≥ 3.16
Clang
平台 SDK 自带
C++
C++11
Ninja
推荐(可选,Make 也可以)
各平台构建
Android
export ANDROID_HOME=path/to/sdk
export NDK_VERSION=23.1.7779620
./platforms/android/build.sh Release
# 产物: build/android/{arm64-v8a,armeabi-v7a,x86_64}/libmcd_logger_core.so
iOS
./platforms/ios/build.sh Release
# 产物: build/ios/McdLoggerCore.xcframework/
HarmonyOS NEXT
export OHOS_NDK_HOME=/path/to/sdk/default/openharmony/native
./platforms/ohos/build.sh Release
# 产物: build/ohos/arm64-v8a/libmcd_logger_core.so
本地开发(macOS)
cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build build
# 产物: build/libmcd_logger_core.a
C++ 运行时策略

目录结构
mcdloggercore/
├── CMakeLists.txt # 主构建文件
├── include/ # 公开头文件
│ ├── mcd_log_writer.h # 门面 API + 日志等级枚举
│ ├── circular_buffer.h # 环形缓冲区 API
│ ├── gzip_encoder.h # 压缩 API
│ ├── deflate_dict.h # 预设字典
│ └── mcd_logger_core_export.h # 符号可见性宏
├── src/ # 实现
│ ├── mcd_log_writer.cpp # 门面实现(时间戳格式化 + 日志行组装)
│ ├── circular_buffer.cpp # mmap 环形缓冲区
│ ├── gzip_encoder.cpp # raw deflate 压缩(带预设字典)
│ └── deflate_dict.cpp # 预设字典数据
├── platforms/ # 平台桥接 & 构建脚本
│ ├── android/
│ │ ├── build.sh
│ │ ├── mcd_jni_bridge.cpp # JNI 桥接(Kotlin ByteArray → C++)
│ │ └── mcd_logger_core.map
│ ├── ios/
│ │ ├── build.sh
│ │ └── ios.toolchain.cmake
│ └── ohos/
│ ├── build.sh
│ ├── mcd_napi_bridge.cpp # NAPI 桥接(ArkTS ArrayBuffer → C++)
│ └── mcd_logger_core.map
├── reader/ # 浏览器日志阅读器
│ ├── index.html # 阅读器主页面
│ ├── install.sh # 安装 mlr 命令
│ ├── generate_sample.py # 生成测试样例
│ └── generate_wrap_sample.py
└── tests/
└── smoke_test.cpp # 冒烟测试
更多推荐

所有评论(0)