Interpreting the implementation of the android Log Mechanism: (5) obtain the log application logcat
Tian haili @ csdn
2011/07/27
The Log Mechanism provided by Android runs through Java, JNI, local C/C ++ implementation, Linux kernel driver, and Other Android layers, and is simple and clear, it is a pretty good case. This series of articles explains the internal implementation mechanism of the log mechanism. This article is the fifth article in this series. It explains how the application logcat uses the open ()/select () /read () to obtain log information.
Once upon a time, I knew that logs were written to the driver node. How can I obtain and present these logs? In Android, an application called logcat is used to obtain log information. Logcat not only obtains logs from the device node, but also provides many options for users to filter and control the output format. This article only explains how to obtain the log part and how to use logcat. For details, refer to the logcat command in Android.
Logcat is implemented in the file system/CORE/logcat. cpp.
According to the implementation of the logger device driver, log reading is a blocking operation, that is, data is available and data is read; otherwise, the read operation is blocked, the corresponding read process will also be suspended. Next, let's take a look at how to implement read in the application logcat. This may require continuous integration with write operations and driver implementations.
Before proceeding to the specific implementation, Let's first look at the important struct log_device_t defined in logcat. Important members will be explained later.
1. Open a device Node
The detailed explanation of the android logcat Command's command parameter-B <buffer> knows that logcat can be used to specify the buffer (main/Radio/event) to operate on. The location where the B parameter of logcat is parsed is to create an above structure variable through the passed parameter (main/Radio/event), which is linked through log_device_t.next.
if (devices) { dev = devices; while (dev->next) { dev = dev->next; } dev->next = new log_device_t(buf, binary, optarg[0]); } else { devices = new log_device_t(buf, binary, optarg[0]); }
The parameters are retained during instance creation for subsequent operations.
<Buf>It is a combination of log_file_dir and optarg (-B parameter) ("/dev/log/main ", "/dev/log/event" or "/dev/log/Radio"), which is stored in device: char *;
<Binary>Retained in binary: bool;
<Optarg [0]>It is the first character of the-B parameter and is saved in label: Char.
Okay, the following parameters are available when the device node is Enabled:
Dev-> FD = open (Dev-> device, mode );
Dev-> DeviceThe-B parameter may be "/dev/log/main", "/dev/log/event", or "/dev/log/Radio ";
ModeThe default value is o_rdonly. O_wronly is enabled only when the-C parameter is used to clear logs when logcat is running.
The file open operator is stored in the log_device_tFDDomain used for subsequent operations.
All Log retrieval operations are implemented in readloglines (log_device_t * devices.
Because logcat may operate on multiple buffers at the same time, and read () will block the reading process and read from other buffers will not be available, so select () is used here () to determine the readable buffer.
Ii. Select the readable Buffer
Logcat sets all the buffer file operators in log_device_tDev-> FDIn readset [line #7]Select<Readfds: fd_set *> in () to obtain the readable buffer. In this way, when any buffer has log data, select () will return. Of course, the influence of other signal is also ignored during the waiting process. The Code is as follows:
fd_set readset; do { timeval timeout = { 0, 5000 /* 5ms */ }; // If we oversleep it's ok, i.e. ignore EINTR. FD_ZERO(&readset); for (dev=devices; dev; dev = dev->next) { FD_SET(dev->fd, &readset); } result = select(max + 1, &readset, NULL, NULL, sleep ? NULL : &timeout); } while (result == -1 && errno == EINTR);
Iii. Log read Operations
After the select () Statement is returned, it cyclically determines whether Dev-> FD is set in readset (fd_isset) [line #3] to determine which log buffer has data.
if (result >= 0) { for (dev=devices; dev; dev = dev->next) { if (FD_ISSET(dev->fd, &readset)) { queued_entry_t* entry = new queued_entry_t(); /* NOTE: driver guarantees we read exactly one full entry */ ret = read(dev->fd, entry->buf, LOGGER_ENTRY_MAX_LEN); //…
Read the log buffer file operator Dev-> FD for [line #6] with data through read () to get the new log.
The application logcat has obtained the log information, and then the data processing can be done here, filtering, writing files, formatting input, and other operations. For details about the logcat command parameters, see the logcat command in Android.
[This series of articles]
Interpreting the implementation of the android Log Mechanism: (1) implementation architecture of log
Interpret the implementation architecture of the log mechanism.
Interpreting the implementation of the android Log Mechanism: (2) Java domain output log
Explain how the android Java program outputs log information to the log system.
Interpreting the implementation of the android Log Mechanism: (3) Writing Device Files in JNI and native Domains
Interpret the JNI Implementation of Android. util. log and how to operate the device file to write log information in the local implementation of C/C ++.
Interpreting the implementation of the android Log Mechanism: (4) Log Device-driven Logger
Interpret the implementation of the device driver logger in the Linux kernel. Logger is a misc Driver written by Android for Linux. It uses cyclic queues to implement readers/writers. Logger is the core of the implementation of the entire log mechanism.
Interpreting the implementation of the android Log Mechanism: (5) Obtaining the log program logcat
Explains how the application logcat obtains log information through open ()/select ()/read () of the device file.
Interpreting the implementation of the android Log Mechanism: (6) using log in the C/C ++ domain
This article explains how to use the Log Mechanism in the C/C ++ program of Android to record log information.