Merge "logd: Worst Tag filter enabled for events buffer"
This commit is contained in:
commit
c4be85fbba
5 changed files with 101 additions and 63 deletions
|
@ -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<const UidEntry *[]> 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<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();
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 <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;
|
||||
|
@ -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));
|
||||
}
|
||||
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<PidEntry> sortPids(uid_t uid, pid_t pid, size_t len, log_id id) {
|
||||
return LogFindWorst<PidEntry>(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
|
||||
|
|
|
@ -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…
Reference in a new issue