Merge "logd: correctly label identical lines"

am: a9b5a5e96a

Change-Id: I0cd6ad498e46bbaa2c78ee8ad95b920b309edd90
This commit is contained in:
Mark Salyzyn 2017-04-03 14:25:15 +00:00 committed by android-build-merger
commit 41e44283d2
5 changed files with 48 additions and 41 deletions

View file

@ -109,11 +109,11 @@ void LogBuffer::init() {
LogBuffer::LogBuffer(LastLogTimes* times) LogBuffer::LogBuffer(LastLogTimes* times)
: monotonic(android_log_clockid() == CLOCK_MONOTONIC), mTimes(*times) { : monotonic(android_log_clockid() == CLOCK_MONOTONIC), mTimes(*times) {
pthread_mutex_init(&mLogElementsLock, NULL); pthread_mutex_init(&mLogElementsLock, nullptr);
log_id_for_each(i) { log_id_for_each(i) {
lastLoggedElements[i] = NULL; lastLoggedElements[i] = nullptr;
droppedElements[i] = NULL; droppedElements[i] = nullptr;
} }
init(); init();
@ -196,7 +196,7 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
new LogBufferElement(log_id, realtime, uid, pid, tid, msg, len); new LogBufferElement(log_id, realtime, uid, pid, tid, msg, len);
if (log_id != LOG_ID_SECURITY) { if (log_id != LOG_ID_SECURITY) {
int prio = ANDROID_LOG_INFO; int prio = ANDROID_LOG_INFO;
const char* tag = NULL; const char* tag = nullptr;
if (log_id == LOG_ID_EVENTS) { if (log_id == LOG_ID_EVENTS) {
tag = tagToName(elem->getTag()); tag = tagToName(elem->getTag());
} else { } else {
@ -222,24 +222,24 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
// //
// State Init // State Init
// incoming: // incoming:
// dropped = NULL // dropped = nullptr
// currentLast = NULL; // currentLast = nullptr;
// elem = incoming message // elem = incoming message
// outgoing: // outgoing:
// dropped = NULL -> State 0 // dropped = nullptr -> State 0
// currentLast = copy of elem // currentLast = copy of elem
// log elem // log elem
// State 0 // State 0
// incoming: // incoming:
// count = 0 // count = 0
// dropped = NULL // dropped = nullptr
// currentLast = copy of last message // currentLast = copy of last message
// elem = incoming message // elem = incoming message
// outgoing: if match != DIFFERENT // outgoing: if match != DIFFERENT
// dropped = copy of first identical message -> State 1 // dropped = copy of first identical message -> State 1
// currentLast = reference to elem // currentLast = reference to elem
// break: if match == DIFFERENT // break: if match == DIFFERENT
// dropped = NULL -> State 0 // dropped = nullptr -> State 0
// delete copy of last message (incoming currentLast) // delete copy of last message (incoming currentLast)
// currentLast = copy of elem // currentLast = copy of elem
// log elem // log elem
@ -266,7 +266,7 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
// currentLast = reference to elem, sum liblog. // currentLast = reference to elem, sum liblog.
// break: if match == DIFFERENT // break: if match == DIFFERENT
// delete dropped // delete dropped
// dropped = NULL -> State 0 // dropped = nullptr -> State 0
// log reference to last held-back (currentLast) // log reference to last held-back (currentLast)
// currentLast = copy of elem // currentLast = copy of elem
// log elem // log elem
@ -285,7 +285,7 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
// currentLast = reference to elem // currentLast = reference to elem
// break: if match == DIFFERENT // break: if match == DIFFERENT
// log dropped (chatty message) // log dropped (chatty message)
// dropped = NULL -> State 0 // dropped = nullptr -> State 0
// log reference to last held-back (currentLast) // log reference to last held-back (currentLast)
// currentLast = copy of elem // currentLast = copy of elem
// log elem // log elem
@ -350,7 +350,7 @@ int LogBuffer::log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid,
} else { // State 1 } else { // State 1
delete dropped; delete dropped;
} }
droppedElements[log_id] = NULL; droppedElements[log_id] = nullptr;
log(currentLast); // report last message in the series log(currentLast); // report last message in the series
} else { // State 0 } else { // State 0
delete currentLast; delete currentLast;
@ -654,7 +654,7 @@ class LogBufferElementLast {
// mLogElementsLock must be held when this function is called. // mLogElementsLock must be held when this function is called.
// //
bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) { bool LogBuffer::prune(log_id_t id, unsigned long pruneRows, uid_t caller_uid) {
LogTimeEntry* oldest = NULL; LogTimeEntry* oldest = nullptr;
bool busy = false; bool busy = false;
bool clearAll = pruneRows == ULONG_MAX; bool clearAll = pruneRows == ULONG_MAX;
@ -1076,9 +1076,11 @@ unsigned long LogBuffer::getSize(log_id_t id) {
return retval; return retval;
} }
log_time LogBuffer::flushTo( log_time LogBuffer::flushTo(SocketClient* reader, const log_time& start,
SocketClient* reader, const log_time& start, bool privileged, bool security, pid_t* lastTid, bool privileged, bool security,
int (*filter)(const LogBufferElement* element, void* arg), void* arg) { int (*filter)(const LogBufferElement* element,
void* arg),
void* arg) {
LogBufferElementCollection::iterator it; LogBufferElementCollection::iterator it;
uid_t uid = reader->getUid(); uid_t uid = reader->getUid();
@ -1107,9 +1109,6 @@ log_time LogBuffer::flushTo(
} }
log_time max = start; log_time max = start;
// Help detect if the valid message before is from the same source so
// we can differentiate chatty filter types.
pid_t lastTid[LOG_ID_MAX] = { 0 };
for (; it != mLogElements.end(); ++it) { for (; it != mLogElements.end(); ++it) {
LogBufferElement* element = *it; LogBufferElement* element = *it;
@ -1137,14 +1136,17 @@ log_time LogBuffer::flushTo(
} }
} }
bool sameTid = lastTid[element->getLogId()] == element->getTid(); bool sameTid = false;
// Dropped (chatty) immediately following a valid log from the if (lastTid) {
// same source in the same log buffer indicates we have a sameTid = lastTid[element->getLogId()] == element->getTid();
// multiple identical squash. chatty that differs source // Dropped (chatty) immediately following a valid log from the
// is due to spam filter. chatty to chatty of different // same source in the same log buffer indicates we have a
// source is also due to spam filter. // multiple identical squash. chatty that differs source
lastTid[element->getLogId()] = // is due to spam filter. chatty to chatty of different
(element->getDropped() && !sameTid) ? 0 : element->getTid(); // source is also due to spam filter.
lastTid[element->getLogId()] =
(element->getDropped() && !sameTid) ? 0 : element->getTid();
}
pthread_mutex_unlock(&mLogElementsLock); pthread_mutex_unlock(&mLogElementsLock);

View file

@ -115,11 +115,15 @@ class LogBuffer {
int log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid, int log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
const char* msg, unsigned short len); const char* msg, unsigned short len);
// lastTid is an optional context to help detect if the last previous
// valid message was from the same source so we can differentiate chatty
// filter types (identical or expired)
log_time flushTo(SocketClient* writer, const log_time& start, log_time flushTo(SocketClient* writer, const log_time& start,
pid_t* lastTid, // &lastTid[LOG_ID_MAX] or nullptr
bool privileged, bool security, bool privileged, bool security,
int (*filter)(const LogBufferElement* element, int (*filter)(const LogBufferElement* element,
void* arg) = NULL, void* arg) = nullptr,
void* arg = NULL); void* arg = nullptr);
bool clear(log_id_t id, uid_t uid = AID_ROOT); bool clear(log_id_t id, uid_t uid = AID_ROOT);
unsigned long getSize(log_id_t id); unsigned long getSize(log_id_t id);

View file

@ -182,7 +182,7 @@ bool LogReader::onDataAvailable(SocketClient* cli) {
} logFindStart(pid, logMask, sequence, } logFindStart(pid, logMask, sequence,
logbuf().isMonotonic() && android::isMonotonic(start)); logbuf().isMonotonic() && android::isMonotonic(start));
logbuf().flushTo(cli, sequence, FlushCommand::hasReadLogs(cli), logbuf().flushTo(cli, sequence, nullptr, FlushCommand::hasReadLogs(cli),
FlushCommand::hasSecurityLogs(cli), FlushCommand::hasSecurityLogs(cli),
logFindStart.callback, &logFindStart); logFindStart.callback, &logFindStart);

View file

@ -15,6 +15,7 @@
*/ */
#include <errno.h> #include <errno.h>
#include <string.h>
#include <sys/prctl.h> #include <sys/prctl.h>
#include <private/android_logger.h> #include <private/android_logger.h>
@ -47,7 +48,8 @@ LogTimeEntry::LogTimeEntry(LogReader& reader, SocketClient* client,
mEnd(log_time(android_log_clockid())) { mEnd(log_time(android_log_clockid())) {
mTimeout.tv_sec = timeout / NS_PER_SEC; mTimeout.tv_sec = timeout / NS_PER_SEC;
mTimeout.tv_nsec = timeout % NS_PER_SEC; mTimeout.tv_nsec = timeout % NS_PER_SEC;
pthread_cond_init(&threadTriggeredCondition, NULL); memset(mLastTid, 0, sizeof(mLastTid));
pthread_cond_init(&threadTriggeredCondition, nullptr);
cleanSkip_Locked(); cleanSkip_Locked();
} }
@ -98,7 +100,7 @@ void LogTimeEntry::threadStop(void* obj) {
it++; it++;
} }
me->mClient = NULL; me->mClient = nullptr;
reader.release(client); reader.release(client);
} }
@ -122,7 +124,7 @@ void* LogTimeEntry::threadStart(void* obj) {
SocketClient* client = me->mClient; SocketClient* client = me->mClient;
if (!client) { if (!client) {
me->error(); me->error();
return NULL; return nullptr;
} }
LogBuffer& logbuf = me->mReader.logbuf(); LogBuffer& logbuf = me->mReader.logbuf();
@ -151,12 +153,12 @@ void* LogTimeEntry::threadStart(void* obj) {
unlock(); unlock();
if (me->mTail) { if (me->mTail) {
logbuf.flushTo(client, start, privileged, security, FilterFirstPass, logbuf.flushTo(client, start, nullptr, privileged, security,
me); FilterFirstPass, me);
me->leadingDropped = true; me->leadingDropped = true;
} }
start = logbuf.flushTo(client, start, privileged, security, start = logbuf.flushTo(client, start, me->mLastTid, privileged,
FilterSecondPass, me); security, FilterSecondPass, me);
lock(); lock();
@ -182,7 +184,7 @@ void* LogTimeEntry::threadStart(void* obj) {
pthread_cleanup_pop(true); pthread_cleanup_pop(true);
return NULL; return nullptr;
} }
// A first pass to count the number of elements // A first pass to count the number of elements
@ -281,7 +283,5 @@ stop:
} }
void LogTimeEntry::cleanSkip_Locked(void) { void LogTimeEntry::cleanSkip_Locked(void) {
for (log_id_t i = LOG_ID_MIN; i < LOG_ID_MAX; i = (log_id_t)(i + 1)) { memset(skipAhead, 0, sizeof(skipAhead));
skipAhead[i] = 0;
}
} }

View file

@ -44,6 +44,7 @@ class LogTimeEntry {
const unsigned int mLogMask; const unsigned int mLogMask;
const pid_t mPid; const pid_t mPid;
unsigned int skipAhead[LOG_ID_MAX]; unsigned int skipAhead[LOG_ID_MAX];
pid_t mLastTid[LOG_ID_MAX];
unsigned long mCount; unsigned long mCount;
unsigned long mTail; unsigned long mTail;
unsigned long mIndex; unsigned long mIndex;