Merge "logd: Worst Tag filter enabled for events buffer"

This commit is contained in:
Treehugger Robot 2016-07-16 00:23:40 +00:00 committed by Gerrit Code Review
commit c4be85fbba
5 changed files with 101 additions and 63 deletions

View file

@ -313,16 +313,16 @@ LogBufferElementCollection::iterator LogBuffer::erase(
LogBufferElement *element = *it; LogBufferElement *element = *it;
log_id_t id = element->getLogId(); log_id_t id = element->getLogId();
{ // start of scope for uid found iterator { // start of scope for found iterator
LogBufferIteratorMap::iterator found = int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) ?
mLastWorstUid[id].find(element->getUid()); element->getTag() : element->getUid();
if ((found != mLastWorstUid[id].end()) LogBufferIteratorMap::iterator found = mLastWorst[id].find(key);
&& (it == found->second)) { if ((found != mLastWorst[id].end()) && (it == found->second)) {
mLastWorstUid[id].erase(found); 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 // start of scope for pid found iterator
LogBufferPidIteratorMap::iterator found = LogBufferPidIteratorMap::iterator found =
mLastWorstPidOfSystem[id].find(element->getPid()); 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(); bool hasBlacklist = (id != LOG_ID_SECURITY) && mPrune.naughty();
while (!clearAll && (pruneRows > 0)) { while (!clearAll && (pruneRows > 0)) {
// recalculate the worst offender on every batched pass // 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 worst_sizes = 0;
size_t second_worst_sizes = 0; size_t second_worst_sizes = 0;
pid_t worstPid = 0; // POSIX guarantees PID != 0 pid_t worstPid = 0; // POSIX guarantees PID != 0
if (worstUidEnabledForLogid(id) && mPrune.worstUidEnabled()) { if (worstUidEnabledForLogid(id) && mPrune.worstUidEnabled()) {
{ // begin scope for UID sorted list // Calculate threshold as 12.5% of available storage
std::unique_ptr<const UidEntry *[]> sorted = stats.sort( size_t threshold = log_buffer_size(id) / 8;
AID_ROOT, (pid_t)0, 2, id);
if (sorted.get() && sorted[0] && sorted[1]) { if ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) {
worst_sizes = sorted[0]->getSizes(); stats.sortTags(AID_ROOT, (pid_t)0, 2, id).findWorst(
// Calculate threshold as 12.5% of available storage worst, worst_sizes, second_worst_sizes, threshold);
size_t threshold = log_buffer_size(id) / 8; } else {
if ((worst_sizes > threshold) stats.sort(AID_ROOT, (pid_t)0, 2, id).findWorst(
// Allow time horizon to extend roughly tenfold, assume worst, worst_sizes, second_worst_sizes, threshold);
// 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 ((worst == AID_SYSTEM) && mPrune.worstPidOfSystemEnabled()) { if ((worst == AID_SYSTEM) && mPrune.worstPidOfSystemEnabled()) {
// begin scope of PID sorted list stats.sortPids(worst, (pid_t)0, 2, id).findWorst(
std::unique_ptr<const PidEntry *[]> sorted = stats.sortPids( worstPid, worst_sizes, second_worst_sizes);
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();
} }
} }
} }
// skip if we have neither worst nor naughty filters // skip if we have neither worst nor naughty filters
if ((worst == (uid_t) -1) && !hasBlacklist) { if ((worst == -1) && !hasBlacklist) {
break; break;
} }
@ -597,10 +580,10 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
// - coalesce chatty tags // - coalesce chatty tags
// - check age-out of preserved logs // - check age-out of preserved logs
bool gc = pruneRows <= 1; bool gc = pruneRows <= 1;
if (!gc && (worst != (uid_t) -1)) { if (!gc && (worst != -1)) {
{ // begin scope for uid worst found iterator { // begin scope for worst found iterator
LogBufferIteratorMap::iterator found = mLastWorstUid[id].find(worst); LogBufferIteratorMap::iterator found = mLastWorst[id].find(worst);
if ((found != mLastWorstUid[id].end()) if ((found != mLastWorst[id].end())
&& (found->second != mLogElements.end())) { && (found->second != mLogElements.end())) {
leading = false; leading = false;
it = found->second; it = found->second;
@ -658,6 +641,10 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
continue; continue;
} }
int key = ((id == LOG_ID_EVENTS) || (id == LOG_ID_SECURITY)) ?
element->getTag() :
element->getUid();
if (hasBlacklist && mPrune.naughty(element)) { if (hasBlacklist && mPrune.naughty(element)) {
last.clear(element); last.clear(element);
it = erase(it); it = erase(it);
@ -670,7 +657,7 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
break; break;
} }
if (element->getUid() == worst) { if (key == worst) {
kick = true; kick = true;
if (worst_sizes < second_worst_sizes) { if (worst_sizes < second_worst_sizes) {
break; break;
@ -689,20 +676,19 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
last.add(element); last.add(element);
if (worstPid if (worstPid
&& ((!gc && (element->getPid() == worstPid)) && ((!gc && (element->getPid() == worstPid))
|| (mLastWorstPidOfSystem[id].find(element->getPid()) || (mLastWorstPidOfSystem[id].find(element->getPid())
== mLastWorstPidOfSystem[id].end()))) { == mLastWorstPidOfSystem[id].end()))) {
mLastWorstPidOfSystem[id][element->getUid()] = it; mLastWorstPidOfSystem[id][key] = it;
} }
if ((!gc && !worstPid && (element->getUid() == worst)) if ((!gc && !worstPid && (key == worst))
|| (mLastWorstUid[id].find(element->getUid()) || (mLastWorst[id].find(key) == mLastWorst[id].end())) {
== mLastWorstUid[id].end())) { mLastWorst[id][key] = it;
mLastWorstUid[id][element->getUid()] = it;
} }
++it; ++it;
continue; continue;
} }
if ((element->getUid() != worst) if ((key != worst)
|| (worstPid && (element->getPid() != worstPid))) { || (worstPid && (element->getPid() != worstPid))) {
leading = false; leading = false;
last.clear(element); 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].end()))) {
mLastWorstPidOfSystem[id][worstPid] = it; mLastWorstPidOfSystem[id][worstPid] = it;
} }
if ((!gc && !worstPid) || (mLastWorstUid[id].find(worst) if ((!gc && !worstPid) ||
== mLastWorstUid[id].end())) { (mLastWorst[id].find(worst) == mLastWorst[id].end())) {
mLastWorstUid[id][worst] = it; mLastWorst[id][worst] = it;
} }
++it; ++it;
} }

View file

@ -89,7 +89,7 @@ class LogBuffer {
typedef std::unordered_map<uid_t, typedef std::unordered_map<uid_t,
LogBufferElementCollection::iterator> LogBufferElementCollection::iterator>
LogBufferIteratorMap; LogBufferIteratorMap;
LogBufferIteratorMap mLastWorstUid[LOG_ID_MAX]; LogBufferIteratorMap mLastWorst[LOG_ID_MAX];
// watermark of any worst/chatty pid of system processing // watermark of any worst/chatty pid of system processing
typedef std::unordered_map<pid_t, typedef std::unordered_map<pid_t,
LogBufferElementCollection::iterator> LogBufferElementCollection::iterator>

View file

@ -152,6 +152,15 @@ void LogStatistics::drop(LogBufferElement *element) {
pidTable.drop(element->getPid(), element); pidTable.drop(element->getPid(), element);
tidTable.drop(element->getTid(), 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 // caller must own and free character string
@ -438,6 +447,10 @@ std::string TagEntry::format(const LogStatistics & /* stat */, log_id_t /* id */
getSizes()); getSizes());
std::string pruned = ""; std::string pruned = "";
size_t dropped = getDropped();
if (dropped) {
pruned = android::base::StringPrintf("%zu", dropped);
}
return formatLine(name, size, pruned); return formatLine(name, size, pruned);
} }

View file

@ -203,7 +203,7 @@ struct EntryBaseDropped : public EntryBase {
EntryBaseDropped():dropped(0) { } EntryBaseDropped():dropped(0) { }
EntryBaseDropped(LogBufferElement *element): EntryBaseDropped(LogBufferElement *element):
EntryBase(element), EntryBase(element),
dropped(element->getDropped()){ dropped(element->getDropped()) {
} }
size_t getDropped() const { return dropped; } 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; std::string format(const LogStatistics &stat, log_id_t id) const;
}; };
struct TagEntry : public EntryBase { struct TagEntry : public EntryBaseDropped {
const uint32_t tag; const uint32_t tag;
pid_t pid; pid_t pid;
uid_t uid; uid_t uid;
TagEntry(LogBufferElement *element): TagEntry(LogBufferElement *element):
EntryBase(element), EntryBaseDropped(element),
tag(element->getTag()), tag(element->getTag()),
pid(element->getPid()), pid(element->getPid()),
uid(element->getUid()) { uid(element->getUid()) {
@ -401,6 +401,43 @@ struct TagEntry : public EntryBase {
std::string format(const LogStatistics &stat, log_id_t id) const; 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 // Log Statistics
class LogStatistics { class LogStatistics {
friend UidEntry; friend UidEntry;
@ -451,13 +488,14 @@ public:
--mDroppedElements[log_id]; --mDroppedElements[log_id];
} }
std::unique_ptr<const UidEntry *[]> sort(uid_t uid, pid_t pid, LogFindWorst<UidEntry> sort(uid_t uid, pid_t pid, size_t len, log_id id) {
size_t len, log_id id) { return LogFindWorst<UidEntry>(uidTable[id].sort(uid, pid, len));
return uidTable[id].sort(uid, pid, len);
} }
std::unique_ptr<const PidEntry *[]> sortPids(uid_t uid, pid_t pid, LogFindWorst<PidEntry> sortPids(uid_t uid, pid_t pid, size_t len, log_id id) {
size_t len, log_id id) { return LogFindWorst<PidEntry>(pidSystemTable[id].sort(uid, pid, len));
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 // fast track current value by id only

View file

@ -56,7 +56,8 @@ bool clientHasLogCredentials(SocketClient *cli);
bool property_get_bool(const char *key, int def); bool property_get_bool(const char *key, int def);
static inline bool worstUidEnabledForLogid(log_id_t id) { 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)> template <int (*cmp)(const char *l, const char *r, const size_t s)>