Merge "logd: format LogBufferElement and LogStatistics correctly"
This commit is contained in:
commit
4ab0bc414d
7 changed files with 479 additions and 594 deletions
|
@ -48,38 +48,33 @@ ChattyLogBuffer::~ChattyLogBuffer() {}
|
|||
|
||||
enum match_type { DIFFERENT, SAME, SAME_LIBLOG };
|
||||
|
||||
static enum match_type Identical(LogBufferElement* elem, LogBufferElement* last) {
|
||||
// is it mostly identical?
|
||||
// if (!elem) return DIFFERENT;
|
||||
ssize_t lenl = elem->getMsgLen();
|
||||
static enum match_type Identical(const LogBufferElement& elem, const LogBufferElement& last) {
|
||||
ssize_t lenl = elem.msg_len();
|
||||
if (lenl <= 0) return DIFFERENT; // value if this represents a chatty elem
|
||||
// if (!last) return DIFFERENT;
|
||||
ssize_t lenr = last->getMsgLen();
|
||||
ssize_t lenr = last.msg_len();
|
||||
if (lenr <= 0) return DIFFERENT; // value if this represents a chatty elem
|
||||
// if (elem->getLogId() != last->getLogId()) return DIFFERENT;
|
||||
if (elem->getUid() != last->getUid()) return DIFFERENT;
|
||||
if (elem->getPid() != last->getPid()) return DIFFERENT;
|
||||
if (elem->getTid() != last->getTid()) return DIFFERENT;
|
||||
if (elem.uid() != last.uid()) return DIFFERENT;
|
||||
if (elem.pid() != last.pid()) return DIFFERENT;
|
||||
if (elem.tid() != last.tid()) return DIFFERENT;
|
||||
|
||||
// last is more than a minute old, stop squashing identical messages
|
||||
if (elem->getRealTime().nsec() > (last->getRealTime().nsec() + 60 * NS_PER_SEC))
|
||||
return DIFFERENT;
|
||||
if (elem.realtime().nsec() > (last.realtime().nsec() + 60 * NS_PER_SEC)) return DIFFERENT;
|
||||
|
||||
// Identical message
|
||||
const char* msgl = elem->getMsg();
|
||||
const char* msgr = last->getMsg();
|
||||
const char* msgl = elem.msg();
|
||||
const char* msgr = last.msg();
|
||||
if (lenl == lenr) {
|
||||
if (!fastcmp<memcmp>(msgl, msgr, lenl)) return SAME;
|
||||
// liblog tagged messages (content gets summed)
|
||||
if (elem->getLogId() == LOG_ID_EVENTS && lenl == sizeof(android_log_event_int_t) &&
|
||||
if (elem.log_id() == LOG_ID_EVENTS && lenl == sizeof(android_log_event_int_t) &&
|
||||
!fastcmp<memcmp>(msgl, msgr, sizeof(android_log_event_int_t) - sizeof(int32_t)) &&
|
||||
elem->getTag() == LIBLOG_LOG_TAG) {
|
||||
elem.GetTag() == LIBLOG_LOG_TAG) {
|
||||
return SAME_LIBLOG;
|
||||
}
|
||||
}
|
||||
|
||||
// audit message (except sequence number) identical?
|
||||
if (last->isBinary() && lenl > static_cast<ssize_t>(sizeof(android_log_event_string_t)) &&
|
||||
if (last.IsBinary() && lenl > static_cast<ssize_t>(sizeof(android_log_event_string_t)) &&
|
||||
lenr > static_cast<ssize_t>(sizeof(android_log_event_string_t))) {
|
||||
if (fastcmp<memcmp>(msgl, msgr, sizeof(android_log_event_string_t) - sizeof(int32_t))) {
|
||||
return DIFFERENT;
|
||||
|
@ -105,11 +100,11 @@ static enum match_type Identical(LogBufferElement* elem, LogBufferElement* last)
|
|||
|
||||
void ChattyLogBuffer::LogInternal(LogBufferElement&& elem) {
|
||||
// b/137093665: don't coalesce security messages.
|
||||
if (elem.getLogId() == LOG_ID_SECURITY) {
|
||||
if (elem.log_id() == LOG_ID_SECURITY) {
|
||||
SimpleLogBuffer::LogInternal(std::move(elem));
|
||||
return;
|
||||
}
|
||||
int log_id = elem.getLogId();
|
||||
int log_id = elem.log_id();
|
||||
|
||||
// Initialize last_logged_elements_ to a copy of elem if logging the first element for a log_id.
|
||||
if (!last_logged_elements_[log_id]) {
|
||||
|
@ -119,12 +114,12 @@ void ChattyLogBuffer::LogInternal(LogBufferElement&& elem) {
|
|||
}
|
||||
|
||||
LogBufferElement& current_last = *last_logged_elements_[log_id];
|
||||
enum match_type match = Identical(&elem, ¤t_last);
|
||||
enum match_type match = Identical(elem, current_last);
|
||||
|
||||
if (match == DIFFERENT) {
|
||||
if (duplicate_elements_[log_id]) {
|
||||
// If we previously had 3+ identical messages, log the chatty message.
|
||||
if (duplicate_elements_[log_id]->getDropped() > 0) {
|
||||
if (duplicate_elements_[log_id]->dropped_count() > 0) {
|
||||
SimpleLogBuffer::LogInternal(std::move(*duplicate_elements_[log_id]));
|
||||
}
|
||||
duplicate_elements_[log_id].reset();
|
||||
|
@ -146,10 +141,10 @@ void ChattyLogBuffer::LogInternal(LogBufferElement&& elem) {
|
|||
// 3+ identical LIBLOG event messages: coalesce them into last_logged_elements_.
|
||||
if (match == SAME_LIBLOG) {
|
||||
const android_log_event_int_t* current_last_event =
|
||||
reinterpret_cast<const android_log_event_int_t*>(current_last.getMsg());
|
||||
reinterpret_cast<const android_log_event_int_t*>(current_last.msg());
|
||||
int64_t current_last_count = current_last_event->payload.data;
|
||||
android_log_event_int_t* elem_event =
|
||||
reinterpret_cast<android_log_event_int_t*>(const_cast<char*>(elem.getMsg()));
|
||||
reinterpret_cast<android_log_event_int_t*>(const_cast<char*>(elem.msg()));
|
||||
int64_t elem_count = elem_event->payload.data;
|
||||
|
||||
int64_t total = current_last_count + elem_count;
|
||||
|
@ -158,22 +153,22 @@ void ChattyLogBuffer::LogInternal(LogBufferElement&& elem) {
|
|||
last_logged_elements_[log_id].emplace(std::move(elem));
|
||||
return;
|
||||
}
|
||||
stats()->AddTotal(current_last.getLogId(), current_last.getMsgLen());
|
||||
stats()->AddTotal(current_last.log_id(), current_last.msg_len());
|
||||
elem_event->payload.data = total;
|
||||
last_logged_elements_[log_id].emplace(std::move(elem));
|
||||
return;
|
||||
}
|
||||
|
||||
// 3+ identical messages (not LIBLOG) messages: increase the drop count.
|
||||
uint16_t dropped_count = duplicate_elements_[log_id]->getDropped();
|
||||
uint16_t dropped_count = duplicate_elements_[log_id]->dropped_count();
|
||||
if (dropped_count == std::numeric_limits<uint16_t>::max()) {
|
||||
SimpleLogBuffer::LogInternal(std::move(*duplicate_elements_[log_id]));
|
||||
dropped_count = 0;
|
||||
}
|
||||
// We're dropping the current_last log so add its stats to the total.
|
||||
stats()->AddTotal(current_last.getLogId(), current_last.getMsgLen());
|
||||
stats()->AddTotal(current_last.log_id(), current_last.msg_len());
|
||||
// Use current_last for tracking the dropped count to always use the latest timestamp.
|
||||
current_last.setDropped(dropped_count + 1);
|
||||
current_last.SetDropped(dropped_count + 1);
|
||||
duplicate_elements_[log_id].emplace(std::move(current_last));
|
||||
last_logged_elements_[log_id].emplace(std::move(elem));
|
||||
}
|
||||
|
@ -181,14 +176,13 @@ void ChattyLogBuffer::LogInternal(LogBufferElement&& elem) {
|
|||
LogBufferElementCollection::iterator ChattyLogBuffer::Erase(LogBufferElementCollection::iterator it,
|
||||
bool coalesce) {
|
||||
LogBufferElement& element = *it;
|
||||
log_id_t id = element.getLogId();
|
||||
log_id_t id = element.log_id();
|
||||
|
||||
// Remove iterator references in the various lists that will become stale
|
||||
// after the element is erased from the main logging list.
|
||||
|
||||
{ // start of scope for found iterator
|
||||
int key = (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element.getTag()
|
||||
: element.getUid();
|
||||
int key = (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element.GetTag() : element.uid();
|
||||
LogBufferIteratorMap::iterator found = mLastWorst[id].find(key);
|
||||
if ((found != mLastWorst[id].end()) && (it == found->second)) {
|
||||
mLastWorst[id].erase(found);
|
||||
|
@ -196,10 +190,10 @@ LogBufferElementCollection::iterator ChattyLogBuffer::Erase(LogBufferElementColl
|
|||
}
|
||||
|
||||
{ // start of scope for pid found iterator
|
||||
// element->getUid() may not be AID_SYSTEM for next-best-watermark.
|
||||
// element->uid() may not be AID_SYSTEM for next-best-watermark.
|
||||
// will not assume id != LOG_ID_EVENTS or LOG_ID_SECURITY for KISS and
|
||||
// long term code stability, find() check should be fast for those ids.
|
||||
LogBufferPidIteratorMap::iterator found = mLastWorstPidOfSystem[id].find(element.getPid());
|
||||
LogBufferPidIteratorMap::iterator found = mLastWorstPidOfSystem[id].find(element.pid());
|
||||
if (found != mLastWorstPidOfSystem[id].end() && it == found->second) {
|
||||
mLastWorstPidOfSystem[id].erase(found);
|
||||
}
|
||||
|
@ -207,14 +201,13 @@ LogBufferElementCollection::iterator ChattyLogBuffer::Erase(LogBufferElementColl
|
|||
|
||||
#ifdef DEBUG_CHECK_FOR_STALE_ENTRIES
|
||||
LogBufferElementCollection::iterator bad = it;
|
||||
int key =
|
||||
(id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element->getTag() : element->getUid();
|
||||
int key = (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element->GetTag() : element->uid();
|
||||
#endif
|
||||
|
||||
if (coalesce) {
|
||||
stats()->Erase(&element);
|
||||
stats()->Erase(element);
|
||||
} else {
|
||||
stats()->Subtract(&element);
|
||||
stats()->Subtract(element);
|
||||
}
|
||||
|
||||
it = SimpleLogBuffer::Erase(it);
|
||||
|
@ -245,15 +238,15 @@ class LogBufferElementLast {
|
|||
|
||||
public:
|
||||
bool coalesce(LogBufferElement* element, uint16_t dropped) {
|
||||
uint64_t key = LogBufferElementKey(element->getUid(), element->getPid(), element->getTid());
|
||||
uint64_t key = LogBufferElementKey(element->uid(), element->pid(), element->tid());
|
||||
LogBufferElementMap::iterator it = map.find(key);
|
||||
if (it != map.end()) {
|
||||
LogBufferElement* found = it->second;
|
||||
uint16_t moreDropped = found->getDropped();
|
||||
uint16_t moreDropped = found->dropped_count();
|
||||
if ((dropped + moreDropped) > USHRT_MAX) {
|
||||
map.erase(it);
|
||||
} else {
|
||||
found->setDropped(dropped + moreDropped);
|
||||
found->SetDropped(dropped + moreDropped);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -261,18 +254,18 @@ class LogBufferElementLast {
|
|||
}
|
||||
|
||||
void add(LogBufferElement* element) {
|
||||
uint64_t key = LogBufferElementKey(element->getUid(), element->getPid(), element->getTid());
|
||||
uint64_t key = LogBufferElementKey(element->uid(), element->pid(), element->tid());
|
||||
map[key] = element;
|
||||
}
|
||||
|
||||
void clear() { map.clear(); }
|
||||
|
||||
void clear(LogBufferElement* element) {
|
||||
uint64_t current = element->getRealTime().nsec() - (EXPIRE_RATELIMIT * NS_PER_SEC);
|
||||
uint64_t current = element->realtime().nsec() - (EXPIRE_RATELIMIT * NS_PER_SEC);
|
||||
for (LogBufferElementMap::iterator it = map.begin(); it != map.end();) {
|
||||
LogBufferElement* mapElement = it->second;
|
||||
if (mapElement->getDropped() >= EXPIRE_THRESHOLD &&
|
||||
current > mapElement->getRealTime().nsec()) {
|
||||
if (mapElement->dropped_count() >= EXPIRE_THRESHOLD &&
|
||||
current > mapElement->realtime().nsec()) {
|
||||
it = map.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
|
@ -359,12 +352,12 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u
|
|||
while (it != logs().end()) {
|
||||
LogBufferElement& element = *it;
|
||||
|
||||
if (element.getLogId() != id || element.getUid() != caller_uid) {
|
||||
if (element.log_id() != id || element.uid() != caller_uid) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (oldest && oldest->start() <= element.getSequence()) {
|
||||
if (oldest && oldest->start() <= element.sequence()) {
|
||||
busy = true;
|
||||
KickReader(oldest, id, pruneRows);
|
||||
break;
|
||||
|
@ -382,7 +375,7 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u
|
|||
bool hasBlacklist = (id != LOG_ID_SECURITY) && prune_->naughty();
|
||||
while (!clearAll && (pruneRows > 0)) {
|
||||
// recalculate the worst offender on every batched pass
|
||||
int worst = -1; // not valid for getUid() or getKey()
|
||||
int worst = -1; // not valid for uid() or getKey()
|
||||
size_t worst_sizes = 0;
|
||||
size_t second_worst_sizes = 0;
|
||||
pid_t worstPid = 0; // POSIX guarantees PID != 0
|
||||
|
@ -445,19 +438,19 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u
|
|||
while (it != logs().end()) {
|
||||
LogBufferElement& element = *it;
|
||||
|
||||
if (oldest && oldest->start() <= element.getSequence()) {
|
||||
if (oldest && oldest->start() <= element.sequence()) {
|
||||
busy = true;
|
||||
// Do not let chatty eliding trigger any reader mitigation
|
||||
break;
|
||||
}
|
||||
|
||||
if (element.getLogId() != id) {
|
||||
if (element.log_id() != id) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
// below this point element->getLogId() == id
|
||||
// below this point element->log_id() == id
|
||||
|
||||
uint16_t dropped = element.getDropped();
|
||||
uint16_t dropped = element.dropped_count();
|
||||
|
||||
// remove any leading drops
|
||||
if (leading && dropped) {
|
||||
|
@ -470,8 +463,8 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u
|
|||
continue;
|
||||
}
|
||||
|
||||
int key = (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element.getTag()
|
||||
: element.getUid();
|
||||
int key = (id == LOG_ID_EVENTS || id == LOG_ID_SECURITY) ? element.GetTag()
|
||||
: element.uid();
|
||||
|
||||
if (hasBlacklist && prune_->naughty(&element)) {
|
||||
last.clear(&element);
|
||||
|
@ -490,25 +483,25 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u
|
|||
if (worst_sizes < second_worst_sizes) {
|
||||
break;
|
||||
}
|
||||
worst_sizes -= element.getMsgLen();
|
||||
worst_sizes -= element.msg_len();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (element.getRealTime() < (lastt->getRealTime() - too_old) ||
|
||||
element.getRealTime() > lastt->getRealTime()) {
|
||||
if (element.realtime() < (lastt->realtime() - too_old) ||
|
||||
element.realtime() > lastt->realtime()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (dropped) {
|
||||
last.add(&element);
|
||||
if (worstPid && ((!gc && element.getPid() == worstPid) ||
|
||||
mLastWorstPidOfSystem[id].find(element.getPid()) ==
|
||||
if (worstPid && ((!gc && element.pid() == worstPid) ||
|
||||
mLastWorstPidOfSystem[id].find(element.pid()) ==
|
||||
mLastWorstPidOfSystem[id].end())) {
|
||||
// element->getUid() may not be AID_SYSTEM, next best
|
||||
// element->uid() may not be AID_SYSTEM, next best
|
||||
// watermark if current one empty. id is not LOG_ID_EVENTS
|
||||
// or LOG_ID_SECURITY because of worstPid check.
|
||||
mLastWorstPidOfSystem[id][element.getPid()] = it;
|
||||
mLastWorstPidOfSystem[id][element.pid()] = it;
|
||||
}
|
||||
if ((!gc && !worstPid && (key == worst)) ||
|
||||
(mLastWorst[id].find(key) == mLastWorst[id].end())) {
|
||||
|
@ -518,14 +511,14 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u
|
|||
continue;
|
||||
}
|
||||
|
||||
if (key != worst || (worstPid && element.getPid() != worstPid)) {
|
||||
if (key != worst || (worstPid && element.pid() != worstPid)) {
|
||||
leading = false;
|
||||
last.clear(&element);
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
// key == worst below here
|
||||
// If worstPid set, then element->getPid() == worstPid below here
|
||||
// If worstPid set, then element->pid() == worstPid below here
|
||||
|
||||
pruneRows--;
|
||||
if (pruneRows == 0) {
|
||||
|
@ -534,21 +527,21 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u
|
|||
|
||||
kick = true;
|
||||
|
||||
uint16_t len = element.getMsgLen();
|
||||
uint16_t len = element.msg_len();
|
||||
|
||||
// do not create any leading drops
|
||||
if (leading) {
|
||||
it = Erase(it);
|
||||
} else {
|
||||
stats()->Drop(&element);
|
||||
element.setDropped(1);
|
||||
stats()->Drop(element);
|
||||
element.SetDropped(1);
|
||||
if (last.coalesce(&element, 1)) {
|
||||
it = Erase(it, true);
|
||||
} else {
|
||||
last.add(&element);
|
||||
if (worstPid && (!gc || mLastWorstPidOfSystem[id].find(worstPid) ==
|
||||
mLastWorstPidOfSystem[id].end())) {
|
||||
// element->getUid() may not be AID_SYSTEM, next best
|
||||
// element->uid() may not be AID_SYSTEM, next best
|
||||
// watermark if current one empty. id is not
|
||||
// LOG_ID_EVENTS or LOG_ID_SECURITY because of worstPid.
|
||||
mLastWorstPidOfSystem[id][worstPid] = it;
|
||||
|
@ -577,18 +570,18 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u
|
|||
while ((pruneRows > 0) && (it != logs().end())) {
|
||||
LogBufferElement& element = *it;
|
||||
|
||||
if (element.getLogId() != id) {
|
||||
if (element.log_id() != id) {
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (oldest && oldest->start() <= element.getSequence()) {
|
||||
if (oldest && oldest->start() <= element.sequence()) {
|
||||
busy = true;
|
||||
if (!whitelist) KickReader(oldest, id, pruneRows);
|
||||
break;
|
||||
}
|
||||
|
||||
if (hasWhitelist && !element.getDropped() && prune_->nice(&element)) {
|
||||
if (hasWhitelist && !element.dropped_count() && prune_->nice(&element)) {
|
||||
// WhiteListed
|
||||
whitelist = true;
|
||||
it++;
|
||||
|
@ -605,12 +598,12 @@ bool ChattyLogBuffer::Prune(log_id_t id, unsigned long pruneRows, uid_t caller_u
|
|||
while ((it != logs().end()) && (pruneRows > 0)) {
|
||||
LogBufferElement& element = *it;
|
||||
|
||||
if (element.getLogId() != id) {
|
||||
if (element.log_id() != id) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (oldest && oldest->start() <= element.getSequence()) {
|
||||
if (oldest && oldest->start() <= element.sequence()) {
|
||||
busy = true;
|
||||
KickReader(oldest, id, pruneRows);
|
||||
break;
|
||||
|
|
|
@ -32,92 +32,92 @@
|
|||
|
||||
LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
|
||||
pid_t tid, uint64_t sequence, const char* msg, uint16_t len)
|
||||
: mUid(uid),
|
||||
mPid(pid),
|
||||
mTid(tid),
|
||||
mSequence(sequence),
|
||||
mRealTime(realtime),
|
||||
mMsgLen(len),
|
||||
mLogId(log_id),
|
||||
mDropped(false) {
|
||||
mMsg = new char[len];
|
||||
memcpy(mMsg, msg, len);
|
||||
: uid_(uid),
|
||||
pid_(pid),
|
||||
tid_(tid),
|
||||
sequence_(sequence),
|
||||
realtime_(realtime),
|
||||
msg_len_(len),
|
||||
log_id_(log_id),
|
||||
dropped_(false) {
|
||||
msg_ = new char[len];
|
||||
memcpy(msg_, msg, len);
|
||||
}
|
||||
|
||||
LogBufferElement::LogBufferElement(const LogBufferElement& elem)
|
||||
: mUid(elem.mUid),
|
||||
mPid(elem.mPid),
|
||||
mTid(elem.mTid),
|
||||
mSequence(elem.mSequence),
|
||||
mRealTime(elem.mRealTime),
|
||||
mMsgLen(elem.mMsgLen),
|
||||
mLogId(elem.mLogId),
|
||||
mDropped(elem.mDropped) {
|
||||
if (mDropped) {
|
||||
mTag = elem.getTag();
|
||||
: uid_(elem.uid_),
|
||||
pid_(elem.pid_),
|
||||
tid_(elem.tid_),
|
||||
sequence_(elem.sequence_),
|
||||
realtime_(elem.realtime_),
|
||||
msg_len_(elem.msg_len_),
|
||||
log_id_(elem.log_id_),
|
||||
dropped_(elem.dropped_) {
|
||||
if (dropped_) {
|
||||
tag_ = elem.GetTag();
|
||||
} else {
|
||||
mMsg = new char[mMsgLen];
|
||||
memcpy(mMsg, elem.mMsg, mMsgLen);
|
||||
msg_ = new char[msg_len_];
|
||||
memcpy(msg_, elem.msg_, msg_len_);
|
||||
}
|
||||
}
|
||||
|
||||
LogBufferElement::LogBufferElement(LogBufferElement&& elem)
|
||||
: mUid(elem.mUid),
|
||||
mPid(elem.mPid),
|
||||
mTid(elem.mTid),
|
||||
mSequence(elem.mSequence),
|
||||
mRealTime(elem.mRealTime),
|
||||
mMsgLen(elem.mMsgLen),
|
||||
mLogId(elem.mLogId),
|
||||
mDropped(elem.mDropped) {
|
||||
if (mDropped) {
|
||||
mTag = elem.getTag();
|
||||
: uid_(elem.uid_),
|
||||
pid_(elem.pid_),
|
||||
tid_(elem.tid_),
|
||||
sequence_(elem.sequence_),
|
||||
realtime_(elem.realtime_),
|
||||
msg_len_(elem.msg_len_),
|
||||
log_id_(elem.log_id_),
|
||||
dropped_(elem.dropped_) {
|
||||
if (dropped_) {
|
||||
tag_ = elem.GetTag();
|
||||
} else {
|
||||
mMsg = elem.mMsg;
|
||||
elem.mMsg = nullptr;
|
||||
msg_ = elem.msg_;
|
||||
elem.msg_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
LogBufferElement::~LogBufferElement() {
|
||||
if (!mDropped) {
|
||||
delete[] mMsg;
|
||||
if (!dropped_) {
|
||||
delete[] msg_;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t LogBufferElement::getTag() const {
|
||||
uint32_t LogBufferElement::GetTag() const {
|
||||
// Binary buffers have no tag.
|
||||
if (!isBinary()) {
|
||||
if (!IsBinary()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Dropped messages store the tag in place of mMsg.
|
||||
if (mDropped) {
|
||||
return mTag;
|
||||
// Dropped messages store the tag in place of msg_.
|
||||
if (dropped_) {
|
||||
return tag_;
|
||||
}
|
||||
|
||||
// For non-dropped messages, we get the tag from the message header itself.
|
||||
if (mMsgLen < sizeof(android_event_header_t)) {
|
||||
if (msg_len_ < sizeof(android_event_header_t)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return reinterpret_cast<const android_event_header_t*>(mMsg)->tag;
|
||||
return reinterpret_cast<const android_event_header_t*>(msg_)->tag;
|
||||
}
|
||||
|
||||
uint16_t LogBufferElement::setDropped(uint16_t value) {
|
||||
if (mDropped) {
|
||||
return mDroppedCount = value;
|
||||
uint16_t LogBufferElement::SetDropped(uint16_t value) {
|
||||
if (dropped_) {
|
||||
return dropped_count_ = value;
|
||||
}
|
||||
|
||||
// The tag information is saved in mMsg data, which is in a union with mTag, used after mDropped
|
||||
// is set to true. Therefore we save the tag value aside, delete mMsg, then set mTag to the tag
|
||||
// The tag information is saved in msg_ data, which is in a union with tag_, used after dropped_
|
||||
// is set to true. Therefore we save the tag value aside, delete msg_, then set tag_ to the tag
|
||||
// value in its place.
|
||||
auto old_tag = getTag();
|
||||
delete[] mMsg;
|
||||
mMsg = nullptr;
|
||||
auto old_tag = GetTag();
|
||||
delete[] msg_;
|
||||
msg_ = nullptr;
|
||||
|
||||
mTag = old_tag;
|
||||
mDropped = true;
|
||||
return mDroppedCount = value;
|
||||
tag_ = old_tag;
|
||||
dropped_ = true;
|
||||
return dropped_count_ = value;
|
||||
}
|
||||
|
||||
// caller must own and free character string
|
||||
|
@ -165,8 +165,8 @@ char* android::tidToName(pid_t tid) {
|
|||
return retval;
|
||||
}
|
||||
|
||||
// assumption: mMsg == NULL
|
||||
size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogStatistics* stats,
|
||||
// assumption: msg_ == NULL
|
||||
size_t LogBufferElement::PopulateDroppedMessage(char*& buffer, LogStatistics* stats,
|
||||
bool lastSame) {
|
||||
static const char tag[] = "chatty";
|
||||
|
||||
|
@ -176,13 +176,13 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogStatistics* st
|
|||
}
|
||||
|
||||
static const char format_uid[] = "uid=%u%s%s %s %u line%s";
|
||||
const char* name = stats->UidToName(mUid);
|
||||
const char* commName = android::tidToName(mTid);
|
||||
if (!commName && (mTid != mPid)) {
|
||||
commName = android::tidToName(mPid);
|
||||
const char* name = stats->UidToName(uid_);
|
||||
const char* commName = android::tidToName(tid_);
|
||||
if (!commName && (tid_ != pid_)) {
|
||||
commName = android::tidToName(pid_);
|
||||
}
|
||||
if (!commName) {
|
||||
commName = stats->PidToName(mPid);
|
||||
commName = stats->PidToName(pid_);
|
||||
}
|
||||
if (name && name[0] && commName && (name[0] == commName[0])) {
|
||||
size_t len = strlen(name + 1);
|
||||
|
@ -214,12 +214,11 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogStatistics* st
|
|||
}
|
||||
// identical to below to calculate the buffer size required
|
||||
const char* type = lastSame ? "identical" : "expire";
|
||||
size_t len = snprintf(nullptr, 0, format_uid, mUid, name ? name : "",
|
||||
commName ? commName : "", type, getDropped(),
|
||||
(getDropped() > 1) ? "s" : "");
|
||||
size_t len = snprintf(nullptr, 0, format_uid, uid_, name ? name : "", commName ? commName : "",
|
||||
type, dropped_count(), (dropped_count() > 1) ? "s" : "");
|
||||
|
||||
size_t hdrLen;
|
||||
if (isBinary()) {
|
||||
if (IsBinary()) {
|
||||
hdrLen = sizeof(android_log_event_string_t);
|
||||
} else {
|
||||
hdrLen = 1 + sizeof(tag);
|
||||
|
@ -233,7 +232,7 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogStatistics* st
|
|||
}
|
||||
|
||||
size_t retval = hdrLen + len;
|
||||
if (isBinary()) {
|
||||
if (IsBinary()) {
|
||||
android_log_event_string_t* event =
|
||||
reinterpret_cast<android_log_event_string_t*>(buffer);
|
||||
|
||||
|
@ -246,9 +245,8 @@ size_t LogBufferElement::populateDroppedMessage(char*& buffer, LogStatistics* st
|
|||
strcpy(buffer + 1, tag);
|
||||
}
|
||||
|
||||
snprintf(buffer + hdrLen, len + 1, format_uid, mUid, name ? name : "",
|
||||
commName ? commName : "", type, getDropped(),
|
||||
(getDropped() > 1) ? "s" : "");
|
||||
snprintf(buffer + hdrLen, len + 1, format_uid, uid_, name ? name : "", commName ? commName : "",
|
||||
type, dropped_count(), (dropped_count() > 1) ? "s" : "");
|
||||
free(const_cast<char*>(name));
|
||||
free(const_cast<char*>(commName));
|
||||
|
||||
|
@ -259,22 +257,22 @@ bool LogBufferElement::FlushTo(LogWriter* writer, LogStatistics* stats, bool las
|
|||
struct logger_entry entry = {};
|
||||
|
||||
entry.hdr_size = sizeof(struct logger_entry);
|
||||
entry.lid = mLogId;
|
||||
entry.pid = mPid;
|
||||
entry.tid = mTid;
|
||||
entry.uid = mUid;
|
||||
entry.sec = mRealTime.tv_sec;
|
||||
entry.nsec = mRealTime.tv_nsec;
|
||||
entry.lid = log_id_;
|
||||
entry.pid = pid_;
|
||||
entry.tid = tid_;
|
||||
entry.uid = uid_;
|
||||
entry.sec = realtime_.tv_sec;
|
||||
entry.nsec = realtime_.tv_nsec;
|
||||
|
||||
char* buffer = nullptr;
|
||||
const char* msg;
|
||||
if (mDropped) {
|
||||
entry.len = populateDroppedMessage(buffer, stats, lastSame);
|
||||
if (dropped_) {
|
||||
entry.len = PopulateDroppedMessage(buffer, stats, lastSame);
|
||||
if (!entry.len) return true;
|
||||
msg = buffer;
|
||||
} else {
|
||||
msg = mMsg;
|
||||
entry.len = mMsgLen;
|
||||
msg = msg_;
|
||||
entry.len = msg_len_;
|
||||
}
|
||||
|
||||
bool retval = writer->Write(entry, msg);
|
||||
|
|
|
@ -33,26 +33,6 @@ class LogStatistics;
|
|||
#define EXPIRE_RATELIMIT 10 // maximum rate in seconds to report expiration
|
||||
|
||||
class __attribute__((packed)) LogBufferElement {
|
||||
// sized to match reality of incoming log packets
|
||||
const uint32_t mUid;
|
||||
const uint32_t mPid;
|
||||
const uint32_t mTid;
|
||||
uint64_t mSequence;
|
||||
log_time mRealTime;
|
||||
union {
|
||||
char* mMsg; // mDropped == false
|
||||
int32_t mTag; // mDropped == true
|
||||
};
|
||||
union {
|
||||
const uint16_t mMsgLen; // mDropped == false
|
||||
uint16_t mDroppedCount; // mDropped == true
|
||||
};
|
||||
const uint8_t mLogId;
|
||||
bool mDropped;
|
||||
|
||||
// assumption: mDropped == true
|
||||
size_t populateDroppedMessage(char*& buffer, LogStatistics* parent, bool lastSame);
|
||||
|
||||
public:
|
||||
LogBufferElement(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
|
||||
uint64_t sequence, const char* msg, uint16_t len);
|
||||
|
@ -60,37 +40,41 @@ class __attribute__((packed)) LogBufferElement {
|
|||
LogBufferElement(LogBufferElement&& elem);
|
||||
~LogBufferElement();
|
||||
|
||||
bool isBinary(void) const {
|
||||
return (mLogId == LOG_ID_EVENTS) || (mLogId == LOG_ID_SECURITY);
|
||||
}
|
||||
bool IsBinary() const { return (log_id_ == LOG_ID_EVENTS) || (log_id_ == LOG_ID_SECURITY); }
|
||||
|
||||
log_id_t getLogId() const {
|
||||
return static_cast<log_id_t>(mLogId);
|
||||
}
|
||||
uid_t getUid(void) const {
|
||||
return mUid;
|
||||
}
|
||||
pid_t getPid(void) const {
|
||||
return mPid;
|
||||
}
|
||||
pid_t getTid(void) const {
|
||||
return mTid;
|
||||
}
|
||||
uint32_t getTag() const;
|
||||
uint16_t getDropped(void) const {
|
||||
return mDropped ? mDroppedCount : 0;
|
||||
}
|
||||
uint16_t setDropped(uint16_t value);
|
||||
uint16_t getMsgLen() const {
|
||||
return mDropped ? 0 : mMsgLen;
|
||||
}
|
||||
const char* getMsg() const {
|
||||
return mDropped ? nullptr : mMsg;
|
||||
}
|
||||
uint64_t getSequence() const { return mSequence; }
|
||||
log_time getRealTime(void) const {
|
||||
return mRealTime;
|
||||
}
|
||||
uint32_t GetTag() const;
|
||||
uint16_t SetDropped(uint16_t value);
|
||||
|
||||
bool FlushTo(LogWriter* writer, LogStatistics* parent, bool lastSame);
|
||||
|
||||
log_id_t log_id() const { return static_cast<log_id_t>(log_id_); }
|
||||
uid_t uid() const { return uid_; }
|
||||
pid_t pid() const { return pid_; }
|
||||
pid_t tid() const { return tid_; }
|
||||
uint16_t msg_len() const { return dropped_ ? 0 : msg_len_; }
|
||||
const char* msg() const { return dropped_ ? nullptr : msg_; }
|
||||
uint64_t sequence() const { return sequence_; }
|
||||
log_time realtime() const { return realtime_; }
|
||||
uint16_t dropped_count() const { return dropped_ ? dropped_count_ : 0; }
|
||||
|
||||
private:
|
||||
// assumption: mDropped == true
|
||||
size_t PopulateDroppedMessage(char*& buffer, LogStatistics* parent, bool lastSame);
|
||||
|
||||
// sized to match reality of incoming log packets
|
||||
const uint32_t uid_;
|
||||
const uint32_t pid_;
|
||||
const uint32_t tid_;
|
||||
uint64_t sequence_;
|
||||
log_time realtime_;
|
||||
union {
|
||||
char* msg_; // mDropped == false
|
||||
int32_t tag_; // mDropped == true
|
||||
};
|
||||
union {
|
||||
const uint16_t msg_len_; // mDropped == false
|
||||
uint16_t dropped_count_; // mDropped == true
|
||||
};
|
||||
const uint8_t log_id_;
|
||||
bool dropped_;
|
||||
};
|
||||
|
|
|
@ -87,10 +87,10 @@ void LogStatistics::AddTotal(log_id_t log_id, uint16_t size) {
|
|||
++mElementsTotal[log_id];
|
||||
}
|
||||
|
||||
void LogStatistics::Add(LogBufferElement* element) {
|
||||
void LogStatistics::Add(const LogBufferElement& element) {
|
||||
auto lock = std::lock_guard{lock_};
|
||||
log_id_t log_id = element->getLogId();
|
||||
uint16_t size = element->getMsgLen();
|
||||
log_id_t log_id = element.log_id();
|
||||
uint16_t size = element.msg_len();
|
||||
mSizes[log_id] += size;
|
||||
++mElements[log_id];
|
||||
|
||||
|
@ -99,7 +99,7 @@ void LogStatistics::Add(LogBufferElement* element) {
|
|||
// evaluated and trimmed, thus recording size and number of
|
||||
// elements, but we must recognize the manufactured dropped
|
||||
// entry as not contributing to the lifetime totals.
|
||||
if (element->getDropped()) {
|
||||
if (element.dropped_count()) {
|
||||
++mDroppedElements[log_id];
|
||||
} else {
|
||||
mSizesTotal[log_id] += size;
|
||||
|
@ -107,7 +107,7 @@ void LogStatistics::Add(LogBufferElement* element) {
|
|||
++mElementsTotal[log_id];
|
||||
}
|
||||
|
||||
log_time stamp(element->getRealTime());
|
||||
log_time stamp(element.realtime());
|
||||
if (mNewest[log_id] < stamp) {
|
||||
// A major time update invalidates the statistics :-(
|
||||
log_time diff = stamp - mNewest[log_id];
|
||||
|
@ -132,111 +132,111 @@ void LogStatistics::Add(LogBufferElement* element) {
|
|||
return;
|
||||
}
|
||||
|
||||
uidTable[log_id].add(element->getUid(), element);
|
||||
if (element->getUid() == AID_SYSTEM) {
|
||||
pidSystemTable[log_id].add(element->getPid(), element);
|
||||
uidTable[log_id].Add(element.uid(), element);
|
||||
if (element.uid() == AID_SYSTEM) {
|
||||
pidSystemTable[log_id].Add(element.pid(), element);
|
||||
}
|
||||
|
||||
if (!enable) {
|
||||
return;
|
||||
}
|
||||
|
||||
pidTable.add(element->getPid(), element);
|
||||
tidTable.add(element->getTid(), element);
|
||||
pidTable.Add(element.pid(), element);
|
||||
tidTable.Add(element.tid(), element);
|
||||
|
||||
uint32_t tag = element->getTag();
|
||||
uint32_t tag = element.GetTag();
|
||||
if (tag) {
|
||||
if (log_id == LOG_ID_SECURITY) {
|
||||
securityTagTable.add(tag, element);
|
||||
securityTagTable.Add(tag, element);
|
||||
} else {
|
||||
tagTable.add(tag, element);
|
||||
tagTable.Add(tag, element);
|
||||
}
|
||||
}
|
||||
|
||||
if (!element->getDropped()) {
|
||||
tagNameTable.add(TagNameKey(element), element);
|
||||
if (!element.dropped_count()) {
|
||||
tagNameTable.Add(TagNameKey(element), element);
|
||||
}
|
||||
}
|
||||
|
||||
void LogStatistics::Subtract(LogBufferElement* element) {
|
||||
void LogStatistics::Subtract(const LogBufferElement& element) {
|
||||
auto lock = std::lock_guard{lock_};
|
||||
log_id_t log_id = element->getLogId();
|
||||
uint16_t size = element->getMsgLen();
|
||||
log_id_t log_id = element.log_id();
|
||||
uint16_t size = element.msg_len();
|
||||
mSizes[log_id] -= size;
|
||||
--mElements[log_id];
|
||||
if (element->getDropped()) {
|
||||
if (element.dropped_count()) {
|
||||
--mDroppedElements[log_id];
|
||||
}
|
||||
|
||||
if (mOldest[log_id] < element->getRealTime()) {
|
||||
mOldest[log_id] = element->getRealTime();
|
||||
if (mOldest[log_id] < element.realtime()) {
|
||||
mOldest[log_id] = element.realtime();
|
||||
}
|
||||
|
||||
if (log_id == LOG_ID_KERNEL) {
|
||||
return;
|
||||
}
|
||||
|
||||
uidTable[log_id].subtract(element->getUid(), element);
|
||||
if (element->getUid() == AID_SYSTEM) {
|
||||
pidSystemTable[log_id].subtract(element->getPid(), element);
|
||||
uidTable[log_id].Subtract(element.uid(), element);
|
||||
if (element.uid() == AID_SYSTEM) {
|
||||
pidSystemTable[log_id].Subtract(element.pid(), element);
|
||||
}
|
||||
|
||||
if (!enable) {
|
||||
return;
|
||||
}
|
||||
|
||||
pidTable.subtract(element->getPid(), element);
|
||||
tidTable.subtract(element->getTid(), element);
|
||||
pidTable.Subtract(element.pid(), element);
|
||||
tidTable.Subtract(element.tid(), element);
|
||||
|
||||
uint32_t tag = element->getTag();
|
||||
uint32_t tag = element.GetTag();
|
||||
if (tag) {
|
||||
if (log_id == LOG_ID_SECURITY) {
|
||||
securityTagTable.subtract(tag, element);
|
||||
securityTagTable.Subtract(tag, element);
|
||||
} else {
|
||||
tagTable.subtract(tag, element);
|
||||
tagTable.Subtract(tag, element);
|
||||
}
|
||||
}
|
||||
|
||||
if (!element->getDropped()) {
|
||||
tagNameTable.subtract(TagNameKey(element), element);
|
||||
if (!element.dropped_count()) {
|
||||
tagNameTable.Subtract(TagNameKey(element), element);
|
||||
}
|
||||
}
|
||||
|
||||
// Atomically set an entry to drop
|
||||
// entry->setDropped(1) must follow this call, caller should do this explicitly.
|
||||
void LogStatistics::Drop(LogBufferElement* element) {
|
||||
void LogStatistics::Drop(const LogBufferElement& element) {
|
||||
auto lock = std::lock_guard{lock_};
|
||||
log_id_t log_id = element->getLogId();
|
||||
uint16_t size = element->getMsgLen();
|
||||
log_id_t log_id = element.log_id();
|
||||
uint16_t size = element.msg_len();
|
||||
mSizes[log_id] -= size;
|
||||
++mDroppedElements[log_id];
|
||||
|
||||
if (mNewestDropped[log_id] < element->getRealTime()) {
|
||||
mNewestDropped[log_id] = element->getRealTime();
|
||||
if (mNewestDropped[log_id] < element.realtime()) {
|
||||
mNewestDropped[log_id] = element.realtime();
|
||||
}
|
||||
|
||||
uidTable[log_id].drop(element->getUid(), element);
|
||||
if (element->getUid() == AID_SYSTEM) {
|
||||
pidSystemTable[log_id].drop(element->getPid(), element);
|
||||
uidTable[log_id].Drop(element.uid(), element);
|
||||
if (element.uid() == AID_SYSTEM) {
|
||||
pidSystemTable[log_id].Drop(element.pid(), element);
|
||||
}
|
||||
|
||||
if (!enable) {
|
||||
return;
|
||||
}
|
||||
|
||||
pidTable.drop(element->getPid(), element);
|
||||
tidTable.drop(element->getTid(), element);
|
||||
pidTable.Drop(element.pid(), element);
|
||||
tidTable.Drop(element.tid(), element);
|
||||
|
||||
uint32_t tag = element->getTag();
|
||||
uint32_t tag = element.GetTag();
|
||||
if (tag) {
|
||||
if (log_id == LOG_ID_SECURITY) {
|
||||
securityTagTable.drop(tag, element);
|
||||
securityTagTable.Drop(tag, element);
|
||||
} else {
|
||||
tagTable.drop(tag, element);
|
||||
tagTable.Drop(tag, element);
|
||||
}
|
||||
}
|
||||
|
||||
tagNameTable.subtract(TagNameKey(element), element);
|
||||
tagNameTable.Subtract(TagNameKey(element), element);
|
||||
}
|
||||
|
||||
const char* LogStatistics::UidToName(uid_t uid) const {
|
||||
|
@ -283,8 +283,8 @@ const char* LogStatistics::UidToNameLocked(uid_t uid) const {
|
|||
++it) {
|
||||
const PidEntry& entry = it->second;
|
||||
|
||||
if (entry.getUid() == uid) {
|
||||
const char* nameTmp = entry.getName();
|
||||
if (entry.uid() == uid) {
|
||||
const char* nameTmp = entry.name();
|
||||
|
||||
if (nameTmp) {
|
||||
if (!name) {
|
||||
|
@ -314,8 +314,8 @@ void LogStatistics::WorstTwoWithThreshold(const LogHashtable<TKey, TEntry>& tabl
|
|||
*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();
|
||||
if (*worst_sizes > threshold && *worst_sizes > (10 * max_entries[0]->dropped_count())) {
|
||||
*worst = max_entries[0]->key();
|
||||
*second_worst_sizes = max_entries[1]->getSizes();
|
||||
if (*second_worst_sizes < threshold) {
|
||||
*second_worst_sizes = threshold;
|
||||
|
@ -344,7 +344,7 @@ void LogStatistics::WorstTwoSystemPids(log_id id, size_t worst_uid_sizes, int* w
|
|||
return;
|
||||
}
|
||||
|
||||
*worst = max_entries[0]->getKey();
|
||||
*worst = max_entries[0]->key();
|
||||
*second_worst_sizes = worst_uid_sizes - max_entries[0]->getSizes() + max_entries[1]->getSizes();
|
||||
}
|
||||
|
||||
|
@ -393,9 +393,8 @@ void LogStatistics::FormatTmp(const char* nameTmp, uid_t uid, std::string& name,
|
|||
if (!nameTmp) nameTmp = allocNameTmp = UidToNameLocked(uid);
|
||||
if (nameTmp) {
|
||||
size_t lenSpace = std::max(nameLen - name.length(), (size_t)1);
|
||||
size_t len = EntryBaseConstants::total_len -
|
||||
EntryBaseConstants::pruned_len - size.length() -
|
||||
name.length() - lenSpace - 2;
|
||||
size_t len = EntryBase::TOTAL_LEN - EntryBase::PRUNED_LEN - size.length() - name.length() -
|
||||
lenSpace - 2;
|
||||
size_t lenNameTmp = strlen(nameTmp);
|
||||
while ((len < lenNameTmp) && (lenSpace > 1)) {
|
||||
++len;
|
||||
|
@ -412,11 +411,10 @@ void LogStatistics::FormatTmp(const char* nameTmp, uid_t uid, std::string& name,
|
|||
}
|
||||
|
||||
std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const REQUIRES(stat.lock_) {
|
||||
uid_t uid = getUid();
|
||||
std::string name = android::base::StringPrintf("%u", uid);
|
||||
std::string name = android::base::StringPrintf("%u", uid_);
|
||||
std::string size = android::base::StringPrintf("%zu", getSizes());
|
||||
|
||||
stat.FormatTmp(nullptr, uid, name, size, 6);
|
||||
stat.FormatTmp(nullptr, uid_, name, size, 6);
|
||||
|
||||
std::string pruned = "";
|
||||
if (worstUidEnabledForLogid(id)) {
|
||||
|
@ -424,7 +422,7 @@ std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const REQUI
|
|||
for (LogStatistics::uidTable_t::const_iterator it =
|
||||
stat.uidTable[id].begin();
|
||||
it != stat.uidTable[id].end(); ++it) {
|
||||
totalDropped += it->second.getDropped();
|
||||
totalDropped += it->second.dropped_count();
|
||||
}
|
||||
size_t sizes = stat.mSizes[id];
|
||||
size_t totalSize = stat.mSizesTotal[id];
|
||||
|
@ -434,7 +432,7 @@ std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const REQUI
|
|||
size_t entrySize = getSizes();
|
||||
float virtualEntrySize = entrySize;
|
||||
int realPermille = virtualEntrySize * 1000.0 / sizes;
|
||||
size_t dropped = getDropped();
|
||||
size_t dropped = dropped_count();
|
||||
if (dropped) {
|
||||
pruned = android::base::StringPrintf("%zu", dropped);
|
||||
virtualEntrySize += (float)dropped * totalSize / totalElements;
|
||||
|
@ -461,8 +459,7 @@ std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const REQUI
|
|||
change = android::base::StringPrintf(
|
||||
"%s%d%s", prefix, (permille + 5) / 10, units);
|
||||
}
|
||||
ssize_t spaces = EntryBaseConstants::pruned_len - 2 -
|
||||
pruned.length() - change.length();
|
||||
ssize_t spaces = EntryBase::PRUNED_LEN - 2 - pruned.length() - change.length();
|
||||
if ((spaces <= 0) && pruned.length()) {
|
||||
spaces = 1;
|
||||
}
|
||||
|
@ -475,13 +472,13 @@ std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const REQUI
|
|||
|
||||
std::string output = formatLine(name, size, pruned);
|
||||
|
||||
if (uid != AID_SYSTEM) {
|
||||
if (uid_ != AID_SYSTEM) {
|
||||
return output;
|
||||
}
|
||||
|
||||
static const size_t maximum_sorted_entries = 32;
|
||||
std::array<const PidEntry*, maximum_sorted_entries> sorted;
|
||||
stat.pidSystemTable[id].MaxEntries(uid, 0, &sorted);
|
||||
stat.pidSystemTable[id].MaxEntries(uid_, 0, &sorted);
|
||||
|
||||
std::string byPid;
|
||||
size_t index;
|
||||
|
@ -494,7 +491,7 @@ std::string UidEntry::format(const LogStatistics& stat, log_id_t id) const REQUI
|
|||
if (entry->getSizes() <= (getSizes() / 100)) {
|
||||
break;
|
||||
}
|
||||
if (entry->getDropped()) {
|
||||
if (entry->dropped_count()) {
|
||||
hasDropped = true;
|
||||
}
|
||||
byPid += entry->format(stat, id);
|
||||
|
@ -518,15 +515,13 @@ std::string PidEntry::formatHeader(const std::string& name,
|
|||
|
||||
std::string PidEntry::format(const LogStatistics& stat, log_id_t /* id */) const
|
||||
REQUIRES(stat.lock_) {
|
||||
uid_t uid = getUid();
|
||||
pid_t pid = getPid();
|
||||
std::string name = android::base::StringPrintf("%5u/%u", pid, uid);
|
||||
std::string name = android::base::StringPrintf("%5u/%u", pid_, uid_);
|
||||
std::string size = android::base::StringPrintf("%zu", getSizes());
|
||||
|
||||
stat.FormatTmp(getName(), uid, name, size, 12);
|
||||
stat.FormatTmp(name_, uid_, name, size, 12);
|
||||
|
||||
std::string pruned = "";
|
||||
size_t dropped = getDropped();
|
||||
size_t dropped = dropped_count();
|
||||
if (dropped) {
|
||||
pruned = android::base::StringPrintf("%zu", dropped);
|
||||
}
|
||||
|
@ -543,14 +538,13 @@ std::string TidEntry::formatHeader(const std::string& name,
|
|||
|
||||
std::string TidEntry::format(const LogStatistics& stat, log_id_t /* id */) const
|
||||
REQUIRES(stat.lock_) {
|
||||
uid_t uid = getUid();
|
||||
std::string name = android::base::StringPrintf("%5u/%u", getTid(), uid);
|
||||
std::string name = android::base::StringPrintf("%5u/%u", tid(), uid_);
|
||||
std::string size = android::base::StringPrintf("%zu", getSizes());
|
||||
|
||||
stat.FormatTmp(getName(), uid, name, size, 12);
|
||||
stat.FormatTmp(name_, uid_, name, size, 12);
|
||||
|
||||
std::string pruned = "";
|
||||
size_t dropped = getDropped();
|
||||
size_t dropped = dropped_count();
|
||||
if (dropped) {
|
||||
pruned = android::base::StringPrintf("%zu", dropped);
|
||||
}
|
||||
|
@ -569,13 +563,12 @@ std::string TagEntry::formatHeader(const std::string& name, log_id_t id) const {
|
|||
std::string TagEntry::format(const LogStatistics& /* stat */,
|
||||
log_id_t /* id */) const {
|
||||
std::string name;
|
||||
uid_t uid = getUid();
|
||||
if (uid == (uid_t)-1) {
|
||||
name = android::base::StringPrintf("%7u", getKey());
|
||||
if (uid_ == (uid_t)-1) {
|
||||
name = android::base::StringPrintf("%7u", key());
|
||||
} else {
|
||||
name = android::base::StringPrintf("%7u/%u", getKey(), uid);
|
||||
name = android::base::StringPrintf("%7u/%u", key(), uid_);
|
||||
}
|
||||
const char* nameTmp = getName();
|
||||
const char* nameTmp = this->name();
|
||||
if (nameTmp) {
|
||||
name += android::base::StringPrintf(
|
||||
"%*s%s", (int)std::max(14 - name.length(), (size_t)1), "", nameTmp);
|
||||
|
@ -584,7 +577,7 @@ std::string TagEntry::format(const LogStatistics& /* stat */,
|
|||
std::string size = android::base::StringPrintf("%zu", getSizes());
|
||||
|
||||
std::string pruned = "";
|
||||
size_t dropped = getDropped();
|
||||
size_t dropped = dropped_count();
|
||||
if (dropped) {
|
||||
pruned = android::base::StringPrintf("%zu", dropped);
|
||||
}
|
||||
|
@ -602,34 +595,30 @@ std::string TagNameEntry::formatHeader(const std::string& name,
|
|||
std::string TagNameEntry::format(const LogStatistics& /* stat */,
|
||||
log_id_t /* id */) const {
|
||||
std::string name;
|
||||
pid_t tid = getTid();
|
||||
pid_t pid = getPid();
|
||||
std::string pidstr;
|
||||
if (pid != (pid_t)-1) {
|
||||
pidstr = android::base::StringPrintf("%u", pid);
|
||||
if ((tid != (pid_t)-1) && (tid != pid)) pidstr = "/" + pidstr;
|
||||
if (pid_ != (pid_t)-1) {
|
||||
pidstr = android::base::StringPrintf("%u", pid_);
|
||||
if (tid_ != (pid_t)-1 && tid_ != pid_) pidstr = "/" + pidstr;
|
||||
}
|
||||
int len = 9 - pidstr.length();
|
||||
if (len < 0) len = 0;
|
||||
if ((tid == (pid_t)-1) || (tid == pid)) {
|
||||
if (tid_ == (pid_t)-1 || tid_ == pid_) {
|
||||
name = android::base::StringPrintf("%*s", len, "");
|
||||
} else {
|
||||
name = android::base::StringPrintf("%*u", len, tid);
|
||||
name = android::base::StringPrintf("%*u", len, tid_);
|
||||
}
|
||||
name += pidstr;
|
||||
uid_t uid = getUid();
|
||||
if (uid != (uid_t)-1) {
|
||||
name += android::base::StringPrintf("/%u", uid);
|
||||
if (uid_ != (uid_t)-1) {
|
||||
name += android::base::StringPrintf("/%u", uid_);
|
||||
}
|
||||
|
||||
std::string size = android::base::StringPrintf("%zu", getSizes());
|
||||
|
||||
const char* nameTmp = getName();
|
||||
const char* nameTmp = this->name();
|
||||
if (nameTmp) {
|
||||
size_t lenSpace = std::max(16 - name.length(), (size_t)1);
|
||||
size_t len = EntryBaseConstants::total_len -
|
||||
EntryBaseConstants::pruned_len - size.length() -
|
||||
name.length() - lenSpace - 2;
|
||||
size_t len = EntryBase::TOTAL_LEN - EntryBase::PRUNED_LEN - size.length() - name.length() -
|
||||
lenSpace - 2;
|
||||
size_t lenNameTmp = strlen(nameTmp);
|
||||
while ((len < lenNameTmp) && (lenSpace > 1)) {
|
||||
++len;
|
||||
|
@ -944,7 +933,7 @@ uid_t pidToUid(pid_t pid) {
|
|||
|
||||
uid_t LogStatistics::PidToUid(pid_t pid) {
|
||||
auto lock = std::lock_guard{lock_};
|
||||
return pidTable.add(pid)->second.getUid();
|
||||
return pidTable.Add(pid)->second.uid();
|
||||
}
|
||||
|
||||
// caller must free character string
|
||||
|
@ -952,7 +941,7 @@ const char* LogStatistics::PidToName(pid_t pid) const {
|
|||
auto lock = std::lock_guard{lock_};
|
||||
// An inconvenient truth ... getName() can alter the object
|
||||
pidTable_t& writablePidTable = const_cast<pidTable_t&>(pidTable);
|
||||
const char* name = writablePidTable.add(pid)->second.getName();
|
||||
const char* name = writablePidTable.Add(pid)->second.name();
|
||||
if (!name) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ class LogHashtable {
|
|||
static const size_t unordered_map_per_entry_overhead = sizeof(void*);
|
||||
static const size_t unordered_map_bucket_overhead = sizeof(void*);
|
||||
|
||||
public:
|
||||
public:
|
||||
size_t size() const {
|
||||
return map.size();
|
||||
}
|
||||
|
@ -90,10 +90,10 @@ class LogHashtable {
|
|||
for (const_iterator it = map.begin(); it != map.end(); ++it) {
|
||||
const TEntry& entry = it->second;
|
||||
|
||||
if ((uid != AID_ROOT) && (uid != entry.getUid())) {
|
||||
if (uid != AID_ROOT && uid != entry.uid()) {
|
||||
continue;
|
||||
}
|
||||
if (pid && entry.getPid() && (pid != entry.getPid())) {
|
||||
if (pid && entry.pid() && pid != entry.pid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -113,95 +113,67 @@ class LogHashtable {
|
|||
}
|
||||
}
|
||||
|
||||
inline iterator add(const TKey& key, const LogBufferElement* element) {
|
||||
iterator Add(const TKey& key, const LogBufferElement& element) {
|
||||
iterator it = map.find(key);
|
||||
if (it == map.end()) {
|
||||
it = map.insert(std::make_pair(key, TEntry(element))).first;
|
||||
} else {
|
||||
it->second.add(element);
|
||||
it->second.Add(element);
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
inline iterator add(TKey key) {
|
||||
iterator Add(const TKey& key) {
|
||||
iterator it = map.find(key);
|
||||
if (it == map.end()) {
|
||||
it = map.insert(std::make_pair(key, TEntry(key))).first;
|
||||
} else {
|
||||
it->second.add(key);
|
||||
it->second.Add(key);
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
void subtract(TKey&& key, const LogBufferElement* element) {
|
||||
iterator it = map.find(std::move(key));
|
||||
if ((it != map.end()) && it->second.subtract(element)) {
|
||||
map.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void subtract(const TKey& key, const LogBufferElement* element) {
|
||||
void Subtract(const TKey& key, const LogBufferElement& element) {
|
||||
iterator it = map.find(key);
|
||||
if ((it != map.end()) && it->second.subtract(element)) {
|
||||
if (it != map.end() && it->second.Subtract(element)) {
|
||||
map.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
inline void drop(TKey key, const LogBufferElement* element) {
|
||||
void Drop(const TKey& key, const LogBufferElement& element) {
|
||||
iterator it = map.find(key);
|
||||
if (it != map.end()) {
|
||||
it->second.drop(element);
|
||||
it->second.Drop(element);
|
||||
}
|
||||
}
|
||||
|
||||
inline iterator begin() {
|
||||
return map.begin();
|
||||
}
|
||||
inline const_iterator begin() const {
|
||||
return map.begin();
|
||||
}
|
||||
inline iterator end() {
|
||||
return map.end();
|
||||
}
|
||||
inline const_iterator end() const {
|
||||
return map.end();
|
||||
}
|
||||
iterator begin() { return map.begin(); }
|
||||
const_iterator begin() const { return map.begin(); }
|
||||
iterator end() { return map.end(); }
|
||||
const_iterator end() const { return map.end(); }
|
||||
};
|
||||
|
||||
namespace EntryBaseConstants {
|
||||
static constexpr size_t pruned_len = 14;
|
||||
static constexpr size_t total_len = 80;
|
||||
}
|
||||
class EntryBase {
|
||||
public:
|
||||
EntryBase() : size_(0) {}
|
||||
explicit EntryBase(const LogBufferElement& element) : size_(element.msg_len()) {}
|
||||
|
||||
struct EntryBase {
|
||||
size_t size;
|
||||
size_t getSizes() const { return size_; }
|
||||
|
||||
EntryBase() : size(0) {
|
||||
}
|
||||
explicit EntryBase(const LogBufferElement* element)
|
||||
: size(element->getMsgLen()) {
|
||||
void Add(const LogBufferElement& element) { size_ += element.msg_len(); }
|
||||
bool Subtract(const LogBufferElement& element) {
|
||||
size_ -= element.msg_len();
|
||||
return !size_;
|
||||
}
|
||||
|
||||
size_t getSizes() const {
|
||||
return size;
|
||||
}
|
||||
|
||||
inline void add(const LogBufferElement* element) {
|
||||
size += element->getMsgLen();
|
||||
}
|
||||
inline bool subtract(const LogBufferElement* element) {
|
||||
size -= element->getMsgLen();
|
||||
return !size;
|
||||
}
|
||||
static constexpr size_t PRUNED_LEN = 14;
|
||||
static constexpr size_t TOTAL_LEN = 80;
|
||||
|
||||
static std::string formatLine(const std::string& name,
|
||||
const std::string& size,
|
||||
const std::string& pruned) {
|
||||
ssize_t drop_len =
|
||||
std::max(pruned.length() + 1, EntryBaseConstants::pruned_len);
|
||||
ssize_t size_len =
|
||||
std::max(size.length() + 1, EntryBaseConstants::total_len -
|
||||
name.length() - drop_len - 1);
|
||||
ssize_t drop_len = std::max(pruned.length() + 1, PRUNED_LEN);
|
||||
ssize_t size_len = std::max(size.length() + 1, TOTAL_LEN - name.length() - drop_len - 1);
|
||||
|
||||
std::string ret = android::base::StringPrintf(
|
||||
"%s%*s%*s", name.c_str(), (int)size_len, size.c_str(),
|
||||
|
@ -213,258 +185,220 @@ struct EntryBase {
|
|||
if (len) ret.erase(pos + 1, len);
|
||||
return ret + "\n";
|
||||
}
|
||||
|
||||
private:
|
||||
size_t size_;
|
||||
};
|
||||
|
||||
struct EntryBaseDropped : public EntryBase {
|
||||
size_t dropped;
|
||||
class EntryBaseDropped : public EntryBase {
|
||||
public:
|
||||
EntryBaseDropped() : dropped_(0) {}
|
||||
explicit EntryBaseDropped(const LogBufferElement& element)
|
||||
: EntryBase(element), dropped_(element.dropped_count()) {}
|
||||
|
||||
EntryBaseDropped() : dropped(0) {
|
||||
size_t dropped_count() const { return dropped_; }
|
||||
|
||||
void Add(const LogBufferElement& element) {
|
||||
dropped_ += element.dropped_count();
|
||||
EntryBase::Add(element);
|
||||
}
|
||||
explicit EntryBaseDropped(const LogBufferElement* element)
|
||||
: EntryBase(element), dropped(element->getDropped()) {
|
||||
bool Subtract(const LogBufferElement& element) {
|
||||
dropped_ -= element.dropped_count();
|
||||
return EntryBase::Subtract(element) && !dropped_;
|
||||
}
|
||||
void Drop(const LogBufferElement& element) {
|
||||
dropped_ += 1;
|
||||
EntryBase::Subtract(element);
|
||||
}
|
||||
|
||||
size_t getDropped() const {
|
||||
return dropped;
|
||||
}
|
||||
|
||||
inline void add(const LogBufferElement* element) {
|
||||
dropped += element->getDropped();
|
||||
EntryBase::add(element);
|
||||
}
|
||||
inline bool subtract(const LogBufferElement* element) {
|
||||
dropped -= element->getDropped();
|
||||
return EntryBase::subtract(element) && !dropped;
|
||||
}
|
||||
inline void drop(const LogBufferElement* element) {
|
||||
dropped += 1;
|
||||
EntryBase::subtract(element);
|
||||
}
|
||||
private:
|
||||
size_t dropped_;
|
||||
};
|
||||
|
||||
struct UidEntry : public EntryBaseDropped {
|
||||
const uid_t uid;
|
||||
pid_t pid;
|
||||
class UidEntry : public EntryBaseDropped {
|
||||
public:
|
||||
explicit UidEntry(const LogBufferElement& element)
|
||||
: EntryBaseDropped(element), uid_(element.uid()), pid_(element.pid()) {}
|
||||
|
||||
explicit UidEntry(const LogBufferElement* element)
|
||||
: EntryBaseDropped(element),
|
||||
uid(element->getUid()),
|
||||
pid(element->getPid()) {
|
||||
}
|
||||
uid_t key() const { return uid_; }
|
||||
uid_t uid() const { return key(); }
|
||||
pid_t pid() const { return pid_; }
|
||||
|
||||
inline const uid_t& getKey() const {
|
||||
return uid;
|
||||
}
|
||||
inline const uid_t& getUid() const {
|
||||
return getKey();
|
||||
}
|
||||
inline const pid_t& getPid() const {
|
||||
return pid;
|
||||
}
|
||||
|
||||
inline void add(const LogBufferElement* element) {
|
||||
if (pid != element->getPid()) {
|
||||
pid = -1;
|
||||
void Add(const LogBufferElement& element) {
|
||||
if (pid_ != element.pid()) {
|
||||
pid_ = -1;
|
||||
}
|
||||
EntryBaseDropped::add(element);
|
||||
EntryBaseDropped::Add(element);
|
||||
}
|
||||
|
||||
std::string formatHeader(const std::string& name, log_id_t id) const;
|
||||
std::string format(const LogStatistics& stat, log_id_t id) const;
|
||||
|
||||
private:
|
||||
const uid_t uid_;
|
||||
pid_t pid_;
|
||||
};
|
||||
|
||||
namespace android {
|
||||
uid_t pidToUid(pid_t pid);
|
||||
}
|
||||
|
||||
struct PidEntry : public EntryBaseDropped {
|
||||
const pid_t pid;
|
||||
uid_t uid;
|
||||
char* name;
|
||||
|
||||
class PidEntry : public EntryBaseDropped {
|
||||
public:
|
||||
explicit PidEntry(pid_t pid)
|
||||
: EntryBaseDropped(),
|
||||
pid(pid),
|
||||
uid(android::pidToUid(pid)),
|
||||
name(android::pidToName(pid)) {
|
||||
}
|
||||
explicit PidEntry(const LogBufferElement* element)
|
||||
pid_(pid),
|
||||
uid_(android::pidToUid(pid)),
|
||||
name_(android::pidToName(pid)) {}
|
||||
explicit PidEntry(const LogBufferElement& element)
|
||||
: EntryBaseDropped(element),
|
||||
pid(element->getPid()),
|
||||
uid(element->getUid()),
|
||||
name(android::pidToName(pid)) {
|
||||
}
|
||||
pid_(element.pid()),
|
||||
uid_(element.uid()),
|
||||
name_(android::pidToName(pid_)) {}
|
||||
PidEntry(const PidEntry& element)
|
||||
: EntryBaseDropped(element),
|
||||
pid(element.pid),
|
||||
uid(element.uid),
|
||||
name(element.name ? strdup(element.name) : nullptr) {
|
||||
}
|
||||
~PidEntry() {
|
||||
free(name);
|
||||
}
|
||||
pid_(element.pid_),
|
||||
uid_(element.uid_),
|
||||
name_(element.name_ ? strdup(element.name_) : nullptr) {}
|
||||
~PidEntry() { free(name_); }
|
||||
|
||||
const pid_t& getKey() const {
|
||||
return pid;
|
||||
}
|
||||
const pid_t& getPid() const {
|
||||
return getKey();
|
||||
}
|
||||
const uid_t& getUid() const {
|
||||
return uid;
|
||||
}
|
||||
const char* getName() const {
|
||||
return name;
|
||||
}
|
||||
pid_t key() const { return pid_; }
|
||||
pid_t pid() const { return key(); }
|
||||
uid_t uid() const { return uid_; }
|
||||
const char* name() const { return name_; }
|
||||
|
||||
inline void add(pid_t newPid) {
|
||||
if (name && !fastcmp<strncmp>(name, "zygote", 6)) {
|
||||
free(name);
|
||||
name = nullptr;
|
||||
void Add(pid_t new_pid) {
|
||||
if (name_ && !fastcmp<strncmp>(name_, "zygote", 6)) {
|
||||
free(name_);
|
||||
name_ = nullptr;
|
||||
}
|
||||
if (!name) {
|
||||
name = android::pidToName(newPid);
|
||||
if (!name_) {
|
||||
name_ = android::pidToName(new_pid);
|
||||
}
|
||||
}
|
||||
|
||||
inline void add(const LogBufferElement* element) {
|
||||
uid_t incomingUid = element->getUid();
|
||||
if (getUid() != incomingUid) {
|
||||
uid = incomingUid;
|
||||
free(name);
|
||||
name = android::pidToName(element->getPid());
|
||||
void Add(const LogBufferElement& element) {
|
||||
uid_t incoming_uid = element.uid();
|
||||
if (uid() != incoming_uid) {
|
||||
uid_ = incoming_uid;
|
||||
free(name_);
|
||||
name_ = android::pidToName(element.pid());
|
||||
} else {
|
||||
add(element->getPid());
|
||||
Add(element.pid());
|
||||
}
|
||||
EntryBaseDropped::add(element);
|
||||
EntryBaseDropped::Add(element);
|
||||
}
|
||||
|
||||
std::string formatHeader(const std::string& name, log_id_t id) const;
|
||||
std::string format(const LogStatistics& stat, log_id_t id) const;
|
||||
|
||||
private:
|
||||
const pid_t pid_;
|
||||
uid_t uid_;
|
||||
char* name_;
|
||||
};
|
||||
|
||||
struct TidEntry : public EntryBaseDropped {
|
||||
const pid_t tid;
|
||||
pid_t pid;
|
||||
uid_t uid;
|
||||
char* name;
|
||||
|
||||
class TidEntry : public EntryBaseDropped {
|
||||
public:
|
||||
TidEntry(pid_t tid, pid_t pid)
|
||||
: EntryBaseDropped(),
|
||||
tid(tid),
|
||||
pid(pid),
|
||||
uid(android::pidToUid(tid)),
|
||||
name(android::tidToName(tid)) {
|
||||
}
|
||||
explicit TidEntry(const LogBufferElement* element)
|
||||
tid_(tid),
|
||||
pid_(pid),
|
||||
uid_(android::pidToUid(tid)),
|
||||
name_(android::tidToName(tid)) {}
|
||||
explicit TidEntry(const LogBufferElement& element)
|
||||
: EntryBaseDropped(element),
|
||||
tid(element->getTid()),
|
||||
pid(element->getPid()),
|
||||
uid(element->getUid()),
|
||||
name(android::tidToName(tid)) {
|
||||
}
|
||||
tid_(element.tid()),
|
||||
pid_(element.pid()),
|
||||
uid_(element.uid()),
|
||||
name_(android::tidToName(tid_)) {}
|
||||
TidEntry(const TidEntry& element)
|
||||
: EntryBaseDropped(element),
|
||||
tid(element.tid),
|
||||
pid(element.pid),
|
||||
uid(element.uid),
|
||||
name(element.name ? strdup(element.name) : nullptr) {
|
||||
}
|
||||
~TidEntry() {
|
||||
free(name);
|
||||
}
|
||||
tid_(element.tid_),
|
||||
pid_(element.pid_),
|
||||
uid_(element.uid_),
|
||||
name_(element.name_ ? strdup(element.name_) : nullptr) {}
|
||||
~TidEntry() { free(name_); }
|
||||
|
||||
const pid_t& getKey() const {
|
||||
return tid;
|
||||
}
|
||||
const pid_t& getTid() const {
|
||||
return getKey();
|
||||
}
|
||||
const pid_t& getPid() const {
|
||||
return pid;
|
||||
}
|
||||
const uid_t& getUid() const {
|
||||
return uid;
|
||||
}
|
||||
const char* getName() const {
|
||||
return name;
|
||||
}
|
||||
pid_t key() const { return tid_; }
|
||||
pid_t tid() const { return key(); }
|
||||
pid_t pid() const { return pid_; }
|
||||
uid_t uid() const { return uid_; }
|
||||
const char* name() const { return name_; }
|
||||
|
||||
inline void add(pid_t incomingTid) {
|
||||
if (name && !fastcmp<strncmp>(name, "zygote", 6)) {
|
||||
free(name);
|
||||
name = nullptr;
|
||||
void Add(pid_t incomingTid) {
|
||||
if (name_ && !fastcmp<strncmp>(name_, "zygote", 6)) {
|
||||
free(name_);
|
||||
name_ = nullptr;
|
||||
}
|
||||
if (!name) {
|
||||
name = android::tidToName(incomingTid);
|
||||
if (!name_) {
|
||||
name_ = android::tidToName(incomingTid);
|
||||
}
|
||||
}
|
||||
|
||||
inline void add(const LogBufferElement* element) {
|
||||
uid_t incomingUid = element->getUid();
|
||||
pid_t incomingPid = element->getPid();
|
||||
if ((getUid() != incomingUid) || (getPid() != incomingPid)) {
|
||||
uid = incomingUid;
|
||||
pid = incomingPid;
|
||||
free(name);
|
||||
name = android::tidToName(element->getTid());
|
||||
void Add(const LogBufferElement& element) {
|
||||
uid_t incoming_uid = element.uid();
|
||||
pid_t incoming_pid = element.pid();
|
||||
if (uid() != incoming_uid || pid() != incoming_pid) {
|
||||
uid_ = incoming_uid;
|
||||
pid_ = incoming_pid;
|
||||
free(name_);
|
||||
name_ = android::tidToName(element.tid());
|
||||
} else {
|
||||
add(element->getTid());
|
||||
Add(element.tid());
|
||||
}
|
||||
EntryBaseDropped::add(element);
|
||||
EntryBaseDropped::Add(element);
|
||||
}
|
||||
|
||||
std::string formatHeader(const std::string& name, log_id_t id) const;
|
||||
std::string format(const LogStatistics& stat, log_id_t id) const;
|
||||
|
||||
private:
|
||||
const pid_t tid_;
|
||||
pid_t pid_;
|
||||
uid_t uid_;
|
||||
char* name_;
|
||||
};
|
||||
|
||||
struct TagEntry : public EntryBaseDropped {
|
||||
const uint32_t tag;
|
||||
pid_t pid;
|
||||
uid_t uid;
|
||||
|
||||
explicit TagEntry(const LogBufferElement* element)
|
||||
class TagEntry : public EntryBaseDropped {
|
||||
public:
|
||||
explicit TagEntry(const LogBufferElement& element)
|
||||
: EntryBaseDropped(element),
|
||||
tag(element->getTag()),
|
||||
pid(element->getPid()),
|
||||
uid(element->getUid()) {
|
||||
}
|
||||
tag_(element.GetTag()),
|
||||
pid_(element.pid()),
|
||||
uid_(element.uid()) {}
|
||||
|
||||
const uint32_t& getKey() const {
|
||||
return tag;
|
||||
}
|
||||
const pid_t& getPid() const {
|
||||
return pid;
|
||||
}
|
||||
const uid_t& getUid() const {
|
||||
return uid;
|
||||
}
|
||||
const char* getName() const {
|
||||
return android::tagToName(tag);
|
||||
}
|
||||
uint32_t key() const { return tag_; }
|
||||
pid_t pid() const { return pid_; }
|
||||
uid_t uid() const { return uid_; }
|
||||
const char* name() const { return android::tagToName(tag_); }
|
||||
|
||||
inline void add(const LogBufferElement* element) {
|
||||
if (uid != element->getUid()) {
|
||||
uid = -1;
|
||||
void Add(const LogBufferElement& element) {
|
||||
if (uid_ != element.uid()) {
|
||||
uid_ = -1;
|
||||
}
|
||||
if (pid != element->getPid()) {
|
||||
pid = -1;
|
||||
if (pid_ != element.pid()) {
|
||||
pid_ = -1;
|
||||
}
|
||||
EntryBaseDropped::add(element);
|
||||
EntryBaseDropped::Add(element);
|
||||
}
|
||||
|
||||
std::string formatHeader(const std::string& name, log_id_t id) const;
|
||||
std::string format(const LogStatistics& stat, log_id_t id) const;
|
||||
|
||||
private:
|
||||
const uint32_t tag_;
|
||||
pid_t pid_;
|
||||
uid_t uid_;
|
||||
};
|
||||
|
||||
struct TagNameKey {
|
||||
std::string* alloc;
|
||||
std::string_view name; // Saves space if const char*
|
||||
|
||||
explicit TagNameKey(const LogBufferElement* element)
|
||||
: alloc(nullptr), name("", strlen("")) {
|
||||
if (element->isBinary()) {
|
||||
uint32_t tag = element->getTag();
|
||||
explicit TagNameKey(const LogBufferElement& element) : alloc(nullptr), name("", strlen("")) {
|
||||
if (element.IsBinary()) {
|
||||
uint32_t tag = element.GetTag();
|
||||
if (tag) {
|
||||
const char* cp = android::tagToName(tag);
|
||||
if (cp) {
|
||||
|
@ -478,13 +412,13 @@ struct TagNameKey {
|
|||
name = std::string_view(alloc->c_str(), alloc->size());
|
||||
return;
|
||||
}
|
||||
const char* msg = element->getMsg();
|
||||
const char* msg = element.msg();
|
||||
if (!msg) {
|
||||
name = std::string_view("chatty", strlen("chatty"));
|
||||
return;
|
||||
}
|
||||
++msg;
|
||||
uint16_t len = element->getMsgLen();
|
||||
uint16_t len = element.msg_len();
|
||||
len = (len <= 1) ? 0 : strnlen(msg, len - 1);
|
||||
if (!len) {
|
||||
name = std::string_view("<NULL>", strlen("<NULL>"));
|
||||
|
@ -544,54 +478,43 @@ struct std::hash<TagNameKey>
|
|||
}
|
||||
};
|
||||
|
||||
struct TagNameEntry : public EntryBase {
|
||||
pid_t tid;
|
||||
pid_t pid;
|
||||
uid_t uid;
|
||||
TagNameKey name;
|
||||
|
||||
explicit TagNameEntry(const LogBufferElement* element)
|
||||
class TagNameEntry : public EntryBase {
|
||||
public:
|
||||
explicit TagNameEntry(const LogBufferElement& element)
|
||||
: EntryBase(element),
|
||||
tid(element->getTid()),
|
||||
pid(element->getPid()),
|
||||
uid(element->getUid()),
|
||||
name(element) {
|
||||
}
|
||||
tid_(element.tid()),
|
||||
pid_(element.pid()),
|
||||
uid_(element.uid()),
|
||||
name_(element) {}
|
||||
|
||||
const TagNameKey& getKey() const {
|
||||
return name;
|
||||
}
|
||||
const pid_t& getTid() const {
|
||||
return tid;
|
||||
}
|
||||
const pid_t& getPid() const {
|
||||
return pid;
|
||||
}
|
||||
const uid_t& getUid() const {
|
||||
return uid;
|
||||
}
|
||||
const char* getName() const {
|
||||
return name.data();
|
||||
}
|
||||
size_t getNameAllocLength() const {
|
||||
return name.getAllocLength();
|
||||
}
|
||||
const TagNameKey& key() const { return name_; }
|
||||
pid_t tid() const { return tid_; }
|
||||
pid_t pid() const { return pid_; }
|
||||
uid_t uid() const { return uid_; }
|
||||
const char* name() const { return name_.data(); }
|
||||
size_t getNameAllocLength() const { return name_.getAllocLength(); }
|
||||
|
||||
inline void add(const LogBufferElement* element) {
|
||||
if (uid != element->getUid()) {
|
||||
uid = -1;
|
||||
void Add(const LogBufferElement& element) {
|
||||
if (uid_ != element.uid()) {
|
||||
uid_ = -1;
|
||||
}
|
||||
if (pid != element->getPid()) {
|
||||
pid = -1;
|
||||
if (pid_ != element.pid()) {
|
||||
pid_ = -1;
|
||||
}
|
||||
if (tid != element->getTid()) {
|
||||
tid = -1;
|
||||
if (tid_ != element.tid()) {
|
||||
tid_ = -1;
|
||||
}
|
||||
EntryBase::add(element);
|
||||
EntryBase::Add(element);
|
||||
}
|
||||
|
||||
std::string formatHeader(const std::string& name, log_id_t id) const;
|
||||
std::string format(const LogStatistics& stat, log_id_t id) const;
|
||||
|
||||
private:
|
||||
pid_t tid_;
|
||||
pid_t pid_;
|
||||
uid_t uid_;
|
||||
TagNameKey name_;
|
||||
};
|
||||
|
||||
// Log Statistics
|
||||
|
@ -645,11 +568,11 @@ class LogStatistics {
|
|||
(pidTable.size() * sizeof(pidTable_t::iterator)) +
|
||||
(tagTable.size() * sizeof(tagTable_t::iterator));
|
||||
for (auto it : pidTable) {
|
||||
const char* name = it.second.getName();
|
||||
const char* name = it.second.name();
|
||||
if (name) size += strlen(name) + 1;
|
||||
}
|
||||
for (auto it : tidTable) {
|
||||
const char* name = it.second.getName();
|
||||
const char* name = it.second.name();
|
||||
if (name) size += strlen(name) + 1;
|
||||
}
|
||||
for (auto it : tagNameTable) size += it.second.getNameAllocLength();
|
||||
|
@ -667,14 +590,14 @@ class LogStatistics {
|
|||
LogStatistics(bool enable_statistics);
|
||||
|
||||
void AddTotal(log_id_t log_id, uint16_t size) EXCLUDES(lock_);
|
||||
void Add(LogBufferElement* entry) EXCLUDES(lock_);
|
||||
void Subtract(LogBufferElement* entry) EXCLUDES(lock_);
|
||||
void Add(const LogBufferElement& entry) EXCLUDES(lock_);
|
||||
void Subtract(const LogBufferElement& entry) EXCLUDES(lock_);
|
||||
// entry->setDropped(1) must follow this call
|
||||
void Drop(LogBufferElement* entry) EXCLUDES(lock_);
|
||||
void Drop(const LogBufferElement& entry) EXCLUDES(lock_);
|
||||
// Correct for coalescing two entries referencing dropped content
|
||||
void Erase(LogBufferElement* element) EXCLUDES(lock_) {
|
||||
void Erase(const LogBufferElement& element) EXCLUDES(lock_) {
|
||||
auto lock = std::lock_guard{lock_};
|
||||
log_id_t log_id = element->getLogId();
|
||||
log_id_t log_id = element.log_id();
|
||||
--mElements[log_id];
|
||||
--mDroppedElements[log_id];
|
||||
}
|
||||
|
|
|
@ -43,9 +43,7 @@ class Prune {
|
|||
return mPid;
|
||||
}
|
||||
|
||||
int cmp(LogBufferElement* e) const {
|
||||
return cmp(e->getUid(), e->getPid());
|
||||
}
|
||||
int cmp(LogBufferElement* e) const { return cmp(e->uid(), e->pid()); }
|
||||
|
||||
std::string format();
|
||||
};
|
||||
|
|
|
@ -44,7 +44,7 @@ std::list<LogBufferElement>::iterator SimpleLogBuffer::GetOldest(log_id_t log_id
|
|||
if (oldest_[log_id]) {
|
||||
it = *oldest_[log_id];
|
||||
}
|
||||
while (it != logs().end() && it->getLogId() != log_id) {
|
||||
while (it != logs().end() && it->log_id() != log_id) {
|
||||
it++;
|
||||
}
|
||||
if (it != logs().end()) {
|
||||
|
@ -102,10 +102,10 @@ int SimpleLogBuffer::Log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pi
|
|||
}
|
||||
|
||||
void SimpleLogBuffer::LogInternal(LogBufferElement&& elem) {
|
||||
log_id_t log_id = elem.getLogId();
|
||||
log_id_t log_id = elem.log_id();
|
||||
|
||||
logs_.emplace_back(std::move(elem));
|
||||
stats_->Add(&logs_.back());
|
||||
stats_->Add(logs_.back());
|
||||
MaybePrune(log_id);
|
||||
reader_list_->NotifyNewLog(1 << log_id);
|
||||
}
|
||||
|
@ -146,9 +146,9 @@ bool SimpleLogBuffer::FlushTo(
|
|||
for (it = logs_.end(); it != logs_.begin();
|
||||
/* do nothing */) {
|
||||
--it;
|
||||
if (it->getSequence() == state.start()) {
|
||||
if (it->sequence() == state.start()) {
|
||||
break;
|
||||
} else if (it->getSequence() < state.start()) {
|
||||
} else if (it->sequence() < state.start()) {
|
||||
it++;
|
||||
break;
|
||||
}
|
||||
|
@ -158,19 +158,19 @@ bool SimpleLogBuffer::FlushTo(
|
|||
for (; it != logs_.end(); ++it) {
|
||||
LogBufferElement& element = *it;
|
||||
|
||||
state.set_start(element.getSequence());
|
||||
state.set_start(element.sequence());
|
||||
|
||||
if (!writer->privileged() && element.getUid() != writer->uid()) {
|
||||
if (!writer->privileged() && element.uid() != writer->uid()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((1 << element.getLogId()) & state.log_mask()) == 0) {
|
||||
if (((1 << element.log_id()) & state.log_mask()) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (filter) {
|
||||
FilterResult ret = filter(element.getLogId(), element.getPid(), element.getSequence(),
|
||||
element.getRealTime(), element.getDropped());
|
||||
FilterResult ret = filter(element.log_id(), element.pid(), element.sequence(),
|
||||
element.realtime(), element.dropped_count());
|
||||
if (ret == FilterResult::kSkip) {
|
||||
continue;
|
||||
}
|
||||
|
@ -179,12 +179,12 @@ bool SimpleLogBuffer::FlushTo(
|
|||
}
|
||||
}
|
||||
|
||||
bool same_tid = state.last_tid()[element.getLogId()] == element.getTid();
|
||||
bool same_tid = state.last_tid()[element.log_id()] == element.tid();
|
||||
// Dropped (chatty) immediately following a valid log from the same source in the same log
|
||||
// buffer indicates we have a multiple identical squash. chatty that differs source is due
|
||||
// to spam filter. chatty to chatty of different source is also due to spam filter.
|
||||
state.last_tid()[element.getLogId()] =
|
||||
(element.getDropped() && !same_tid) ? 0 : element.getTid();
|
||||
state.last_tid()[element.log_id()] =
|
||||
(element.dropped_count() && !same_tid) ? 0 : element.tid();
|
||||
|
||||
shared_lock.unlock();
|
||||
// We never prune logs equal to or newer than any LogReaderThreads' `start` value, so the
|
||||
|
@ -288,22 +288,22 @@ bool SimpleLogBuffer::Prune(log_id_t id, unsigned long prune_rows, uid_t caller_
|
|||
while (it != logs_.end()) {
|
||||
LogBufferElement& element = *it;
|
||||
|
||||
if (element.getLogId() != id) {
|
||||
if (element.log_id() != id) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (caller_uid != 0 && element.getUid() != caller_uid) {
|
||||
if (caller_uid != 0 && element.uid() != caller_uid) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (oldest && oldest->start() <= element.getSequence()) {
|
||||
if (oldest && oldest->start() <= element.sequence()) {
|
||||
KickReader(oldest, id, prune_rows);
|
||||
return true;
|
||||
}
|
||||
|
||||
stats_->Subtract(&element);
|
||||
stats_->Subtract(element);
|
||||
it = Erase(it);
|
||||
if (--prune_rows == 0) {
|
||||
return false;
|
||||
|
|
Loading…
Reference in a new issue