summaryrefslogtreecommitdiffstats
path: root/logd
diff options
context:
space:
mode:
authorMark Salyzyn <salyzyn@google.com>2015-04-13 14:24:45 -0700
committerMark Salyzyn <salyzyn@google.com>2015-05-12 15:34:56 -0700
commitff32f3c77439b9791e58c225a8b7ca82dfc2c3da (patch)
tree4edf4b3f72fc804ab237ce89763c5576e2d84e7e /logd
parent4fba28671b7213010dbfe6ad88e9891cc4080c75 (diff)
downloadcore-ff32f3c77439b9791e58c225a8b7ca82dfc2c3da.tar.gz
core-ff32f3c77439b9791e58c225a8b7ca82dfc2c3da.tar.bz2
core-ff32f3c77439b9791e58c225a8b7ca82dfc2c3da.zip
logd: Add Tag statistics
(cherry pick from commit 344bff4391dd434dda501e812f18f524290c5a7c) - Optional class of statistics for events Tags - export tagToName from LogBuffer (located in main.cp to address https://android-review.googlesource.com/#/c/110204) - Can not handle dropped because getTag() can not work, will need to be fixed if we start filtering. Bug: 19608965 Change-Id: I7b90607ca588bf37bab71f19b1570a290e772776
Diffstat (limited to 'logd')
-rw-r--r--logd/LogBufferElement.cpp7
-rw-r--r--logd/LogBufferElement.h5
-rw-r--r--logd/LogStatistics.cpp55
-rw-r--r--logd/LogStatistics.h27
-rw-r--r--logd/main.cpp18
5 files changed, 110 insertions, 2 deletions
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
index 6a057000d..164faa9f8 100644
--- a/logd/LogBufferElement.cpp
+++ b/logd/LogBufferElement.cpp
@@ -50,6 +50,13 @@ LogBufferElement::~LogBufferElement() {
delete [] mMsg;
}
+uint32_t LogBufferElement::getTag() const {
+ if ((mLogId != LOG_ID_EVENTS) || !mMsg || (mMsgLen < sizeof(uint32_t))) {
+ return 0;
+ }
+ return le32toh(reinterpret_cast<android_event_header_t *>(mMsg)->tag);
+}
+
// caller must own and free character string
static char *tidToName(pid_t tid) {
char *retval = NULL;
diff --git a/logd/LogBufferElement.h b/logd/LogBufferElement.h
index b6c6196d2..75ec59e80 100644
--- a/logd/LogBufferElement.h
+++ b/logd/LogBufferElement.h
@@ -36,6 +36,9 @@ char *uidToName(uid_t uid);
// Furnished in LogStatistics.cpp. Caller must own and free returned value
char *pidToName(pid_t pid);
+// Furnished in main.cpp. Thread safe.
+const char *tagToName(uint32_t tag);
+
}
static inline bool worstUidEnabledForLogid(log_id_t id) {
@@ -85,6 +88,8 @@ public:
static uint64_t getCurrentSequence(void) { return sequence.load(memory_order_relaxed); }
log_time getRealTime(void) const { return mRealTime; }
+ uint32_t getTag(void) const;
+
static const uint64_t FLUSH_ERROR;
uint64_t flushTo(SocketClient *writer, LogBuffer *parent);
};
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index 2eab4dd72..4511e0b8e 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -80,6 +80,11 @@ void LogStatistics::add(LogBufferElement *e) {
}
pidTable.add(e->getPid(), e);
+
+ uint32_t tag = e->getTag();
+ if (tag) {
+ tagTable.add(tag, e);
+ }
}
void LogStatistics::subtract(LogBufferElement *e) {
@@ -95,6 +100,11 @@ void LogStatistics::subtract(LogBufferElement *e) {
}
pidTable.subtract(e->getPid(), e);
+
+ uint32_t tag = e->getTag();
+ if (tag) {
+ tagTable.subtract(tag, e);
+ }
}
// Atomically set an entry to drop
@@ -373,6 +383,51 @@ void LogStatistics::format(char **buf, uid_t uid, unsigned int logMask) {
}
}
+ if (enable && (logMask & (1 << LOG_ID_EVENTS))) {
+ // Tag table
+ bool headerPrinted = false;
+ std::unique_ptr<const TagEntry *[]> sorted = tagTable.sort(maximum_sorted_entries);
+ ssize_t index = -1;
+ while ((index = tagTable.next(index, sorted, maximum_sorted_entries)) >= 0) {
+ const TagEntry *entry = sorted[index];
+ uid_t u = entry->getUid();
+ if ((uid != AID_ROOT) && (u != uid)) {
+ continue;
+ }
+
+ android::String8 pruned("");
+
+ if (!headerPrinted) {
+ output.appendFormat("\n\n");
+ android::String8 name("Chattiest events log buffer TAGs:");
+ android::String8 size("Size");
+ format_line(output, name, size, pruned);
+
+ name.setTo(" TAG/UID TAGNAME");
+ size.setTo("BYTES");
+ format_line(output, name, size, pruned);
+
+ headerPrinted = true;
+ }
+
+ android::String8 name("");
+ if (u == (uid_t)-1) {
+ name.appendFormat("%7u", entry->getKey());
+ } else {
+ name.appendFormat("%7u/%u", entry->getKey(), u);
+ }
+ const char *n = entry->getName();
+ if (n) {
+ name.appendFormat("%*s%s", (int)std::max(14 - name.length(), (size_t)1), "", n);
+ }
+
+ android::String8 size("");
+ size.appendFormat("%zu", entry->getSizes());
+
+ format_line(output, name, size, pruned);
+ }
+ }
+
*buf = strdup(output.string());
}
diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h
index ca4b9a6bf..d21a75bfe 100644
--- a/logd/LogStatistics.h
+++ b/logd/LogStatistics.h
@@ -154,8 +154,6 @@ struct UidEntry : public EntryBaseDropped {
};
namespace android {
-// caller must own and free character string
-char *pidToName(pid_t pid);
uid_t pidToUid(pid_t pid);
}
@@ -209,7 +207,28 @@ struct PidEntry : public EntryBaseDropped {
}
EntryBaseDropped::add(e);
}
+};
+
+struct TagEntry : public EntryBase {
+ const uint32_t tag;
+ uid_t uid;
+
+ TagEntry(LogBufferElement *e):
+ EntryBase(e),
+ tag(e->getTag()),
+ uid(e->getUid()) { }
+
+ const uint32_t&getKey() const { return tag; }
+ const uid_t&getUid() const { return uid; }
+ const char*getName() const { return android::tagToName(tag); }
+ inline void add(LogBufferElement *e) {
+ uid_t u = e->getUid();
+ if (uid != u) {
+ uid = -1;
+ }
+ EntryBase::add(e);
+ }
};
// Log Statistics
@@ -228,6 +247,10 @@ class LogStatistics {
typedef LogHashtable<pid_t, PidEntry> pidTable_t;
pidTable_t pidTable;
+ // tag list
+ typedef LogHashtable<uint32_t, TagEntry> tagTable_t;
+ tagTable_t tagTable;
+
public:
LogStatistics();
diff --git a/logd/main.cpp b/logd/main.cpp
index 237c7c1cf..7b8e94e66 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -35,6 +35,7 @@
#include <cutils/properties.h>
#include <cutils/sched_policy.h>
#include <cutils/sockets.h>
+#include <log/event_tag_map.h>
#include <private/android_filesystem_config.h>
#include "CommandListener.h"
@@ -238,6 +239,23 @@ void reinit_signal_handler(int /*signal*/) {
sem_post(&reinit);
}
+// tagToName converts an events tag into a name
+const char *android::tagToName(uint32_t tag) {
+ static const EventTagMap *map;
+
+ if (!map) {
+ sem_wait(&sem_name);
+ if (!map) {
+ map = android_openEventTagMap(EVENT_TAG_MAP_FILE);
+ }
+ sem_post(&sem_name);
+ if (!map) {
+ return NULL;
+ }
+ }
+ return android_lookupEventTag(map, tag);
+}
+
// Foreground waits for exit of the main persistent threads
// that are started here. The threads are created to manage
// UNIX domain client sockets for writing, reading and