diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp index e5f9b41ce..fa957332d 100644 --- a/logd/LogBuffer.cpp +++ b/logd/LogBuffer.cpp @@ -313,16 +313,16 @@ LogBufferElementCollection::iterator LogBuffer::erase( LogBufferElement *element = *it; log_id_t id = element->getLogId(); - { // start of scope for uid found iterator - LogBufferIteratorMap::iterator found = - mLastWorstUid[id].find(element->getUid()); - if ((found != mLastWorstUid[id].end()) - && (it == found->second)) { - mLastWorstUid[id].erase(found); + { // start of scope for found iterator + int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) ? + element->getTag() : element->getUid(); + LogBufferIteratorMap::iterator found = mLastWorst[id].find(key); + if ((found != mLastWorst[id].end()) && (it == found->second)) { + mLastWorst[id].erase(found); } } - if (element->getUid() == AID_SYSTEM) { + if ((id != LOG_ID_EVENTS) && (id != LOG_ID_SECURITY) && (element->getUid() == AID_SYSTEM)) { // start of scope for pid found iterator LogBufferPidIteratorMap::iterator found = mLastWorstPidOfSystem[id].find(element->getPid()); @@ -544,48 +544,31 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { bool hasBlacklist = (id != LOG_ID_SECURITY) && mPrune.naughty(); while (!clearAll && (pruneRows > 0)) { // recalculate the worst offender on every batched pass - uid_t worst = (uid_t) -1; + int worst = -1; // not valid for getUid() or getKey() size_t worst_sizes = 0; size_t second_worst_sizes = 0; pid_t worstPid = 0; // POSIX guarantees PID != 0 if (worstUidEnabledForLogid(id) && mPrune.worstUidEnabled()) { - { // begin scope for UID sorted list - std::unique_ptr sorted = stats.sort( - AID_ROOT, (pid_t)0, 2, id); + // Calculate threshold as 12.5% of available storage + size_t threshold = log_buffer_size(id) / 8; - if (sorted.get() && sorted[0] && sorted[1]) { - worst_sizes = sorted[0]->getSizes(); - // Calculate threshold as 12.5% of available storage - size_t threshold = log_buffer_size(id) / 8; - if ((worst_sizes > threshold) - // Allow time horizon to extend roughly tenfold, assume - // average entry length is 100 characters. - && (worst_sizes > (10 * sorted[0]->getDropped()))) { - worst = sorted[0]->getKey(); - second_worst_sizes = sorted[1]->getSizes(); - if (second_worst_sizes < threshold) { - second_worst_sizes = threshold; - } - } - } - } + if ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) { + stats.sortTags(AID_ROOT, (pid_t)0, 2, id).findWorst( + worst, worst_sizes, second_worst_sizes, threshold); + } else { + stats.sort(AID_ROOT, (pid_t)0, 2, id).findWorst( + worst, worst_sizes, second_worst_sizes, threshold); - if ((worst == AID_SYSTEM) && mPrune.worstPidOfSystemEnabled()) { - // begin scope of PID sorted list - std::unique_ptr sorted = stats.sortPids( - worst, (pid_t)0, 2, id); - if (sorted.get() && sorted[0] && sorted[1]) { - worstPid = sorted[0]->getKey(); - second_worst_sizes = worst_sizes - - sorted[0]->getSizes() - + sorted[1]->getSizes(); + if ((worst == AID_SYSTEM) && mPrune.worstPidOfSystemEnabled()) { + stats.sortPids(worst, (pid_t)0, 2, id).findWorst( + worstPid, worst_sizes, second_worst_sizes); } } } // skip if we have neither worst nor naughty filters - if ((worst == (uid_t) -1) && !hasBlacklist) { + if ((worst == -1) && !hasBlacklist) { break; } @@ -597,10 +580,10 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { // - coalesce chatty tags // - check age-out of preserved logs bool gc = pruneRows <= 1; - if (!gc && (worst != (uid_t) -1)) { - { // begin scope for uid worst found iterator - LogBufferIteratorMap::iterator found = mLastWorstUid[id].find(worst); - if ((found != mLastWorstUid[id].end()) + if (!gc && (worst != -1)) { + { // begin scope for worst found iterator + LogBufferIteratorMap::iterator found = mLastWorst[id].find(worst); + if ((found != mLastWorst[id].end()) && (found->second != mLogElements.end())) { leading = false; it = found->second; @@ -658,6 +641,10 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { continue; } + int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) ? + element->getTag() : + element->getUid(); + if (hasBlacklist && mPrune.naughty(element)) { last.clear(element); it = erase(it); @@ -670,7 +657,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { break; } - if (element->getUid() == worst) { + if (key == worst) { kick = true; if (worst_sizes < second_worst_sizes) { break; @@ -689,20 +676,19 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { last.add(element); if (worstPid && ((!gc && (element->getPid() == worstPid)) - || (mLastWorstPidOfSystem[id].find(element->getPid()) + || (mLastWorstPidOfSystem[id].find(element->getPid()) == mLastWorstPidOfSystem[id].end()))) { - mLastWorstPidOfSystem[id][element->getUid()] = it; + mLastWorstPidOfSystem[id][key] = it; } - if ((!gc && !worstPid && (element->getUid() == worst)) - || (mLastWorstUid[id].find(element->getUid()) - == mLastWorstUid[id].end())) { - mLastWorstUid[id][element->getUid()] = it; + if ((!gc && !worstPid && (key == worst)) + || (mLastWorst[id].find(key) == mLastWorst[id].end())) { + mLastWorst[id][key] = it; } ++it; continue; } - if ((element->getUid() != worst) + if ((key != worst) || (worstPid && (element->getPid() != worstPid))) { leading = false; last.clear(element); @@ -734,9 +720,9 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { == mLastWorstPidOfSystem[id].end()))) { mLastWorstPidOfSystem[id][worstPid] = it; } - if ((!gc && !worstPid) || (mLastWorstUid[id].find(worst) - == mLastWorstUid[id].end())) { - mLastWorstUid[id][worst] = it; + if ((!gc && !worstPid) || + (mLastWorst[id].find(worst) == mLastWorst[id].end())) { + mLastWorst[id][worst] = it; } ++it; } diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h index 7e9923606..b390a0c7a 100644 --- a/logd/LogBuffer.h +++ b/logd/LogBuffer.h @@ -89,7 +89,7 @@ class LogBuffer { typedef std::unordered_map LogBufferIteratorMap; - LogBufferIteratorMap mLastWorstUid[LOG_ID_MAX]; + LogBufferIteratorMap mLastWorst[LOG_ID_MAX]; // watermark of any worst/chatty pid of system processing typedef std::unordered_map diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp index a2d2aa525..86d33b26d 100644 --- a/logd/LogStatistics.cpp +++ b/logd/LogStatistics.cpp @@ -152,6 +152,15 @@ void LogStatistics::drop(LogBufferElement *element) { pidTable.drop(element->getPid(), element); tidTable.drop(element->getTid(), element); + + uint32_t tag = element->getTag(); + if (tag) { + if (log_id == LOG_ID_SECURITY) { + securityTagTable.drop(tag, element); + } else { + tagTable.drop(tag, element); + } + } } // caller must own and free character string @@ -438,6 +447,10 @@ std::string TagEntry::format(const LogStatistics & /* stat */, log_id_t /* id */ getSizes()); std::string pruned = ""; + size_t dropped = getDropped(); + if (dropped) { + pruned = android::base::StringPrintf("%zu", dropped); + } return formatLine(name, size, pruned); } diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h index 52f1d5b7b..71ad73aef 100644 --- a/logd/LogStatistics.h +++ b/logd/LogStatistics.h @@ -203,7 +203,7 @@ struct EntryBaseDropped : public EntryBase { EntryBaseDropped():dropped(0) { } EntryBaseDropped(LogBufferElement *element): EntryBase(element), - dropped(element->getDropped()){ + dropped(element->getDropped()) { } size_t getDropped() const { return dropped; } @@ -370,13 +370,13 @@ struct TidEntry : public EntryBaseDropped { std::string format(const LogStatistics &stat, log_id_t id) const; }; -struct TagEntry : public EntryBase { +struct TagEntry : public EntryBaseDropped { const uint32_t tag; pid_t pid; uid_t uid; TagEntry(LogBufferElement *element): - EntryBase(element), + EntryBaseDropped(element), tag(element->getTag()), pid(element->getPid()), uid(element->getUid()) { @@ -401,6 +401,43 @@ struct TagEntry : public EntryBase { std::string format(const LogStatistics &stat, log_id_t id) const; }; +template +class LogFindWorst { + std::unique_ptr sorted; + +public: + + LogFindWorst(std::unique_ptr &&sorted) : sorted(std::move(sorted)) { } + + void findWorst(int &worst, + size_t &worst_sizes, size_t &second_worst_sizes, + size_t threshold) { + if (sorted.get() && sorted[0] && sorted[1]) { + worst_sizes = sorted[0]->getSizes(); + if ((worst_sizes > threshold) + // Allow time horizon to extend roughly tenfold, assume + // average entry length is 100 characters. + && (worst_sizes > (10 * sorted[0]->getDropped()))) { + worst = sorted[0]->getKey(); + second_worst_sizes = sorted[1]->getSizes(); + if (second_worst_sizes < threshold) { + second_worst_sizes = threshold; + } + } + } + } + + void findWorst(int &worst, + size_t worst_sizes, size_t &second_worst_sizes) { + if (sorted.get() && sorted[0] && sorted[1]) { + worst = sorted[0]->getKey(); + second_worst_sizes = worst_sizes + - sorted[0]->getSizes() + + sorted[1]->getSizes(); + } + } +}; + // Log Statistics class LogStatistics { friend UidEntry; @@ -451,13 +488,14 @@ public: --mDroppedElements[log_id]; } - std::unique_ptr sort(uid_t uid, pid_t pid, - size_t len, log_id id) { - return uidTable[id].sort(uid, pid, len); + LogFindWorst sort(uid_t uid, pid_t pid, size_t len, log_id id) { + return LogFindWorst(uidTable[id].sort(uid, pid, len)); } - std::unique_ptr sortPids(uid_t uid, pid_t pid, - size_t len, log_id id) { - return pidSystemTable[id].sort(uid, pid, len); + LogFindWorst sortPids(uid_t uid, pid_t pid, size_t len, log_id id) { + return LogFindWorst(pidSystemTable[id].sort(uid, pid, len)); + } + LogFindWorst sortTags(uid_t uid, pid_t pid, size_t len, log_id) { + return LogFindWorst(tagTable.sort(uid, pid, len)); } // fast track current value by id only diff --git a/logd/LogUtils.h b/logd/LogUtils.h index aa4b6e1e3..fc66330a5 100644 --- a/logd/LogUtils.h +++ b/logd/LogUtils.h @@ -56,7 +56,8 @@ bool clientHasLogCredentials(SocketClient *cli); bool property_get_bool(const char *key, int def); static inline bool worstUidEnabledForLogid(log_id_t id) { - return (id == LOG_ID_MAIN) || (id == LOG_ID_SYSTEM) || (id == LOG_ID_RADIO); + return (id == LOG_ID_MAIN) || (id == LOG_ID_SYSTEM) || + (id == LOG_ID_RADIO) || (id == LOG_ID_EVENTS); } template