logd: add Chattiest LOG_TAG statistics
Report global LOG_TAG usage.
Test: gTest liblog-unit-tests, logd-unit-tests & logcat-unit-tests
Test: manual: inspect logcat -S results around 'Chattiest TAGs'
Bug: 37254265
Change-Id: I32473a1d9131c87e4fb7841d5cc0ea9cc14c63cd
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index 0b6b28c..594bd0d 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -32,6 +32,7 @@
static const uint64_t monthSec = 31 * 24 * hourSec;
size_t LogStatistics::SizesTotal;
+size_t TagNameEntry::droppedElsewhere;
LogStatistics::LogStatistics() : enable(false) {
log_time now(CLOCK_REALTIME);
@@ -152,6 +153,8 @@
tagTable.add(tag, element);
}
}
+
+ tagNameTable.add(TagNameEntry(element).getKey(), element);
}
void LogStatistics::subtract(LogBufferElement* element) {
@@ -191,6 +194,8 @@
tagTable.subtract(tag, element);
}
}
+
+ tagNameTable.subtract(TagNameEntry(element).getKey(), element);
}
// Atomically set an entry to drop
@@ -225,6 +230,8 @@
tagTable.drop(tag, element);
}
}
+
+ tagNameTable.drop(TagNameEntry(element).getKey(), element);
}
// caller must own and free character string
@@ -505,6 +512,71 @@
return formatLine(name, size, pruned);
}
+std::string TagNameEntry::formatHeader(const std::string& name,
+ log_id_t /* id */) const {
+ return formatLine(name, std::string("Size"), std::string("Prune")) +
+ formatLine(std::string(" TID/PID/UID LOG_TAG NAME"),
+ std::string("BYTES"), std::string("NUM"));
+}
+
+std::string TagNameEntry::format(const LogStatistics& /* stat */,
+ log_id_t /* id */) const {
+ std::string name;
+ pid_t tid = getTid();
+ pid_t pid = getPid();
+ std::string pidstr;
+ if (pid != (pid_t)-1) {
+ pidstr = android::base::StringPrintf("%u", pid);
+ if ((tid != (pid_t)-1) && (tid != pid)) pidstr = "/" + pidstr;
+ }
+ int len = 9 - pidstr.length();
+ if (len < 0) len = 0;
+ if ((tid == (pid_t)-1) || (tid == pid)) {
+ name = android::base::StringPrintf("%*s", len, "");
+ } else {
+ name = android::base::StringPrintf("%*u", len, tid);
+ }
+ name += pidstr;
+ uid_t uid = getUid();
+ if (uid != (uid_t)-1) {
+ name += android::base::StringPrintf("/%u", uid);
+ }
+
+ std::string size = android::base::StringPrintf("%zu", getSizes());
+
+ const char* nameTmp = getName();
+ if (nameTmp) {
+ size_t lenSpace = std::max(16 - name.length(), (size_t)1);
+ size_t len = EntryBaseConstants::total_len -
+ EntryBaseConstants::pruned_len - size.length() -
+ name.length() - lenSpace - 2;
+ size_t lenNameTmp = strlen(nameTmp);
+ while ((len < lenNameTmp) && (lenSpace > 1)) {
+ ++len;
+ --lenSpace;
+ }
+ name += android::base::StringPrintf("%*s", (int)lenSpace, "");
+ if (len < lenNameTmp) {
+ name += "...";
+ nameTmp += lenNameTmp - std::max(len - 3, (size_t)1);
+ }
+ name += nameTmp;
+ }
+
+ std::string pruned = "";
+
+ // Because of TagNameEntry::droppedElsewhere, dropped count can get
+ // modified for "chatty" tags. Since the size is always zero this
+ // modification is a "can not happen".
+ TagNameEntry& me = const_cast<TagNameEntry&>(*this);
+ size_t dropped = me.getDropped();
+ if (dropped) {
+ pruned = android::base::StringPrintf("%zu", dropped);
+ }
+
+ return formatLine(name, size, pruned);
+}
+
static std::string formatMsec(uint64_t val) {
static const unsigned subsecDigits = 3;
static const uint64_t sec = MS_PER_SEC;
@@ -725,6 +797,13 @@
output += tidTable.format(*this, uid, pid, name);
}
+ if (enable) {
+ name = "Chattiest TAGs";
+ if (pid) name += android::base::StringPrintf(" for PID %d", pid);
+ name += ":";
+ output += tagNameTable.format(*this, uid, pid, name);
+ }
+
if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
name = "Chattiest events log buffer TAGs";
if (pid) name += android::base::StringPrintf(" for PID %d", pid);