Loading logd/LogBuffer.cpp +39 −53 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading @@ -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<const UidEntry *[]> sorted = stats.sort( AID_ROOT, (pid_t)0, 2, id); 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<const PidEntry *[]> 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(); 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; } Loading @@ -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; Loading Loading @@ -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); Loading @@ -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; Loading @@ -691,18 +678,17 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { && ((!gc && (element->getPid() == worstPid)) || (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); Loading Loading @@ -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; } Loading logd/LogBuffer.h +1 −1 Original line number Diff line number Diff line Loading @@ -89,7 +89,7 @@ class LogBuffer { typedef std::unordered_map<uid_t, LogBufferElementCollection::iterator> LogBufferIteratorMap; LogBufferIteratorMap mLastWorstUid[LOG_ID_MAX]; LogBufferIteratorMap mLastWorst[LOG_ID_MAX]; // watermark of any worst/chatty pid of system processing typedef std::unordered_map<pid_t, LogBufferElementCollection::iterator> Loading logd/LogStatistics.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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); } Loading logd/LogStatistics.h +47 −9 Original line number Diff line number Diff line Loading @@ -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()) { Loading @@ -401,6 +401,43 @@ struct TagEntry : public EntryBase { std::string format(const LogStatistics &stat, log_id_t id) const; }; template <typename TEntry> class LogFindWorst { std::unique_ptr<const TEntry *[]> sorted; public: LogFindWorst(std::unique_ptr<const TEntry *[]> &&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; Loading Loading @@ -451,13 +488,14 @@ public: --mDroppedElements[log_id]; } std::unique_ptr<const UidEntry *[]> sort(uid_t uid, pid_t pid, size_t len, log_id id) { return uidTable[id].sort(uid, pid, len); LogFindWorst<UidEntry> sort(uid_t uid, pid_t pid, size_t len, log_id id) { return LogFindWorst<UidEntry>(uidTable[id].sort(uid, pid, len)); } LogFindWorst<PidEntry> sortPids(uid_t uid, pid_t pid, size_t len, log_id id) { return LogFindWorst<PidEntry>(pidSystemTable[id].sort(uid, pid, len)); } std::unique_ptr<const PidEntry *[]> sortPids(uid_t uid, pid_t pid, size_t len, log_id id) { return pidSystemTable[id].sort(uid, pid, len); LogFindWorst<TagEntry> sortTags(uid_t uid, pid_t pid, size_t len, log_id) { return LogFindWorst<TagEntry>(tagTable.sort(uid, pid, len)); } // fast track current value by id only Loading logd/LogUtils.h +2 −1 Original line number Diff line number Diff line Loading @@ -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 <int (*cmp)(const char *l, const char *r, const size_t s)> Loading Loading
logd/LogBuffer.cpp +39 −53 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading @@ -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<const UidEntry *[]> sorted = stats.sort( AID_ROOT, (pid_t)0, 2, id); 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<const PidEntry *[]> 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(); 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; } Loading @@ -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; Loading Loading @@ -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); Loading @@ -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; Loading @@ -691,18 +678,17 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { && ((!gc && (element->getPid() == worstPid)) || (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); Loading Loading @@ -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; } Loading
logd/LogBuffer.h +1 −1 Original line number Diff line number Diff line Loading @@ -89,7 +89,7 @@ class LogBuffer { typedef std::unordered_map<uid_t, LogBufferElementCollection::iterator> LogBufferIteratorMap; LogBufferIteratorMap mLastWorstUid[LOG_ID_MAX]; LogBufferIteratorMap mLastWorst[LOG_ID_MAX]; // watermark of any worst/chatty pid of system processing typedef std::unordered_map<pid_t, LogBufferElementCollection::iterator> Loading
logd/LogStatistics.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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); } Loading
logd/LogStatistics.h +47 −9 Original line number Diff line number Diff line Loading @@ -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()) { Loading @@ -401,6 +401,43 @@ struct TagEntry : public EntryBase { std::string format(const LogStatistics &stat, log_id_t id) const; }; template <typename TEntry> class LogFindWorst { std::unique_ptr<const TEntry *[]> sorted; public: LogFindWorst(std::unique_ptr<const TEntry *[]> &&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; Loading Loading @@ -451,13 +488,14 @@ public: --mDroppedElements[log_id]; } std::unique_ptr<const UidEntry *[]> sort(uid_t uid, pid_t pid, size_t len, log_id id) { return uidTable[id].sort(uid, pid, len); LogFindWorst<UidEntry> sort(uid_t uid, pid_t pid, size_t len, log_id id) { return LogFindWorst<UidEntry>(uidTable[id].sort(uid, pid, len)); } LogFindWorst<PidEntry> sortPids(uid_t uid, pid_t pid, size_t len, log_id id) { return LogFindWorst<PidEntry>(pidSystemTable[id].sort(uid, pid, len)); } std::unique_ptr<const PidEntry *[]> sortPids(uid_t uid, pid_t pid, size_t len, log_id id) { return pidSystemTable[id].sort(uid, pid, len); LogFindWorst<TagEntry> sortTags(uid_t uid, pid_t pid, size_t len, log_id) { return LogFindWorst<TagEntry>(tagTable.sort(uid, pid, len)); } // fast track current value by id only Loading
logd/LogUtils.h +2 −1 Original line number Diff line number Diff line Loading @@ -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 <int (*cmp)(const char *l, const char *r, const size_t s)> Loading