Skip to content
orangeboyChenPublic

About

Rust port of Tencent/mars — the xlog logging pipeline, the STN task model and the SDT network diagnosis, shipped as a Rust crate, a C ABI, a Swift package and Kotlin/Android artifacts.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

310 Commits

Folders and files

Repository files navigation

mars, in Rust

Rust codecov License: MIT

Rust implementation of Tencent/mars, the mobile library WeChat runs on. It is the same three pieces the C++ project is:

piece what it is
xlog the logging pipeline — a logger that writes off the thread that called it
STN the task model: a request with a channel, a timeout and a retry behind it
SDT the network diagnosis: the probes that say which end a connection broke at

One Rust core writes all three, and a package per platform hands that core to an app that is not Rust. What the logger writes is the .xlog the C++ implementation writes — same framing, same compression, same encryption — so the decoders that came with upstream, and any tooling built on them, read these files without a conversion step.

Documentation — English · 简体中文 — install, configure, write, and read the files back. The site is one tab per piece: the logger, the task pipeline and the network diagnosis. Not every package carries the last two — use it says which do.

Where it runs

your app is what you take where it comes from
Rust marsrs / marsrs-xlog the tag of this repository — crates.io publication is pending
iOS 12+, watchOS 10+, Swift or Objective-C the MarsRSXlog product or pod SwiftPM or CocoaPods, from this repository
Android, Kotlin or Java xlog / marsrs JitPack
Kotlin Multiplatform xlog-kmp / marsrs-kmp GitHub Packages, or the release's marsrs-kmp-maven.zip
Flutter marsrs_xlog / marsrs pub.dev, or the release's marsrs-flutter-xlog-<version>.tar.gz
React Native 0.74+ marsrs-react-native-xlog / marsrs-react-native npm, or the release's marsrs-react-native-xlog-<version>.tgz
anything with a C or C++ FFI the marsrs-<version>-<host> archive the release: Linux, macOS and Windows hosts
HarmonyOS marsrs-harmonyos-xlog, or the three .so of marsrs-harmony-<version>.tar.gz the release — ohpm is not switched on yet

The Kotlin Multiplatform package is the widest of them: the same calls in shared code write the same file on Android, iOS, watchOS, tvOS, macOS, Linux and Windows, each platform compiling the half that reaches this core — JNI on Android, cinterop over the C ABI everywhere else. HarmonyOS has both ways in: marsrs-harmonyos-xlog is the package, a HAR an app installs and writes ArkTS through, and marsrs-harmony-<version>.tar.gz is the three .so and the header for an app that would rather write NAPI of its own.

Every release also ships the xlog CLI, which writes and reads those files from a shell and makes the key pair that decides who can — as marsrs-xlog-cli-<version>-<host> on the release, or off the tag with cargo install --git https://github.com/orangeboyChen/mars-rs --tag v0.1.0-alpha.3 marsrs-xlog — and then xlog keygen.

Every one of those platforms has a demo in demo/ — one directory each, and the same seven records written in all eight — one at each level, and one behind a level check — so that what differs between them is what the platform makes of it and not what the app does.

Use it

Two ways in, and the difference is how much of the port you take: xlog alone, or the whole port — xlog, STN and SDT. An app that only logs takes the first; the pair is the same one the crates are. Two of the packages carry the logger under both names without the other two pieces — Flutter's marsrs and marsrs-react-native have no STN or SDT surface yet, so on those two the choice is one of name and not of contents. Everywhere else the wider name is the wider port: marsrs on Android, marsrs-kmp in shared Kotlin and the MarsRS product on Apple are where an app reaches the task pipeline and the diagnosis, and the C archive ships every header beside the libraries: mars_xlog.h and the mars_xlog.hpp beside it, and mars_sdt.h and mars_stn.h.

# The crates are not on crates.io yet — publication is pending — so a Rust app
# takes them off the tag: `cargo add marsrs-xlog` on its own resolves nothing.
# xlog alone — the logger and nothing else:
cargo add marsrs-xlog --git https://github.com/orangeboyChen/mars-rs --tag v0.1.0-alpha.3
# the whole port: + STN, SDT
cargo add marsrs --git https://github.com/orangeboyChen/mars-rs --tag v0.1.0-alpha.3
// Package.swift
.package(url: "https://github.com/orangeboyChen/mars-rs", from: "0.1.0-alpha.3")
.product(name: "MarsRSXlog", package: "mars-rs")   // or "MarsRS", for both halves
# Podfile — Swift or Objective-C
pod 'MarsRSXlog', :podspec => 'https://raw.githubusercontent.com/orangeboyChen/mars-rs/v0.1.0-alpha.3/MarsRSXlog.podspec'

The pods are not on a spec repo, so the podspec is fetched out of the tag it names — the releases page is where the newest one is.

// settings.gradle.kts: maven { url = uri("https://jitpack.io") }
implementation("io.github.orangeboychen.marsrs:xlog:0.1.0-alpha.3")    // xlog alone
implementation("io.github.orangeboychen.marsrs:marsrs:0.1.0-alpha.3")  // + STN, SDT

// build.gradle.kts of a Kotlin Multiplatform shared module
implementation("io.github.orangeboychen.marsrs:xlog-kmp:0.1.0-alpha.3")
implementation("io.github.orangeboychen.marsrs:marsrs-kmp:0.1.0-alpha.3")
# HarmonyOS — ArkTS; xlog only, for now. ohpm is not switched on yet, so a
# release is where the package comes from:
ohpm install marsrs-harmonyos-xlog-<version>.har

Then the same three steps on every platform: open an appender once when the app starts, write through it, and flush before you read or upload its files.

use marsrs::xlog::{LogLevel, XLogConfig, Xlog};

let mut config = XLogConfig::default();
config.logdir = std::path::PathBuf::from("/tmp/mars-log");
config.nameprefix = "marsrs".to_owned();

let xlog = Xlog::open(config, LogLevel::Info)?;
xlog.i("startup", "hello from mars");

xlog.flush_now();   // the records are on disk when this returns
val xlog = Xlog.open(
    XlogConfig(
        logDir = File(context.filesDir, "xlog/log").path,
        namePrefix = "marsrs",
        level = LogLevel.INFO,
    )
)
xlog.i("startup", "cold start in $elapsedMillis ms")

xlog.flushNow()  // before the app reads or uploads the files

The file is <logDir>/<namePrefix>_YYYYMMDD.xlog — marsrs_20260927.xlog above. The default mode is async, so a record can sit in the cache for a moment: flush before the file is read or uploaded.

There are three drains, and two of them on every platform: what Dart has no face for is the blocking one, and what HarmonyOS has no face for is the awaited one.

Rust Kotlin, Swift, TypeScript what the caller gets back
xlog.flush_now() xlog.flushNow() the records are on disk when it returns
xlog.flush().await await xlog.flush() the same drain, off the calling thread
xlog.request_flush() xlog.requestFlush() nothing: it asks and returns at once

request_flush is what a timer calls — what is still in the cache sits in a file the kernel holds, so a drain that has not happened yet has lost nothing. The two that answer are the ones an app wants before it reads or uploads.

Every option, and its name on each platform, is on the configuration page; what has to happen when the app goes away is on log files.

License

MIT, like the upstream project — see LICENSE.

About

Rust port of Tencent/mars — the xlog logging pipeline, the STN task model and the SDT network diagnosis, shipped as a Rust crate, a C ABI, a Swift package and Kotlin/Android artifacts.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages