logd: remove LogFindWorst
LogStatistics relies on LogBuffer's lock for thread safety, but that will be cleaned up in future CLs. It won't be possible to return a 'LogFindWorst' object that references internal LogStatistics pointers in a thread safe way, so we remove this and provide a more simple interface. This also removes unnecessary allocations; std::array of 2 or 32 entries is small enough to allocate on the stack. Test: logging unit tests Change-Id: I38bfcba5b08c640ffd3af5c078bc716688f6edf8
This commit is contained in:
parent
6153b71aea
commit
b6b78e9bb4
|
@ -663,19 +663,14 @@ bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
|
|||
// Calculate threshold as 12.5% of available storage
|
||||
size_t threshold = log_buffer_size(id) / 8;
|
||||
|
||||
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);
|
||||
if (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) {
|
||||
stats.WorstTwoTags(threshold, &worst, &worst_sizes, &second_worst_sizes);
|
||||
// per-pid filter for AID_SYSTEM sources is too complex
|
||||
} else {
|
||||
stats.sort(AID_ROOT, (pid_t)0, 2, id)
|
||||
.findWorst(worst, worst_sizes, second_worst_sizes,
|
||||
threshold);
|
||||
stats.WorstTwoUids(id, threshold, &worst, &worst_sizes, &second_worst_sizes);
|
||||
|
||||
if ((worst == AID_SYSTEM) && prune_->worstPidOfSystemEnabled()) {
|
||||
stats.sortPids(worst, (pid_t)0, 2, id)
|
||||
.findWorst(worstPid, worst_sizes, second_worst_sizes);
|
||||
if (worst == AID_SYSTEM && prune_->worstPidOfSystemEnabled()) {
|
||||
stats.WorstTwoSystemPids(id, worst_sizes, &worstPid, &second_worst_sizes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -297,6 +297,49 @@ const char* LogStatistics::uidToName(uid_t uid) const {
|
|||
return name;
|
||||
}
|
||||
|
||||
template <typename TKey, typename TEntry>
|
||||
void LogStatistics::WorstTwoWithThreshold(const LogHashtable<TKey, TEntry>& table, size_t threshold,
|
||||
int* worst, size_t* worst_sizes,
|
||||
size_t* second_worst_sizes) {
|
||||
std::array<const TEntry*, 2> max_entries;
|
||||
table.MaxEntries(AID_ROOT, 0, &max_entries);
|
||||
if (max_entries[0] == nullptr || max_entries[1] == nullptr) {
|
||||
return;
|
||||
}
|
||||
*worst_sizes = max_entries[0]->getSizes();
|
||||
// b/24782000: Allow time horizon to extend roughly tenfold, assume average entry length is
|
||||
// 100 characters.
|
||||
if (*worst_sizes > threshold && *worst_sizes > (10 * max_entries[0]->getDropped())) {
|
||||
*worst = max_entries[0]->getKey();
|
||||
*second_worst_sizes = max_entries[1]->getSizes();
|
||||
if (*second_worst_sizes < threshold) {
|
||||
*second_worst_sizes = threshold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LogStatistics::WorstTwoUids(log_id id, size_t threshold, int* worst, size_t* worst_sizes,
|
||||
size_t* second_worst_sizes) {
|
||||
WorstTwoWithThreshold(uidTable[id], threshold, worst, worst_sizes, second_worst_sizes);
|
||||
}
|
||||
|
||||
void LogStatistics::WorstTwoTags(size_t threshold, int* worst, size_t* worst_sizes,
|
||||
size_t* second_worst_sizes) {
|
||||
WorstTwoWithThreshold(tagTable, threshold, worst, worst_sizes, second_worst_sizes);
|
||||
}
|
||||
|
||||
void LogStatistics::WorstTwoSystemPids(log_id id, size_t worst_uid_sizes, int* worst,
|
||||
size_t* second_worst_sizes) {
|
||||
std::array<const PidEntry*, 2> max_entries;
|
||||
pidSystemTable[id].MaxEntries(AID_SYSTEM, 0, &max_entries);
|
||||
if (max_entries[0] == nullptr || max_entries[1] == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
*worst = max_entries[0]->getKey();
|
||||
*second_worst_sizes = worst_uid_sizes - max_entries[0]->getSizes() + max_entries[1]->getSizes();
|
||||
}
|
||||
|
||||
std::string UidEntry::formatHeader(const std::string& name, log_id_t id) const {
|
||||
bool isprune = worstUidEnabledForLogid(id);
|
||||
return formatLine(android::base::StringPrintf(name.c_str(),
|
||||
|
@ -401,12 +444,9 @@ std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const {
|
|||
}
|
||||
|
||||
static const size_t maximum_sorted_entries = 32;
|
||||
std::unique_ptr<const PidEntry* []> sorted =
|
||||
stat.pidSystemTable[id].sort(uid, (pid_t)0, maximum_sorted_entries);
|
||||
std::array<const PidEntry*, maximum_sorted_entries> sorted;
|
||||
stat.pidSystemTable[id].MaxEntries(uid, 0, &sorted);
|
||||
|
||||
if (!sorted.get()) {
|
||||
return output;
|
||||
}
|
||||
std::string byPid;
|
||||
size_t index;
|
||||
bool hasDropped = false;
|
||||
|
|
|
@ -14,8 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _LOGD_LOG_STATISTICS_H__
|
||||
#define _LOGD_LOG_STATISTICS_H__
|
||||
#pragma once
|
||||
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
|
@ -25,6 +24,7 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
#include <algorithm> // std::max
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
@ -79,16 +79,12 @@ class LogHashtable {
|
|||
typedef
|
||||
typename std::unordered_map<TKey, TEntry>::const_iterator const_iterator;
|
||||
|
||||
std::unique_ptr<const TEntry* []> sort(uid_t uid, pid_t pid,
|
||||
size_t len) const {
|
||||
if (!len) {
|
||||
std::unique_ptr<const TEntry* []> sorted(nullptr);
|
||||
return sorted;
|
||||
}
|
||||
|
||||
const TEntry** retval = new const TEntry*[len];
|
||||
memset(retval, 0, sizeof(*retval) * len);
|
||||
|
||||
// Returns a sorted array of up to len highest entries sorted by size. If fewer than len
|
||||
// entries are found, their positions are set to nullptr.
|
||||
template <size_t len>
|
||||
void MaxEntries(uid_t uid, pid_t pid, std::array<const TEntry*, len>* out) const {
|
||||
auto& retval = *out;
|
||||
retval.fill(nullptr);
|
||||
for (const_iterator it = map.begin(); it != map.end(); ++it) {
|
||||
const TEntry& entry = it->second;
|
||||
|
||||
|
@ -113,8 +109,6 @@ class LogHashtable {
|
|||
retval[index] = &entry;
|
||||
}
|
||||
}
|
||||
std::unique_ptr<const TEntry* []> sorted(retval);
|
||||
return sorted;
|
||||
}
|
||||
|
||||
inline iterator add(const TKey& key, const LogBufferElement* element) {
|
||||
|
@ -176,11 +170,8 @@ class LogHashtable {
|
|||
log_id_t id = LOG_ID_MAX) const {
|
||||
static const size_t maximum_sorted_entries = 32;
|
||||
std::string output;
|
||||
std::unique_ptr<const TEntry* []> sorted =
|
||||
sort(uid, pid, maximum_sorted_entries);
|
||||
if (!sorted.get()) {
|
||||
return output;
|
||||
}
|
||||
std::array<const TEntry*, maximum_sorted_entries> sorted;
|
||||
MaxEntries(uid, pid, &sorted);
|
||||
bool headerPrinted = false;
|
||||
for (size_t index = 0; index < maximum_sorted_entries; ++index) {
|
||||
const TEntry* entry = sorted[index];
|
||||
|
@ -627,41 +618,6 @@ struct TagNameEntry : 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:
|
||||
explicit 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;
|
||||
|
@ -748,16 +704,12 @@ class LogStatistics {
|
|||
--mDroppedElements[log_id];
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
LogFindWorst<TagEntry> sortTags(uid_t uid, pid_t pid, size_t len, log_id) {
|
||||
return LogFindWorst<TagEntry>(tagTable.sort(uid, pid, len));
|
||||
}
|
||||
void WorstTwoUids(log_id id, size_t threshold, int* worst, size_t* worst_sizes,
|
||||
size_t* second_worst_sizes);
|
||||
void WorstTwoTags(size_t threshold, int* worst, size_t* worst_sizes,
|
||||
size_t* second_worst_sizes);
|
||||
void WorstTwoSystemPids(log_id id, size_t worst_uid_sizes, int* worst,
|
||||
size_t* second_worst_sizes);
|
||||
|
||||
// fast track current value by id only
|
||||
size_t sizes(log_id_t id) const {
|
||||
|
@ -785,6 +737,9 @@ class LogStatistics {
|
|||
const char* pidToName(pid_t pid) const;
|
||||
uid_t pidToUid(pid_t pid);
|
||||
const char* uidToName(uid_t uid) const;
|
||||
};
|
||||
|
||||
#endif // _LOGD_LOG_STATISTICS_H__
|
||||
private:
|
||||
template <typename TKey, typename TEntry>
|
||||
void WorstTwoWithThreshold(const LogHashtable<TKey, TEntry>& table, size_t threshold,
|
||||
int* worst, size_t* worst_sizes, size_t* second_worst_sizes);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue