腾讯 Mars XLog 是一个高性能的端上日志打印方案,关于它的介绍和使用,可以看这一篇文章: 腾讯 XLog 日志框架 Android 端接入

腾讯的 Mars XLog 是一个很好的库,但是其在 Github 上已经基本不更新了,其最新的 release 版本 1.3.0 还停留在 7年前。其既没有做 so 的 16K 对齐,也不能指定日志的格式。不过其代码在一年前还有提交,我们可以在其最新的分支上进行修改和编译,生成 16K 对齐的 so 文件,并实现我们想要的日志格式。
编译环境
我用的编译环境为 WIN11 + WSL2,安装的 Linux 为 Ubuntu 26.04 版本。使用到的编译软件如下:
- NDK 版本 R29
- Python 版本 3.14.4
- CMake 版本 4.2.3
WSL2 确实是一个不错的在 Windows 上使用 Linux 的方式,比安装虚拟机要方便很多。安装 WSL2 可以看这篇文章:安装 WSL 最好的方式
在安装完成之后,我们还需要安装一些编译相关的软件,得益于 Ubuntu 的包管理器,我们只需要执行如下的命令即可:
shell
sudo apt update
sudo apt install -y make cmake g++ python3 python3-pip openjdk-17-jdk-headless zip unzip
下载源代码
Mars 的源代码托管在 Github 上:Tencent/mars: Mars is a cross-platform network component developed by WeChat
我们先将源代码下载本地之后,然后选择一个合适的分支进行编译。这里我用的分支是 release/android/2024-t2.1:
我们使用下面的命令将代码切换到这个分支:
shell
git checkout -b release/android/2024-t2.1 origin/release/android/2024-t2.1
编译过程
Mars 的 Android 编译脚本位置为:./mars/build_android.py,在早期的编译脚本中,需要使用 python2 来进行编译,不过最新的代码已经能够支持 python3 了。 我们进入到这个目录中并用 python 执行这个文件:
shell
avril@LenovoPro16:~/code/mars$ cd mars/
avril@LenovoPro16:~/code/mars/mars$ python3 build_android.py
Enter menu:
1. Clean && build mars.
2. Build incrementally mars.
3. Clean && build xlog.
4. Exit
运行编译脚本后,能看到4个选项,我们只编译 xlog,因此这里只需要输入3即可。
不过此时编译肯定是不成功的,我们需要先修改一些文件并配置环境变量。
配置 NDK 环境变量
编译用到的 NDK 是 r29 版本,这已经算是比较新的,可以从这个网址下载:NDK 下载 | Android NDK | Android Developers
下载之后,可以通过 unzip 解压,然后配置环境变量。因为在 build_android.py 脚本中会读取 NDK_ROOT 环境变量,因此我们做如下的配置:
打开 ~/.bashrc 文件,在文件的末尾添加如下内容:
bash
export NDK_ROOT=~/software/android-sdk/android-ndk-r29 # 你的 NDK 路径
配置完成之后别忘记了:
shell
source .bashrc
修改编译脚本文件
由于官方原始的 build_android.py 使用的是老版本的 NDK 进行的编译,而且引用了 NDK 中相关的文件,不过在新版本的 NDK 中,这些文件在 NDK 中的位置发生了变化,因此我们需要更改这个配置文件。
改动有三处:
py
# 一:将 ANDROID_STL_FILE 更改为:
ANDROID_STL_FILE = {
'armeabi': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi/libc++_shared.so',
'armeabi-v7a': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/arm-linux-androideabi/libc++_shared.so',
'x86': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/i686-linux-android/libc++_shared.so',
'arm64-v8a': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/libc++_shared.so',
'x86_64': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so',
}
# 二:将 ANDROID_STRIP_FILE 更改为:
ANDROID_STRIP_FILE = {
'armeabi': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip',
'armeabi-v7a': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip',
'x86': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip',
'arm64-v8a': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip',
'x86_64': NDK_ROOT + '/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip',
}
# 三:将 get_android_strip_cmd(arch) 方法中的
strip_cmd = ANDROID_STRIP_FILE[arch] %(system_str)
# 更改为:
strip_cmd = ANDROID_STRIP_FILE[arch]
进入上面的更改之后,我们还需要修改 CMake 的编译选项。
修改文件抑制cmake警告
官方版本编译时使用的 cmake 太旧,当我们用新的 cmake 进行编译时,会碰到很多过时的语法或定义,而一旦碰到这种问题,就会编译失败。因此我们需要更改如下的文件,以抑制警告。
mars/build_android.py
还是这个文件,我们需要找到 ANDROID_BUILD_CMD 这个变量,添加 -DCMAKE_CXX_FLAGS="-Wno-error" ,最终的 ANDROID_BUILD_CMD 的结果如下:
python
ANDROID_BUILD_CMD = 'cmake "%s" %s -DANDROID_ABI="%s" ' \
'-DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=%s/build/cmake/android.toolchain.cmake '>
'-DANDROID_TOOLCHAIN=clang -DANDROID_NDK=%s ' \
'-DANDROID_PLATFORM=android-21 ' \
'-DANDROID_STL="c++_shared" ' \
'-DCMAKE_CXX_FLAGS="-Wno-error" ' \
'&& cmake --build . %s --config Release -- -j8'
mars/comm/CMakeExtraFlags.txt
修改这个文件的第三行:
ini
# 将原始的
set(SELF_EXTRA_FLAGS "-Werror -Wall -Werror=sign-compare -Wtype-limits -Wuninitialized -Wempty-body")
# 修改为
set(SELF_EXTRA_FLAGS "-Werror -Wall -Werror=sign-compare -Wtype-limits -Wuninitialized -Wempty-body -Wno-error=deprecated-builtins -Wno-error=deprecated-declarations -Wno-deprecated-builtins -Wno-deprecated-declarations")
修改 exp 文件
修改 mars/libraries/mars_android_sdk/jni/export.exp 文件,删除其中的三行:
makefile
{
global:
__xlogger_Print_impl; # 删除此行
...
local:
_Z22appender_set_console_logb; # 删除此行
_Z24appender_set_console_logb; # 删除此行
*;
}
这三个符号在新版 NDK 编译时不存在或已变更,不删除会导致链接时出现 undefined symbol 错误。
其中 __xlogger_Print_impl 是 XLog 的核心打印函数,_Z22appender_set_console_logb 和 _Z24appender_set_console_logb 是 C++ 编译器修饰后的控制台日志开关函数。在新版 NDK 的编译环境下,这些符号的实现已变更,导出声明与实际编译结果不匹配,因此需要从导出列表中移除。
修改了上述 3个文件之后,应该就可以编译成功了:

编译结果 mars_xlog_sdk 库
编译结果的 so 将会放到 mars_xlog_sdk 库中,打开这个文件夹,你会发现这就是一个 android 的 library module。而编译完成后,mars_xlog_sdk/ 目录就变成了一个完整的 Android Library Module,包含 jni/ 下的 libmarsxlog.so 和 libc++_shared.so(armeabi-v7a 和 arm64-v8a 两种架构)。
此时,就可以直接将这个库复制到你的项目里,用你的 app 模块直接依赖这个库就可以使用 XLog 了:

如果你不想直接依赖 mars_xlog_sdk 这个 library module,可以从这个 module 中直接编译出一个 aar 使用。可以使用下面的命令生成 aar:
shell
.\gradlew :mars_xlog_sdk:assembleRelease
使用这个命令之后,就会在 mars_xlog_sdk/build/outputs/aar 目录下生成 mars_xlog_sdk-release.aar 文件。
另外官方的 XLog 中没有提供混淆,但是在使用时,还是建议添加混淆文件:
csharp
# 保留 XLog 的 JNI 类,不能混淆
-keep class com.tencent.mars.** { *; }
-keep class com.tencent.mars.xlog.** { *; }
# 保留 native 方法(JNI 入口)
-keepclasseswithmembernames class * {
native <methods>;
}
如果你对 XLog 做了自己的封装,还需要在封装类的 module 中通过 consumer-rules 保留封装类的包名。
修改日志格式
上面就是编译 XLog 的所有内容,如果只是为了解决 so 的 16K 对齐的问题,那么你这么编译出来的 so 就已经完成了 16K 对齐。但是从源码编译还能给我们带来更大的自由度,例如我们可以修改日志的打印格式。
修改日志头格式
日志头的内容是每次创建新日志文件时自动写入的文件头部信息,包含编译日期、版本号、磁盘空间等信息:
yaml
^^^^^^^^^^Jul 30 2026^^^16:07:53^^^^^^^^^^[16710,16710][2026-07-30 +0800 17:01:47]
get mmap time: 1
MARS_URL:
MARS_PATH: release/android/2024-t2.1
MARS_REVISION: 041a3c49
MARS_BUILD_TIME: 2026-07-30 16:07:46
MARS_BUILD_JOB:
log appender mode:0, use mmap:1
cache dir space info, capacity:114502369280 free:61877350400 available:61654315008
log dir space info, capacity:114502369280 free:61877350400 available:61654315008
如果要修改这一部分内容的格式,我们需要修改 mars/xlog/src/appender.cc 文件: 
修改日志前缀格式
通过XLog 打印的日志默认格式为:
css
[I][2026-07-29 +8.0 19:09:42.286][27360, 2*][xlog_tag][:0, ][日志信息:time = 1785323382286, count = 1[D][2026-07-29 +8.0 19:09:42.287][27360, 2*][xlog_tag][:0, ][日志信息:time = 1785323382287, count = 2[W][2026-07-29 +8.0 19:09:42.288][27360, 2*][xlog_tag][:0, ][日志信息:time = 1785323382287, count = 3[E][2026-07-29 +8.0 19:09:42.288][27360, 2*][xlog_tag][:0, ][日志信息:time = 1785323382288, count = 4
- 其中 2026-07-29 +8.0 19:09:42.286 是 日期 + 时区偏移(+8.0 = UTC+8) + 时间(毫秒)
- 其中 27360, 2\* 是进程ID 和线程ID,* 表示该线程是主线程
- 其中 :0, 是文件名和行号,这个在 Java 中拿不到
如果我们需要修改日志打印时的默认前缀,则需要修改 mars\xlog\src\formater.cc 文件: 
修改控制台日志格式
如果我们还要修改在控制台打印的日志的格式时,则需要修改 mars/xlog/jni/ConsoleLog.cc 文件:
将上述的内容更改为自己想要日志格式后,再次重新打包,就可以使用自己日志格式了。