From 8e72c5384b288bc11af60e12686a44e502633e3d Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Wed, 26 Mar 2014 10:46:39 -0700 Subject: logd: Statistics: Add up to 10 chattiest clients - embellish pid name - >1% of the logs - fix PID gone detection (EPERM) - some ? : cleanup Change-Id: Iba3b306e1fee43e53931165819a398693910514b --- logd/LogStatistics.cpp | 115 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 108 insertions(+), 7 deletions(-) (limited to 'logd/LogStatistics.cpp') diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp index fc6e6b2..5146030 100644 --- a/logd/LogStatistics.cpp +++ b/logd/LogStatistics.cpp @@ -63,7 +63,7 @@ void PidStatistics::add(unsigned short size) { bool PidStatistics::subtract(unsigned short size) { mSizes -= size; --mElements; - return mElements == 0 && kill(pid, 0); + return (mElements == 0) && kill(pid, 0) && (errno != EPERM); } void PidStatistics::addTotal(size_t size, size_t element) { @@ -508,6 +508,107 @@ void LogStatistics::format(char **buf, spaces += spaces_total; } + // Construct list of worst spammers by Pid + static const unsigned char num_spammers = 10; + bool header = false; + + log_id_for_each(i) { + if (!(logMask & (1 << i))) { + continue; + } + + PidStatisticsCollection pids; + pids.clear(); + + LidStatistics &l = id(i); + UidStatisticsCollection::iterator iu; + for (iu = l.begin(); iu != l.end(); ++iu) { + UidStatistics &u = *(*iu); + PidStatisticsCollection::iterator ip; + for (ip = u.begin(); ip != u.end(); ++ip) { + PidStatistics *p = (*ip); + if (p->getPid() == p->gone) { + break; + } + + size_t mySizes = p->sizes(); + + PidStatisticsCollection::iterator q; + unsigned char num = 0; + for (q = pids.begin(); q != pids.end(); ++q) { + if (mySizes > (*q)->sizes()) { + pids.insert(q, p); + break; + } + // do we need to traverse deeper in the list? + if (++num > num_spammers) { + break; + } + } + if (q == pids.end()) { + pids.push_back(p); + } + } + } + + size_t threshold = sizes(i); + if (threshold < 65536) { + threshold = 65536; + } + threshold /= 100; + + PidStatisticsCollection::iterator pt = pids.begin(); + + for(int line = 0; + (pt != pids.end()) && (line < num_spammers); + ++line, pt = pids.erase(pt)) { + PidStatistics *p = *pt; + + size_t sizes = p->sizes(); + if (sizes < threshold) { + break; + } + + char *name = p->getName(); + pid_t pid = p->getPid(); + if (!name || !*name) { + name = pidToName(pid); + if (name) { + if (*name) { + p->setName(name); + } else { + free(name); + name = NULL; + } + } + } + + if (!header) { + string.appendFormat("\n\nChattiest clients:\n" + "log id %-*s PID[?] name", + spaces_total, "size/total"); + header = true; + } + + size_t sizesTotal = p->sizesTotal(); + + android::String8 sz(""); + sz.appendFormat((sizes != sizesTotal) ? "%zu/%zu" : "%zu", + sizes, sizesTotal); + + android::String8 pd(""); + pd.appendFormat("%u%c", pid, + (kill(pid, 0) && (errno != EPERM)) ? '?' : ' '); + + string.appendFormat("\n%-7s%-*s %-7s%s", + line ? "" : android_log_id_to_name(i), + spaces_total, sz.string(), pd.string(), + name ? name : ""); + } + + pids.clear(); + } + if (dgram_qlen_statistics) { const unsigned short spaces_time = 6; const unsigned long long max_seconds = 100000; @@ -562,7 +663,7 @@ void LogStatistics::format(char **buf, continue; } - bool header = false; + header = false; bool first = true; UidStatisticsCollection::iterator ut; @@ -610,7 +711,7 @@ void LogStatistics::format(char **buf, : "%d/%d") : "%d", u, p); - string.appendFormat((first) ? "\n%-12s" : "%-12s", + string.appendFormat(first ? "\n%-12s" : "%-12s", intermediate.string()); intermediate.clear(); @@ -659,7 +760,7 @@ void LogStatistics::format(char **buf, continue; } els = pp->elements(); - bool gone = kill(p, 0); + bool gone = kill(p, 0) && (errno != EPERM); if (gone && (els == 0)) { // ToDo: garbage collection: move this statistical bucket // from its current UID/PID to UID/? (races and @@ -676,8 +777,8 @@ void LogStatistics::format(char **buf, } spaces = 0; - intermediate = string.format((gone) ? "%d/%d?" : "%d/%d", u, p); - string.appendFormat((first) ? "\n%-12s" : "%-12s", + intermediate = string.format(gone ? "%d/%d?" : "%d/%d", u, p); + string.appendFormat(first ? "\n%-12s" : "%-12s", intermediate.string()); intermediate.clear(); @@ -711,7 +812,7 @@ void LogStatistics::format(char **buf, } intermediate = string.format("%d/?", u); - string.appendFormat((first) ? "\n%-12s" : "%-12s", + string.appendFormat(first ? "\n%-12s" : "%-12s", intermediate.string()); intermediate.clear(); -- cgit v1.1