Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a06694a authored by Mark Salyzyn's avatar Mark Salyzyn
Browse files

logd: Worst Tag filter enabled for events buffer

- Add drop logistics to TagTable
- replace uid references to a key reference since it
  is an UID for most buffers, but a TAG for the
  events and security buffer
- template the find worst entry mechanics into LogFindWorst class

Bug: 30118730
Change-Id: Ibea4be2c50d6ff4b39039e371365fed2453f17a2
parent 47684ca5
Loading
Loading
Loading
Loading
+39 −53
Original line number Diff line number Diff line
@@ -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);

                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;
        }

@@ -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;
@@ -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);
@@ -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;
                }
+1 −1
Original line number Diff line number Diff line
@@ -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>
+13 −0
Original line number Diff line number Diff line
@@ -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);
}
+47 −9
Original line number Diff line number Diff line
@@ -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));
    }
    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
+2 −1
Original line number Diff line number Diff line
@@ -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)>