Mobile Development 14 min read

Holmes Dynamic Logging System for Mobile Apps: Automatic Instrumentation and Runtime Lua Scripting

Holmes is a zero‑cost dynamic logging system for Android apps that automatically instruments every method to emit trace logs, stores them locally, and lets developers remotely retrieve precise execution histories and run Lua scripts for on‑device snapshots, dramatically reducing debugging time despite fragmentation and low performance impact.

Meituan Technology Team
Meituan Technology Team
Meituan Technology Team
Holmes Dynamic Logging System for Mobile Apps: Automatic Instrumentation and Runtime Lua Scripting

Meituan is a global leading one‑stop life‑service platform serving over 600 million users and 4.5 million merchants. Its mobile client faces a huge variety of user‑side issues such as pages failing to load, unresponsive buttons, login failures, or order submission problems. Because of Android fragmentation, diverse network environments, ROMs, OS versions and complex local setups, reproducing these bugs locally is extremely difficult.

Existing mitigation methods include distributing temporary builds, QA attempts to reproduce the issue, online debugging tools, and manual instrumentation. These approaches suffer from cumbersome user cooperation, low reproducibility, high debugging cost, and massive redundant data.

The goal is to obtain precise online logs quickly, with little or no manual instrumentation, and to capture the exact execution context of the problem.

Holmes, a dynamic logging system, automatically records method execution traces (TraceLog) on the user’s device. When an issue is reported, a signal can retrieve the relevant logs, and the system can also push dynamic code to the device for runtime analysis, such as taking object snapshots.

Automatic instrumentation inserts a stub at the beginning of each method to emit a TraceLog containing the method signature, process, thread, and timestamp, which is then stored in a local database awaiting remote retrieval.

public void onCreate(Bundle bundle) { // instrumentation code
    if (Holmes.isEnable(....)) {
        Holmes.invoke(....);
        return;
    }
    super.onCreate(bundle);
    setContentView(R.layout.main);
}

TraceLog provides a complete historical execution path, requiring no manual points, covering all business code, and remaining effective after ProGuard because instrumentation occurs before code shrinking. Logs can be retrieved centered on a specific method, reducing noise and analysis time.

The processing pipeline includes a checker that filters thread‑level noise (e.g., periodic tasks) and high‑frequency methods, then asynchronously pools TraceLog objects, assembles metadata, and batches them into the database. A visual Trace platform displays the logs in chronological order.

When a problem is narrowed down to a particular method, developers need the method’s parameters, field values, and return data. Holmes addresses this by dynamically delivering Lua scripts that run immediately, before the target method, or after it, collecting the required snapshot information.

Because Holmes only instruments method entry, executing a script after the method requires invoking the original method via reflection from the stub, avoiding extra instrumentation and preventing infinite loops by marking reflective calls.

The Lua runtime is tiny, can call Java APIs, and supports extended capabilities such as DB queries, text reporting, SharedPreferences access, context retrieval, permission checks, adding custom points, and file uploads.

Technical challenges include handling massive log volumes, main‑thread blocking, I/O pressure, frequent GC, and noisy logs. Solutions involve CAS‑based lock‑free structures, object pools, multi‑level filtering, and a binary flag per method to enable/disable logging with negligible overhead.

Performance tests on mid‑range devices show an average overhead of 55‑65 ms for one million instrumented calls, CPU usage under 5 %, and memory footprint around 56 KB.

For object snapshots, Holmes implements a deep‑clone library that creates an empty shell of the target object and copies all fields via reflection, handling primitive types, collections, maps, and Android‑specific classes efficiently.

In summary, Holmes provides zero‑cost dynamic logging for Android development, dramatically shortening the time to locate bugs and serving as a foundation for other dynamic code‑execution needs such as crash‑time data collection.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Androiddynamic loggingruntime scripting
Meituan Technology Team
Written by

Meituan Technology Team

Over 10,000 engineers powering China’s leading lifestyle services e‑commerce platform. Supporting hundreds of millions of consumers, millions of merchants across 2,000+ industries. This is the public channel for the tech teams behind Meituan, Dianping, Meituan Waimai, Meituan Select, and related services.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.