Android Logging System Analysis: Architecture, Implementation, and Log Loss Cases
The article dissects Android’s logging system, detailing Java, native, and kernel interfaces, the liblog and logd daemon architecture, logcat usage, common log‑loss scenarios such as socket failures and buffer overflows, and the significant CPU, memory, I/O, and power resources the system consumes.
This article provides a comprehensive analysis of the Android logging system, covering the complete process of log writing and reading, framework design, and source code analysis.
1. Log Interfaces
The logging interfaces are divided into three layers: Java layer, native layer, and kernel layer.
1.1 Java Layer Interface
Log levels are VERBOSE, DEBUG, INFO, WARN, ERROR, ASSERT in ascending order. Five buffer types are defined: main, radio, events, system, and crash. Each buffer serves different purposes - main buffer is the only one available to applications, radio handles telephony messages, events is for binary system events, system stores system-level logs, and crash stores crash information.
1.2 Native Layer Interface
The native logging interface is encapsulated in liblog.so library. It uses socket communication to write logs to logd's buffer. The interface is accessed through ALOGX macros:
#define ALOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG__TAG, __VA_ARGS__)
#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG , LOG_TAG, __VA_ARGS__)
#define ALOGI(...) __android_log_print(ANDROID_LOG_INFO , LOG_TAG, __VA_ARGS__)
#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN , LOG_TAG, __VA_ARGS__)
#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR , LOG_TAG, __VA_ARGS__)
1.3 Kernel Layer Interface
The kernel uses printk interface with levels: KERN_EMERG, KERN_ALERT, KERN_CRIT, KERN_ERR, KERN_WARNING, KERN_NOTICE, KERN_INFO, KERN_DEBUG. Logs are output to /proc/kmsg node.
2. logd Daemon
logd is a native service that manages structured ring buffers. It creates four main components: LogBuffer, LogReader, LogListener, and CommandListener. Three sockets are created: /dev/socket/logd, /dev/socket/logdr, and /dev/socket/logdw.
The log flow: Java layer → JNI → native layer (liblog) → socket communication → logd buffer → logcat reads from logd
3. logcat Command
Common usage: logcat -b main -b system -b crash -r 1024 -n 5 -f android.log -v threadtime
4. Typical Log Loss Cases
Common causes of log loss include: (1) liblog socket transmission failure, (2) log reading speed slower than writing speed causing buffer overflow, (3) buffer size exceeded leading to 10% log trimming, (4) file storage issues preventing log persistence, (5) low memory causing log process termination.
5. Resource Consumption
Logging consumes significant resources including: IPC overhead via socket, RAM for buffer maintenance, CPU for pruneLogs operations, I/O for log persistence, and power consumption due to increased logd CPU load.
OPPO Kernel Craftsman
Sharing Linux kernel-related cutting-edge technology, technical articles, technical news, and curated tutorials
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.