diff options
Diffstat (limited to 'logd')
-rw-r--r-- | logd/LogBufferElement.cpp | 7 | ||||
-rw-r--r-- | logd/LogBufferElement.h | 5 | ||||
-rw-r--r-- | logd/LogStatistics.cpp | 55 | ||||
-rw-r--r-- | logd/LogStatistics.h | 27 | ||||
-rw-r--r-- | logd/main.cpp | 18 |
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 |