Merge "logd: correctly label identical lines"
am: a9b5a5e96a
Change-Id: I0cd6ad498e46bbaa2c78ee8ad95b920b309edd90
This commit is contained in:
commit
41e44283d2
5 changed files with 48 additions and 41 deletions
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue