Mars-XLog

1. 介绍

xlog是微信官方的终端基础组件mars中可以独立使用的日志模块,是一个使用c++编写的业务行无关,平台性无关的基础组件。目前已接入微信Android、IOS、Mac、Window、WP等客户端。

1.1 优点

  1. 使用C++高性能记录日志,避免了使用Java在加密,压缩过程中产生的大量GC。

  2. 使用mmap,既有直接写内存的性能,又有直接写文件的可靠性。

    1. 使用mmap,避免了写文件时内核空间和用户空间频繁切换,以及dirty page回写时带来的不可控的CPU峰值。

      1. 写文件时,Dirty page的回写时机:

        1. 定时回写。
        2. 调用 write 的时候,发现 dirty page 占用内存超过系统内存一定比例。
        3. 内存不足。
      2. mmap的回写时机:

        1. 不设置 MAP_NOSYNC 情况下 30s-60s(仅限FreeBSD,一款类UNIX操作系统)
        2. 调用 msync 或者 munmap
        3. 进程 crash
        4. 内存不足
    2. 使用mmap,避免了使用内存作为写文件的中间buffer时,当程序被系统杀死或发生crash,在内存中的日志信息丢失。

  3. 默认提供压缩功能。

    1. 先压缩再加密。效率比先加密再压缩高。因为压缩后数据量变少,并且加密前重复字符也比较多(时间等)。
    2. 流式压缩日志,避免多条日志集中压缩导致的cpu峰值导致程序卡顿。
    3. 一定大小作为一个压缩单位,即使压缩单位中有部分数据单位损坏,不影响这个单位中损坏部分之前的数据,只影响这个单位中损坏部分之后的数据。
  4. 默认提供 ECDH+TEA的混合加密算法。

    1. ECDH密钥协商层(安全通道建立)
    2. TEA数据加密层(高效传输)
  5. 启动时清理日志,避免占用户空间。

2. 如何引入

2.1 Gradle

build.gradle 复制代码
dependencies {
    implementation 'com.tencent.mars:mars-xlog:1.2.6'
}

2.2 本地编译

2.2.1 安装环境

  1. 安装cmake,在安装过程中勾选添加到环境变量,或者手动把cmake的bin目录配置到环境变量中。

  2. 安装python,要求3.10版本以上。在安装过程中勾选添加到环境变量,或者手动配置环境变量指向python路径。

    1. python从3.6版本开始,在命令行时输入的不是python、python3,而是py

    2. 如果是在Windows 11上,可能会出现运行时启动应用商店的情况。打开设置,在应用>高级应用设置>应用执行别名,关闭应用安装程序即可。

  3. 下载ndk-r20b,并配置环境变量 NDK_ROOT 指向 ndk 路径。

  4. 如果是Windows系统还要安装cygwin,要安装其中的make,gcc,gbd,然后把cygwin的bin目录配置到环境变量中。

2.2.2 编译

  1. 所有的编译脚本都在mars/mars 目录, 运行编译脚本之前也必须cd到此目录,在当前目录下运行,默认是编译 armeabi-v7a,arm64-v8a的,如果需要其他 CPU 架构,把编译脚本中的aarchs = {'armeabi-v7a', 'arm64-v8a'}稍作修改即可。

  2. 执行命令

    复制代码
       py build_android.py
  3. 执行后,会让选择

    markdown 复制代码
       Enter menu:
       1. Clean && build mars.
       2. Build incrementally mars.
       3. Clean && build xlog.
       4. Exit
       ```
  4. 选择3

  5. 输出结果全部在 mars/mars/libraries/mars_xlog_sdk 目录中,把mars_xlog_sdk/src目录下的java文件,以及mars_xlog_sdk/libs目录下的so文件复制到你的项目中。

3. 如何使用

3.1 初始化XLog

在Application或着别的地方初始化XLog

ini 复制代码
private void initXLog() {
    final String logPath = this.getFilesDir() + "/xlog";
    // this is necessary, or may crash for SIGBUS
    final String cachePath = this.getFilesDir() + "/xlog_cache";

    // privateKey = "145aa7717bf9745b91e9569b80bbf1eedaa6cc6cd0e26317d810e35710f44cf8"
    String publicKey = "572d1e2710ae5fbca54c76a382fdd44050b3a675cb2bf39feebe85ef63d947aff0fa4943f1112e8b6af34bebebbaefa1a0aae055d9259b89a1858f7cc9af9df1";
    String logFileNamePrefix = "xlog";
    // debug包最低输出Verbose级别的日志,release包最低输出Info级别的日志
    int logLevel = BuildConfig.DEBUG ? Xlog.LEVEL_VERBOSE : Xlog.LEVEL_INFO;
    Xlog.open(true, logLevel, Xlog.AppednerModeAsync, cachePath, logPath, logFileNamePrefix, publicKey);

    Xlog xlog = new Xlog();
    // debug包输出日志到控制台,release包则不输出
    xlog.setConsoleLogOpen(0, BuildConfig.DEBUG);
    Log.setLogImp(xlog);
}

注意如果App使用了多进程,不要把多个进程的日志输出到同一个文件中,保证每个进程独享一个日志文件。而且保存 log 的目录请使用单独的目录,不要存放任何其他文件防止被 xlog 自动清理功能误删。

3.2 输出日志

像Android的Log一样使用XLog的Log,例如:

scss 复制代码
Log.d(TAG, Message)

3.3 关闭日志

在退出程序时关闭日志:

ini 复制代码
Log.appenderClose();

不要在Application的onTermincate()中调用,因为这个方法在模拟器上才会被回调

csharp 复制代码
 /**
* This method is for use in emulated process environments.  It will
* never be called on a production Android device, where processes are
* removed by simply killing them; no user code (including this callback)
* is executed when doing so.
*/
@CallSuper
public void onTerminate() {
}

可以在例如App的MainActivity#onBackpress()这些退出App的方法中调用

4. 查看日志

4.1 从设备下载日志文件

如果按 3.1 的代码设置日志路径,getFilesDir()对应的路径是 /data/data/你的应用包名/files,这个目录在手机文件管理器是看不到的,可以通过Android Studio的Device Explorer,找到xlog目录下的日志文件

4.2 解密日志文件

4.2.1 仅压缩

如果不想使用加密模块,public key 参数设置为空字符即可,解密脚本使用 decode_mars_nocrypt_log_file.py, 但这样日志会只压缩不加密。

4.2 使用第三方解密软件

  1. 下载 compose-multiplatform-xlog-decode 或者 YXlogDecode

  2. 用软件打开日志文件,并设置 privateKey

  3. 解密日志

4.3 使用官方解密方式

参考 XLog加密使用指引 配置环境并解密日志

相关推荐
anOnion19 小时前
构建无障碍组件之Menu Button pattern
前端·html·交互设计
用户479492835691519 小时前
claude Fable用不了?把Gpt 5.5pro接到你的claude code里
前端·后端
zhangxingchao1 天前
Kotlin常用的Flow 操作符整理
前端
IT_陈寒1 天前
React的useState居然还有这种坑?我差点删库跑路
前端·人工智能·后端
Pedantic1 天前
SwiftUI 手势笔记
前端·后端
橙子家1 天前
浏览器缓存之【结构化数据库与缓存】: IndexedDB、Cache storage 和 Storage buckets
前端
user20585561518131 天前
X6 中边悬浮置顶,规避 `mouseleave` 事件丢失问题
前端
李明卫杭州1 天前
CSS aspect-ratio 属性完全指南
前端
Pedantic1 天前
SwiftUI 手势层级(Gesture Hierarchy)详解
前端