logd: class hierarcy for Uid and Pid statistics.
Add EntryBase and EntryBaseDropped base classes for statistical entries to inherit from. Abstract add(), subtract() and drop() methods to common LogBufferElement in each for entry policy decisions. Some move of details out of LogStatistics.cpp and place them into LogStatistics.h. Add statistical add(), subtract() and drop() methods to hash table to call entries for policy. Bug: 19608965 Change-Id: Ib8a33a8fe28871ef165d1632c6546a5c606231e8
This commit is contained in:
parent
5720d2c168
commit
81b3eabc49
|
@ -25,6 +25,9 @@
|
|||
#include <log/log.h>
|
||||
#include <log/log_read.h>
|
||||
|
||||
// Hijack this header as a common include file used by most all sources
|
||||
// to report some utilities defined here and there.
|
||||
|
||||
namespace android {
|
||||
|
||||
// Furnished in main.cpp. Caller must own and free returned value
|
||||
|
|
|
@ -39,7 +39,7 @@ LogStatistics::LogStatistics()
|
|||
namespace android {
|
||||
|
||||
// caller must own and free character string
|
||||
static char *pidToName(pid_t pid) {
|
||||
char *pidToName(pid_t pid) {
|
||||
char *retval = NULL;
|
||||
if (pid == 0) { // special case from auditd for kernel
|
||||
retval = strdup("logd.auditd");
|
||||
|
@ -70,21 +70,7 @@ void LogStatistics::add(LogBufferElement *e) {
|
|||
mSizes[log_id] += size;
|
||||
++mElements[log_id];
|
||||
|
||||
uid_t uid = e->getUid();
|
||||
unsigned short dropped = e->getDropped();
|
||||
android::hash_t hash = android::hash_type(uid);
|
||||
uidTable_t &table = uidTable[log_id];
|
||||
ssize_t index = table.find(-1, hash, uid);
|
||||
if (index == -1) {
|
||||
UidEntry initEntry(uid);
|
||||
initEntry.add(size);
|
||||
initEntry.add_dropped(dropped);
|
||||
table.add(hash, initEntry);
|
||||
} else {
|
||||
UidEntry &entry = table.editEntryAt(index);
|
||||
entry.add(size);
|
||||
entry.add_dropped(dropped);
|
||||
}
|
||||
uidTable[log_id].add(e->getUid(), e);
|
||||
|
||||
mSizesTotal[log_id] += size;
|
||||
++mElementsTotal[log_id];
|
||||
|
@ -93,28 +79,7 @@ void LogStatistics::add(LogBufferElement *e) {
|
|||
return;
|
||||
}
|
||||
|
||||
pid_t pid = e->getPid();
|
||||
hash = android::hash_type(pid);
|
||||
index = pidTable.find(-1, hash, pid);
|
||||
if (index == -1) {
|
||||
PidEntry initEntry(pid, uid, android::pidToName(pid));
|
||||
initEntry.add(size);
|
||||
initEntry.add_dropped(dropped);
|
||||
pidTable.add(hash, initEntry);
|
||||
} else {
|
||||
PidEntry &entry = pidTable.editEntryAt(index);
|
||||
if (entry.getUid() != uid) {
|
||||
entry.setUid(uid);
|
||||
entry.setName(android::pidToName(pid));
|
||||
} else if (!entry.getName()) {
|
||||
char *name = android::pidToName(pid);
|
||||
if (name) {
|
||||
entry.setName(name);
|
||||
}
|
||||
}
|
||||
entry.add(size);
|
||||
entry.add_dropped(dropped);
|
||||
}
|
||||
pidTable.add(e->getPid(), e);
|
||||
}
|
||||
|
||||
void LogStatistics::subtract(LogBufferElement *e) {
|
||||
|
@ -123,31 +88,13 @@ void LogStatistics::subtract(LogBufferElement *e) {
|
|||
mSizes[log_id] -= size;
|
||||
--mElements[log_id];
|
||||
|
||||
uid_t uid = e->getUid();
|
||||
unsigned short dropped = e->getDropped();
|
||||
android::hash_t hash = android::hash_type(uid);
|
||||
uidTable_t &table = uidTable[log_id];
|
||||
ssize_t index = table.find(-1, hash, uid);
|
||||
if (index != -1) {
|
||||
UidEntry &entry = table.editEntryAt(index);
|
||||
if (entry.subtract(size) || entry.subtract_dropped(dropped)) {
|
||||
table.removeAt(index);
|
||||
}
|
||||
}
|
||||
uidTable[log_id].subtract(e->getUid(), e);
|
||||
|
||||
if (!enable) {
|
||||
return;
|
||||
}
|
||||
|
||||
pid_t pid = e->getPid();
|
||||
hash = android::hash_type(pid);
|
||||
index = pidTable.find(-1, hash, pid);
|
||||
if (index != -1) {
|
||||
PidEntry &entry = pidTable.editEntryAt(index);
|
||||
if (entry.subtract(size) || entry.subtract_dropped(dropped)) {
|
||||
pidTable.removeAt(index);
|
||||
}
|
||||
}
|
||||
pidTable.subtract(e->getPid(), e);
|
||||
}
|
||||
|
||||
// Atomically set an entry to drop
|
||||
|
@ -157,28 +104,13 @@ void LogStatistics::drop(LogBufferElement *e) {
|
|||
unsigned short size = e->getMsgLen();
|
||||
mSizes[log_id] -= size;
|
||||
|
||||
uid_t uid = e->getUid();
|
||||
android::hash_t hash = android::hash_type(uid);
|
||||
typeof uidTable[0] &table = uidTable[log_id];
|
||||
ssize_t index = table.find(-1, hash, uid);
|
||||
if (index != -1) {
|
||||
UidEntry &entry = table.editEntryAt(index);
|
||||
entry.subtract(size);
|
||||
entry.add_dropped(1);
|
||||
}
|
||||
uidTable[log_id].drop(e->getUid(), e);
|
||||
|
||||
if (!enable) {
|
||||
return;
|
||||
}
|
||||
|
||||
pid_t pid = e->getPid();
|
||||
hash = android::hash_type(pid);
|
||||
index = pidTable.find(-1, hash, pid);
|
||||
if (index != -1) {
|
||||
PidEntry &entry = pidTable.editEntryAt(index);
|
||||
entry.subtract(size);
|
||||
entry.add_dropped(1);
|
||||
}
|
||||
pidTable.drop(e->getPid(), e);
|
||||
}
|
||||
|
||||
// caller must own and free character string
|
||||
|
@ -379,6 +311,7 @@ void LogStatistics::format(char **buf, uid_t uid, unsigned int logMask) {
|
|||
}
|
||||
|
||||
if (enable) {
|
||||
// Pid table
|
||||
bool headerPrinted = false;
|
||||
std::unique_ptr<const PidEntry *[]> sorted = pidTable.sort(maximum_sorted_entries);
|
||||
ssize_t index = -1;
|
||||
|
@ -460,48 +393,14 @@ uid_t pidToUid(pid_t pid) {
|
|||
}
|
||||
|
||||
uid_t LogStatistics::pidToUid(pid_t pid) {
|
||||
uid_t uid;
|
||||
android::hash_t hash = android::hash_type(pid);
|
||||
ssize_t index = pidTable.find(-1, hash, pid);
|
||||
if (index == -1) {
|
||||
uid = android::pidToUid(pid);
|
||||
PidEntry initEntry(pid, uid, android::pidToName(pid));
|
||||
pidTable.add(hash, initEntry);
|
||||
} else {
|
||||
PidEntry &entry = pidTable.editEntryAt(index);
|
||||
if (!entry.getName()) {
|
||||
char *name = android::pidToName(pid);
|
||||
if (name) {
|
||||
entry.setName(name);
|
||||
}
|
||||
}
|
||||
uid = entry.getUid();
|
||||
}
|
||||
return uid;
|
||||
return pidTable.entryAt(pidTable.add(pid)).getUid();
|
||||
}
|
||||
|
||||
// caller must free character string
|
||||
char *LogStatistics::pidToName(pid_t pid) {
|
||||
char *name;
|
||||
|
||||
android::hash_t hash = android::hash_type(pid);
|
||||
ssize_t index = pidTable.find(-1, hash, pid);
|
||||
if (index == -1) {
|
||||
name = android::pidToName(pid);
|
||||
PidEntry initEntry(pid, android::pidToUid(pid), name ? strdup(name) : NULL);
|
||||
pidTable.add(hash, initEntry);
|
||||
} else {
|
||||
PidEntry &entry = pidTable.editEntryAt(index);
|
||||
const char *n = entry.getName();
|
||||
if (n) {
|
||||
name = strdup(n);
|
||||
} else {
|
||||
name = android::pidToName(pid);
|
||||
if (name) {
|
||||
entry.setName(strdup(name));
|
||||
}
|
||||
}
|
||||
const char *name = pidTable.entryAt(pidTable.add(pid)).getName();
|
||||
if (!name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return name;
|
||||
return strdup(name);
|
||||
}
|
||||
|
|
|
@ -73,52 +73,139 @@ public:
|
|||
ssize_t next(ssize_t index) {
|
||||
return android::BasicHashtable<TKey, TEntry>::next(index);
|
||||
}
|
||||
|
||||
size_t add(TKey key, LogBufferElement *e) {
|
||||
android::hash_t hash = android::hash_type(key);
|
||||
ssize_t index = android::BasicHashtable<TKey, TEntry>::find(-1, hash, key);
|
||||
if (index == -1) {
|
||||
return android::BasicHashtable<TKey, TEntry>::add(hash, TEntry(e));
|
||||
}
|
||||
android::BasicHashtable<TKey, TEntry>::editEntryAt(index).add(e);
|
||||
return index;
|
||||
}
|
||||
|
||||
inline size_t add(TKey key) {
|
||||
android::hash_t hash = android::hash_type(key);
|
||||
ssize_t index = android::BasicHashtable<TKey, TEntry>::find(-1, hash, key);
|
||||
if (index == -1) {
|
||||
return android::BasicHashtable<TKey, TEntry>::add(hash, TEntry(key));
|
||||
}
|
||||
android::BasicHashtable<TKey, TEntry>::editEntryAt(index).add(key);
|
||||
return index;
|
||||
}
|
||||
|
||||
void subtract(TKey key, LogBufferElement *e) {
|
||||
ssize_t index = android::BasicHashtable<TKey, TEntry>::find(-1, android::hash_type(key), key);
|
||||
if ((index != -1)
|
||||
&& android::BasicHashtable<TKey, TEntry>::editEntryAt(index).subtract(e)) {
|
||||
android::BasicHashtable<TKey, TEntry>::removeAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
inline void drop(TKey key, LogBufferElement *e) {
|
||||
ssize_t index = android::BasicHashtable<TKey, TEntry>::find(-1, android::hash_type(key), key);
|
||||
if (index != -1) {
|
||||
android::BasicHashtable<TKey, TEntry>::editEntryAt(index).drop(e);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct UidEntry {
|
||||
const uid_t uid;
|
||||
struct EntryBase {
|
||||
size_t size;
|
||||
|
||||
EntryBase():size(0) { }
|
||||
EntryBase(LogBufferElement *e):size(e->getMsgLen()) { }
|
||||
|
||||
size_t getSizes() const { return size; }
|
||||
|
||||
inline void add(LogBufferElement *e) { size += e->getMsgLen(); }
|
||||
inline bool subtract(LogBufferElement *e) { size -= e->getMsgLen(); return !size; }
|
||||
};
|
||||
|
||||
struct EntryBaseDropped : public EntryBase {
|
||||
size_t dropped;
|
||||
|
||||
UidEntry(uid_t uid):uid(uid),size(0),dropped(0) { }
|
||||
EntryBaseDropped():dropped(0) { }
|
||||
EntryBaseDropped(LogBufferElement *e):EntryBase(e),dropped(e->getDropped()){ }
|
||||
|
||||
inline const uid_t&getKey() const { return uid; }
|
||||
size_t getSizes() const { return size; }
|
||||
size_t getDropped() const { return dropped; }
|
||||
|
||||
inline void add(size_t s) { size += s; }
|
||||
inline void add_dropped(size_t d) { dropped += d; }
|
||||
inline bool subtract(size_t s) { size -= s; return !dropped && !size; }
|
||||
inline bool subtract_dropped(size_t d) { dropped -= d; return !dropped && !size; }
|
||||
inline void add(LogBufferElement *e) {
|
||||
dropped += e->getDropped();
|
||||
EntryBase::add(e);
|
||||
}
|
||||
inline bool subtract(LogBufferElement *e) {
|
||||
dropped -= e->getDropped();
|
||||
return EntryBase::subtract(e) && !dropped;
|
||||
}
|
||||
inline void drop(LogBufferElement *e) {
|
||||
dropped += 1;
|
||||
EntryBase::subtract(e);
|
||||
}
|
||||
};
|
||||
|
||||
struct PidEntry {
|
||||
struct UidEntry : public EntryBaseDropped {
|
||||
const uid_t uid;
|
||||
|
||||
UidEntry(LogBufferElement *e):EntryBaseDropped(e),uid(e->getUid()) { }
|
||||
|
||||
inline const uid_t&getKey() const { return uid; }
|
||||
};
|
||||
|
||||
namespace android {
|
||||
// caller must own and free character string
|
||||
char *pidToName(pid_t pid);
|
||||
uid_t pidToUid(pid_t pid);
|
||||
}
|
||||
|
||||
struct PidEntry : public EntryBaseDropped {
|
||||
const pid_t pid;
|
||||
uid_t uid;
|
||||
char *name;
|
||||
size_t size;
|
||||
size_t dropped;
|
||||
|
||||
PidEntry(pid_t p, uid_t u, char *n):pid(p),uid(u),name(n),size(0),dropped(0) { }
|
||||
PidEntry(pid_t p):
|
||||
EntryBaseDropped(),
|
||||
pid(p),
|
||||
uid(android::pidToUid(p)),
|
||||
name(android::pidToName(pid)) { }
|
||||
PidEntry(LogBufferElement *e):
|
||||
EntryBaseDropped(e),
|
||||
pid(e->getPid()),
|
||||
uid(e->getUid()),
|
||||
name(android::pidToName(e->getPid())) { }
|
||||
PidEntry(const PidEntry &c):
|
||||
EntryBaseDropped(c),
|
||||
pid(c.pid),
|
||||
uid(c.uid),
|
||||
name(c.name ? strdup(c.name) : NULL),
|
||||
size(c.size),
|
||||
dropped(c.dropped) { }
|
||||
name(c.name ? strdup(c.name) : NULL) { }
|
||||
~PidEntry() { free(name); }
|
||||
|
||||
const pid_t&getKey() const { return pid; }
|
||||
const uid_t&getUid() const { return uid; }
|
||||
uid_t&setUid(uid_t u) { return uid = u; }
|
||||
const char*getName() const { return name; }
|
||||
char *setName(char *n) { free(name); return name = n; }
|
||||
size_t getSizes() const { return size; }
|
||||
size_t getDropped() const { return dropped; }
|
||||
inline void add(size_t s) { size += s; }
|
||||
inline void add_dropped(size_t d) { dropped += d; }
|
||||
inline bool subtract(size_t s) { size -= s; return !dropped && !size; }
|
||||
inline bool subtract_dropped(size_t d) { dropped -= d; return !dropped && !size; }
|
||||
|
||||
inline void add(pid_t p) {
|
||||
if (!name) {
|
||||
char *n = android::pidToName(p);
|
||||
if (n) {
|
||||
name = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void add(LogBufferElement *e) {
|
||||
uid_t u = e->getUid();
|
||||
if (getUid() != u) {
|
||||
uid = u;
|
||||
free(name);
|
||||
name = android::pidToName(e->getPid());
|
||||
} else {
|
||||
add(e->getPid());
|
||||
}
|
||||
EntryBaseDropped::add(e);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Log Statistics
|
||||
|
|
Loading…
Reference in New Issue