logd: liblog: logcat: Add LogWhiteBlackList
- liblog android_logger_get_log_size and android_logger_get_readable_size
adjusted to return long instead of int because of -G flag extending range
NB: ifdef'd only for userdebug and eng builds
- liblog Add android_logger_[sg]et_prune_list and android_logger_set_log_size
- logcat Add -P, -p and -G flags
- logd Add LogWhiteBlackList and configurable log size
(cherry picked from commit 62a5b9dda2f06b88e7f249e7fa0b5052c89aacfb)
Change-Id: I1572338c1b34bd968ad7867857ef708156ec3b6a
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index cf172d1..197b7e8 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -23,13 +23,25 @@
#include "LogBuffer.h"
#include "LogStatistics.h"
+#include "LogWhiteBlackList.h"
#include "LogReader.h"
+// Default
#define LOG_BUFFER_SIZE (256 * 1024) // Tuned on a per-platform basis here?
+#ifdef USERDEBUG_BUILD
+#define log_buffer_size(id) mMaxSize[id]
+#else
+#define log_buffer_size(id) LOG_BUFFER_SIZE
+#endif
LogBuffer::LogBuffer(LastLogTimes *times)
: mTimes(*times) {
pthread_mutex_init(&mLogElementsLock, NULL);
+#ifdef USERDEBUG_BUILD
+ log_id_for_each(i) {
+ mMaxSize[i] = LOG_BUFFER_SIZE;
+ }
+#endif
}
void LogBuffer::log(log_id_t log_id, log_time realtime,
@@ -100,8 +112,8 @@
// mLogElementsLock must be held when this function is called.
void LogBuffer::maybePrune(log_id_t id) {
size_t sizes = stats.sizes(id);
- if (sizes > LOG_BUFFER_SIZE) {
- size_t sizeOver90Percent = sizes - ((LOG_BUFFER_SIZE * 9) / 10);
+ if (sizes > log_buffer_size(id)) {
+ size_t sizeOver90Percent = sizes - ((log_buffer_size(id) * 9) / 10);
size_t elements = stats.elements(id);
unsigned long pruneRows = elements * sizeOver90Percent / sizes;
elements /= 10;
@@ -140,18 +152,23 @@
size_t worst_sizes = 0;
size_t second_worst_sizes = 0;
- LidStatistics &l = stats.id(id);
- UidStatisticsCollection::iterator iu;
- for (iu = l.begin(); iu != l.end(); ++iu) {
- UidStatistics *u = (*iu);
- size_t sizes = u->sizes();
- if (worst_sizes < sizes) {
- second_worst_sizes = worst_sizes;
- worst_sizes = sizes;
- worst = u->getUid();
- }
- if ((second_worst_sizes < sizes) && (sizes < worst_sizes)) {
- second_worst_sizes = sizes;
+#ifdef USERDEBUG_BUILD
+ if (mPrune.worstUidEnabled())
+#endif
+ {
+ LidStatistics &l = stats.id(id);
+ UidStatisticsCollection::iterator iu;
+ for (iu = l.begin(); iu != l.end(); ++iu) {
+ UidStatistics *u = (*iu);
+ size_t sizes = u->sizes();
+ if (worst_sizes < sizes) {
+ second_worst_sizes = worst_sizes;
+ worst_sizes = sizes;
+ worst = u->getUid();
+ }
+ if ((second_worst_sizes < sizes) && (sizes < worst_sizes)) {
+ second_worst_sizes = sizes;
+ }
}
}
@@ -163,7 +180,14 @@
break;
}
- if ((e->getLogId() == id) && (e->getUid() == worst)) {
+ if (e->getLogId() != id) {
+ ++it;
+ continue;
+ }
+
+ uid_t uid = e->getUid();
+
+ if (uid == worst) {
it = mLogElements.erase(it);
unsigned short len = e->getMsgLen();
stats.subtract(len, id, worst, e->getPid());
@@ -174,29 +198,60 @@
break;
}
worst_sizes -= len;
- } else {
+ }
+#ifdef USERDEBUG_BUILD
+ else if (mPrune.naughty(e)) { // BlackListed
+ it = mLogElements.erase(it);
+ stats.subtract(e->getMsgLen(), id, uid, e->getPid());
+ delete e;
+ pruneRows--;
+ if (pruneRows == 0) {
+ break;
+ }
+ }
+#endif
+ else {
++it;
}
}
- if (!kick) {
+ if (!kick
+#ifdef USERDEBUG_BUILD
+ || !mPrune.worstUidEnabled()
+#endif
+ ) {
break; // the following loop will ask bad clients to skip/drop
}
}
+#ifdef USERDEBUG_BUILD
+ bool whitelist = false;
+#endif
it = mLogElements.begin();
while((pruneRows > 0) && (it != mLogElements.end())) {
LogBufferElement *e = *it;
if (e->getLogId() == id) {
if (oldest && (oldest->mStart <= e->getMonotonicTime())) {
- if (stats.sizes(id) > (2 * LOG_BUFFER_SIZE)) {
- // kick a misbehaving log reader client off the island
- oldest->release_Locked();
- } else {
- oldest->triggerSkip_Locked(pruneRows);
+#ifdef USERDEBUG_BUILD
+ if (!whitelist)
+#endif
+ {
+ if (stats.sizes(id) > (2 * log_buffer_size(id))) {
+ // kick a misbehaving log reader client off the island
+ oldest->release_Locked();
+ } else {
+ oldest->triggerSkip_Locked(pruneRows);
+ }
}
break;
}
+#ifdef USERDEBUG_BUILD
+ if (mPrune.nice(e)) { // WhiteListed
+ whitelist = true;
+ it++;
+ continue;
+ }
+#endif
it = mLogElements.erase(it);
stats.subtract(e->getMsgLen(), id, e->getUid(), e->getPid());
delete e;
@@ -206,6 +261,32 @@
}
}
+#ifdef USERDEBUG_BUILD
+ if (whitelist && (pruneRows > 0)) {
+ it = mLogElements.begin();
+ while((it != mLogElements.end()) && (pruneRows > 0)) {
+ LogBufferElement *e = *it;
+ if (e->getLogId() == id) {
+ if (oldest && (oldest->mStart <= e->getMonotonicTime())) {
+ if (stats.sizes(id) > (2 * log_buffer_size(id))) {
+ // kick a misbehaving log reader client off the island
+ oldest->release_Locked();
+ } else {
+ oldest->triggerSkip_Locked(pruneRows);
+ }
+ break;
+ }
+ it = mLogElements.erase(it);
+ stats.subtract(e->getMsgLen(), id, e->getUid(), e->getPid());
+ delete e;
+ pruneRows--;
+ } else {
+ it++;
+ }
+ }
+ }
+#endif
+
LogTimeEntry::unlock();
}
@@ -224,11 +305,37 @@
return retval;
}
+#ifdef USERDEBUG_BUILD
+
+// set the total space allocated to "id"
+int LogBuffer::setSize(log_id_t id, unsigned long size) {
+ // Reasonable limits ...
+ if ((size < (64 * 1024)) || ((256 * 1024 * 1024) < size)) {
+ return -1;
+ }
+ pthread_mutex_lock(&mLogElementsLock);
+ log_buffer_size(id) = size;
+ pthread_mutex_unlock(&mLogElementsLock);
+ return 0;
+}
+
+// get the total space allocated to "id"
+unsigned long LogBuffer::getSize(log_id_t id) {
+ pthread_mutex_lock(&mLogElementsLock);
+ size_t retval = log_buffer_size(id);
+ pthread_mutex_unlock(&mLogElementsLock);
+ return retval;
+}
+
+#else // ! USERDEBUG_BUILD
+
// get the total space allocated to "id"
unsigned long LogBuffer::getSize(log_id_t /*id*/) {
- return LOG_BUFFER_SIZE;
+ return log_buffer_size(id);
}
+#endif
+
log_time LogBuffer::flushTo(
SocketClient *reader, const log_time start, bool privileged,
bool (*filter)(const LogBufferElement *element, void *arg), void *arg) {
@@ -269,7 +376,7 @@
return max;
}
-size_t LogBuffer::formatStatistics(char **strp, uid_t uid, unsigned int logMask) {
+void LogBuffer::formatStatistics(char **strp, uid_t uid, unsigned int logMask) {
log_time oldest(CLOCK_MONOTONIC);
pthread_mutex_lock(&mLogElementsLock);
@@ -285,9 +392,7 @@
}
}
- size_t ret = stats.format(strp, uid, logMask, oldest);
+ stats.format(strp, uid, logMask, oldest);
pthread_mutex_unlock(&mLogElementsLock);
-
- return ret;
}