base_logger_core --- 跨平台 C++ 日志核心库

base_logger_core ------ 跨平台 C++ 日志核心库

跨平台 C++ 日志核心库,提供基于 mmap 的环形缓冲区文件写入,内置预设字典的 deflate 压缩。支持 Android、iOS、HarmonyOS NEXT 三端。

实现原理图:

架构概览

text 复制代码
┌─────────────────────────────────────────────────────────────┐
│  平台壳层 (Kotlin / Swift / ArkTS)                           │
│  ├── 异步队列、消费者线程、控制台输出                            │
│  ├── 生命周期管理                                             │
│  └── Native 桥接 (JNI / 直接链接 / NAPI)                     │
└─────────────────────────────────────────────────────────────┘
         │
         ▼
┌─────────────────────────────────────────────────────────────┐
│  mcd_logger_core (本库)                                      │
│  ├── McdLogWriter    --- 统一门面 (open/write/flush/close)      │
│  ├── GzipEncoder     --- zlib raw deflate + 预设字典压缩         │
│  └── CircularBuffer  --- mmap 环形缓冲区 + 文件头管理            │
└─────────────────────────────────────────────────────────────┘

核心功能

  1. 结构化日志写入:上层传入 timestampMs、level、tag、msg,核心层格式化为标准日志行
  2. 日志格式:yyyy-MM-dd HH:mm:ss.SSS LEVEL tag msg
  3. 压缩存储:使用预设字典的 raw deflate 压缩,显著减小日志体积
  4. mmap 环形缓冲区:崩溃安全,数据直接映射到文件,避免 write 系统调用开销
  5. 线程模型:核心层本身非线程安全,由平台壳层保证单线程/协程调用

API 接口

// 日志等级枚举

cpp 复制代码
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 日志文件

cpp 复制代码
 McdLogWriter* mcd_log_writer_open(const char* filePath, int64_t maxDataSize);

// 写入一条结构化日志(内部自动格式化、压缩)

cpp 复制代码
 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 数据刷盘

cpp 复制代码
void mcd_log_writer_flush(McdLogWriter* writer);

// 关闭并释放所有资源

cpp 复制代码
void mcd_log_writer_close(McdLogWriter* writer);

调用示例

Kotlin (Android JNI):

cpp 复制代码
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 这是一条测试日志

文件格式

文件布局

cpp 复制代码
┌──────────────────────────────────────────────────┐
│ 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。 效果图如下:

构建要求

cpp 复制代码
CMake
≥ 3.16


Clang
平台 SDK 自带


C++
C++11


Ninja
推荐(可选,Make 也可以)

各平台构建

Android

java 复制代码
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

kotlin 复制代码
./platforms/ios/build.sh Release
# 产物: build/ios/McdLoggerCore.xcframework/

HarmonyOS NEXT

cpp 复制代码
export OHOS_NDK_HOME=/path/to/sdk/default/openharmony/native
./platforms/ohos/build.sh Release
# 产物: build/ohos/arm64-v8a/libmcd_logger_core.so

本地开发(macOS)

cpp 复制代码
cmake -B build -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build build
# 产物: build/libmcd_logger_core.a

C++ 运行时策略

目录结构

cpp 复制代码
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          # 冒烟测试
相关推荐
苦瓜花1 小时前
【Kotlin】初入门
android·开发语言·kotlin
dora2 小时前
使用 Cling 实现 DLNA 投屏:从局域网发现到媒体播放控制
android·android things·tvos
apihz3 小时前
全球域名 WHOIS 信息实时查询免费 API 接口教程,支持1000+后缀
android·网络·网络协议·tcp/ip·apache·域名·whois
非典型Android程序员5 小时前
Binder机制学习总结
android
AI2中文网5 小时前
App Inventor 2 音频播放器 vs 音效 vs 视频播放器:三个媒体组件,选错了App直接卡死
android·音视频·媒体
李剑一5 小时前
uni-app x 实现本地 JSON 文件的导入导出(APP端可用)
android·前端·uni-app
喜欢打篮球的普通人5 小时前
LLVM后端指令选择
android·java·javascript
hunterandroid5 小时前
Room 数据库迁移:让本地数据升级更稳
android·前端
阿巴斯甜5 小时前
Compose NavHost的使用:
android