android12-release
| 命令 | 功能 |
|---|---|
| adb bugreport > bugreport.txt | bugreport 日志 |
| adb shell dmesg > dmesg.txt | dmesg 日志 |
| adb logcat -d -v time -b “main” > main.txt | main 日志 |
| adb logcat -d -v time -b “system” > system.txt | system日志 |
| adb logcat -d -v time -b “events” > events.txt | events 日志 |
| adb logcat -b crash | 输出crash日志 |
| … … | 等等 |
| adb logcat -h | 查看logcat命令帮助 |
Usage: logcat [options] [filterspecs]General options:-b, --buffer= Request alternate ring buffer(s):main system radio events crash default allAdditionally, 'kernel' for userdebug and eng builds, and'security' for Device Owner installations.Multiple -b parameters or comma separated list of buffers areallowed. Buffers are interleaved.Default -b main,system,crash,kernel.-L, --last Dump logs from prior to last reboot from pstore.-c, --clear Clear (flush) the entire log and exit.if -f is specified, clear the specified file and its related rotatedlog files instead.if -L is specified, clear pstore log instead.-d Dump the log and then exit (don't block).--pid= Only print logs from the given pid.--wrap Sleep for 2 hours or when buffer about to wrap whichevercomes first. Improves efficiency of polling by providingan about-to-wrap wakeup.Formatting:-v, --format= Sets log print format verb and adverbs, where is one of:brief help long process raw tag thread threadtime timeModifying adverbs can be added:color descriptive epoch monotonic printable uid usec UTC year zoneMultiple -v parameters or comma separated list of format and formatmodifiers are allowed.-D, --dividers Print dividers between each log buffer.-B, --binary Output the log in binary.Outfile files:-f, --file= Log to file instead of stdout.-r, --rotate-kbytes= Rotate log every kbytes. Requires -f option.-n, --rotate-count= Sets max number of rotated logs to , default 4.--id= If the signature for logging to file changes, then clear theassociated files and continue.Logd control:These options send a control message to the logd daemon on device, print its return message ifapplicable, then exit. They are incompatible with -L, as these attributes do not apply to pstore.-g, --buffer-size Get the size of the ring buffers within logd.-G, --buffer-size= Set size of a ring buffer in logd. May suffix with K or M.This can individually control each buffer's size with -b.-S, --statistics Output statistics.--pid can be used to provide pid specific stats.-p, --prune Print prune rules. Each rule is specified as UID, UID/PID or /PID. A'~' prefix indicates that elements matching the rule should be prunedwith higher priority otherwise they're pruned with lower priority. Allother pruning activity is oldest first. Special case ~! represents anautomatic pruning for the noisiest UID as determined by the currentstatistics. Special case ~1000/! represents pruning of the worst PIDwithin AID_SYSTEM when AID_SYSTEM is the noisiest UID.-P, --prune=' ...' Set prune rules, using same format as listed above. Must be quoted.Filtering:-s Set default filter to silent. Equivalent to filterspec '*:S'-e, --regex= Only print lines where the log message matches where isan ECMAScript regular expression.-m, --max-count= Quit after printing lines. This is meant to be paired with--regex, but will work on its own.--print This option is only applicable when --regex is set and only useful if--max-count is also provided.With --print, logcat will print all messages even if they do notmatch the regex. Logcat will quit after printing the max-count numberof lines that match the regex.-t Print only the most recent lines (implies -d).-t '
Android系统启动 查看 init 进程解析 rc 文件,其中解析 logd.rc,调用到logd/main.cpp主函数。
相关目录:
system/logging/logd/logd.rc
system/logging/logd/main.cpp

logd.rc文件:
service logd /system/bin/logdsocket logd stream 0666 logd logdsocket logdr seqpacket 0666 logd logdsocket logdw dgram+passcred 0222 logd logdfile /proc/kmsg rfile /dev/kmsg wuser logdgroup logd system package_info readproccapabilities SYSLOG AUDIT_CONTROLpriority 10writepid /dev/cpuset/system-background/tasksservice logd-reinit /system/bin/logd --reinitoneshotdisableduser logdgroup logdwritepid /dev/cpuset/system-background/tasks# Limit SELinux denial generation to 5/second
service logd-auditctl /system/bin/auditctl -r 5oneshotdisableduser logdgroup logdcapabilities AUDIT_CONTROLon fswrite /dev/event-log-tags "# content owned by logd
"chown logd logd /dev/event-log-tagschmod 0644 /dev/event-log-tagson property:sys.boot_completed=1start logd-auditctl
android::base::KernelLogger 调试logd内部的日志输出,这部分日志输出到kernel log中,通过dmesg获取/dev/kmsgro.logd.kernel 属性控制获取/proc/kmsg的FDchatty、serialized、simple模式(默认serialized),通过属性logd.buffer_type获取;LogBuffer 是负责保存所有日志条目的对象。int main(int argc, char* argv[]) {// We want EPIPE when a reader disconnects, not to terminate logd.signal(SIGPIPE, SIG_IGN);// logd is written under the assumption that the timezone is UTC.// If TZ is not set, persist.sys.timezone is looked up in some time utility// libc functions, including mktime. It confuses the logd time handling,// so here explicitly set TZ to UTC, which overrides the property.setenv("TZ", "UTC", 1);// issue reinit command. KISS argument parsing.if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) {return issueReinit();}android::base::InitLogging(argv, [](android::base::LogId log_id, android::base::LogSeverity severity,const char* tag, const char* file, unsigned int line, const char* message) {if (tag && strcmp(tag, "logd") != 0) {auto prefixed_message = android::base::StringPrintf("%s: %s", tag, message);android::base::KernelLogger(log_id, severity, "logd", file, line,prefixed_message.c_str());} else {android::base::KernelLogger(log_id, severity, "logd", file, line, message);}});static const char dev_kmsg[] = "/dev/kmsg";int fdDmesg = android_get_control_file(dev_kmsg);if (fdDmesg < 0) {fdDmesg = TEMP_FAILURE_RETRY(open(dev_kmsg, O_WRONLY | O_CLOEXEC));}int fdPmesg = -1;bool klogd = GetBoolPropertyEngSvelteDefault("ro.logd.kernel");if (klogd) {SetProperty("ro.logd.kernel", "true");static const char proc_kmsg[] = "/proc/kmsg";fdPmesg = android_get_control_file(proc_kmsg);if (fdPmesg < 0) {fdPmesg = TEMP_FAILURE_RETRY(open(proc_kmsg, O_RDONLY | O_NDELAY | O_CLOEXEC));}if (fdPmesg < 0) PLOG(ERROR) << "Failed to open " << proc_kmsg;}bool auditd = GetBoolProperty("ro.logd.auditd", true);DropPrivs(klogd, auditd);// A cache of event log tagsLogTags log_tags;// Pruning configuration.PruneList prune_list;std::string buffer_type = GetProperty("logd.buffer_type", "serialized");// Partial (required for chatty) or full logging statistics.LogStatistics log_statistics(GetBoolPropertyEngSvelteDefault("logd.statistics"),buffer_type == "serialized");// Serves the purpose of managing the last logs times read on a socket connection, and as a// reader lock on a range of log entries.LogReaderList reader_list;// LogBuffer is the object which is responsible for holding all log entries.LogBuffer* log_buffer = nullptr;if (buffer_type == "chatty") {log_buffer = new ChattyLogBuffer(&reader_list, &log_tags, &prune_list, &log_statistics);} else if (buffer_type == "serialized") {log_buffer = new SerializedLogBuffer(&reader_list, &log_tags, &log_statistics);} else if (buffer_type == "simple") {log_buffer = new SimpleLogBuffer(&reader_list, &log_tags, &log_statistics);} else {LOG(FATAL) << "buffer_type must be one of 'chatty', 'serialized', or 'simple'";}// LogReader listens on /dev/socket/logdr. When a client// connects, log entries in the LogBuffer are written to the client.LogReader* reader = new LogReader(log_buffer, &reader_list);if (reader->startListener()) {return EXIT_FAILURE;}// LogListener listens on /dev/socket/logdw for client// initiated log messages. New log entries are added to LogBuffer// and LogReader is notified to send updates to connected clients.LogListener* swl = new LogListener(log_buffer);if (!swl->StartListener()) {return EXIT_FAILURE;}// Command listener listens on /dev/socket/logd for incoming logd// administrative commands.CommandListener* cl = new CommandListener(log_buffer, &log_tags, &prune_list, &log_statistics);if (cl->startListener()) {return EXIT_FAILURE;}// LogAudit listens on NETLINK_AUDIT socket for selinux// initiated log messages. New log entries are added to LogBuffer// and LogReader is notified to send updates to connected clients.LogAudit* al = nullptr;if (auditd) {int dmesg_fd = GetBoolProperty("ro.logd.auditd.dmesg", true) ? fdDmesg : -1;al = new LogAudit(log_buffer, dmesg_fd, &log_statistics);}LogKlog* kl = nullptr;if (klogd) {kl = new LogKlog(log_buffer, fdDmesg, fdPmesg, al != nullptr, &log_statistics);}readDmesg(al, kl);// failure is an option ... messages are in dmesg (required by standard)if (kl && kl->startListener()) {delete kl;}if (al && al->startListener()) {delete al;}TEMP_FAILURE_RETRY(pause());return EXIT_SUCCESS;
}
1、persist.logd.size.[buffer_name]; 比如buffer_name为main、system、events、crash;
2、ro.logd.size.[buffer_name]
3、persist.logd.size 开发模式中可以设置大小
4、ro.logd.size
5、kLogBufferMinSize = 64 * 1024 默认64k
system/logging/logd/SerializedLogBuffer.cpp

system/logging/logd/SimpleLogBuffer.cpp

system/logging/logd/ChattyLogBuffer.cpp

system/logging/logd/LogBuffer.h
system/logging/logd/LogSize.cpp

system/logging/liblog/logger_name.cpp
