Mobile Development 8 min read

Upgrading the Event Logging Framework: Native Layer Design, Implementation, and Hybrid Stack Solutions

This article explains the motivations for upgrading a mobile event‑logging framework, describes the native C‑based log system design and implementation with code examples, addresses precise exposure challenges, and presents a hybrid stack solution for RN/Flutter integration along with data degradation strategies.

Dada Group Technology
Dada Group Technology
Dada Group Technology
Upgrading the Event Logging Framework: Native Layer Design, Implementation, and Hybrid Stack Solutions

As business grows rapidly and cross‑platform integration accelerates, the existing event‑logging framework can no longer meet fast‑iteration needs, leading to issues such as log loss, Java‑level I/O performance bottlenecks, maintenance overhead, precise exposure requirements, and hybrid stack support for RN/Flutter.

Log loss problem : When logs are aggregated in memory and the app is killed or sent to background, data is lost. The previous solution wrote logs to local files and flushed them on onPause() , but frequent Java I/O caused GC pauses. The new approach moves log handling to a native layer to improve performance and unify Android and iOS logging.

Native layer design : A C‑level log library provides simple APIs for buffering, categorizing, and fragmenting logs (default fragment size 4 KB). It separates a Cache area (sandbox) from a Final area, ensuring that only when logs are moved to the Final area are they handed over to the upload component, and a flush operation forces Cache logs into Final.

Native layer implementation :

/** 初始化log文件系统 */
@param cache_dir_path 缓冲文件路径
@param output_dir_path 输出文件路径
@param max_file_size 最大文件大小 byte
@return 是否初始化成功 
int init_djmta_log_file_system(const char *cache_dir_path, const char *output_dir_path, int max_file_size);

/** 写日志 */
@param type 日志类型 (app / show)
@param log 日志内容
@param log_len 日志长度
@return 是否有待上传日志产生,有返1,无返0 
 d jmta_bool write_djmta_log(DJMTA_LOG_TYPE type, const char *log , long long log_len);

/** 强制清空缓存区到输出日志目录 */
@return 如果有输出日志,有返1,无返0 
 d jmta_bool flush_djmta_log(void);

/** 根据文件名返回log类型 */
@param log_file_name 文件名 
@return 日志类型(app / show) 
 DJMTA_LOG_TYPE judge_type_djmta_log(char *log_file_name);

/** 根据文件路径返回log内容 */
@return 字符串 (注意 用完之后 手动释放 返回char *) 
 char * fetch_djmta_log(const char *log_file_path);

Precise exposure challenges : Simple RecyclerView items can capture lifecycle events for exposure, but complex layouts require model slicing for fine‑grained rendering. For ScrollView and custom ViewGroups, the solution maps the whole view to a data‑structure graph and simulates RecyclerView’s cache mechanism, updating only top/bottom caches to reduce computation while maintaining accurate exposure.

Hybrid stack logging solution : With RN and Flutter embedded as Activities, page view (pv) and click events are generated at the root Activity level, causing inaccurate paths when internal navigation occurs. The hybrid stack introduces enterPv and exitPv methods exposed via a stack, with bridges/plugins for RN and Flutter, handling Intent clearTop, finish, and background‑kill recovery scenarios.

Data degradation strategy : The logging SDK is modularized; each business plugin routes data to a central interceptor that interfaces with the C layer for storage, retrieval, and upload. Dynamic updates allow hot‑fixes for crashes and other runtime issues.

mobile developmentPerformancecross‑platformloggingevent trackingNative Code
Dada Group Technology
Written by

Dada Group Technology

Sharing insights and experiences from Dada Group's R&D department on product refinement and technology advancement, connecting with fellow geeks to exchange ideas and grow together.

0 followers
Reader feedback

How this landed with the community

login 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.