Merge "logd: statistics add logspan"

This commit is contained in:
Mark Salyzyn 2017-04-20 15:19:04 +00:00 committed by Gerrit Code Review
commit e32517d773
2 changed files with 141 additions and 1 deletions

View File

@ -24,19 +24,26 @@
#include <list>
#include <android/log.h>
#include <private/android_logger.h>
#include "LogStatistics.h"
static const uint64_t hourSec = 60 * 60;
static const uint64_t monthSec = 31 * 24 * hourSec;
size_t LogStatistics::SizesTotal;
LogStatistics::LogStatistics() : enable(false) {
log_time now(CLOCK_REALTIME);
log_id_for_each(id) {
mSizes[id] = 0;
mElements[id] = 0;
mDroppedElements[id] = 0;
mSizesTotal[id] = 0;
mElementsTotal[id] = 0;
mOldest[id] = now;
mNewest[id] = now;
mNewestDropped[id] = now;
}
}
@ -100,6 +107,27 @@ void LogStatistics::add(LogBufferElement* element) {
++mElementsTotal[log_id];
}
log_time stamp(element->getRealTime());
if (mNewest[log_id] < stamp) {
// A major time update invalidates the statistics :-(
log_time diff = stamp - mNewest[log_id];
mNewest[log_id] = stamp;
if (diff.tv_sec > hourSec) {
// approximate Do-Your-Best fixup
diff += mOldest[log_id];
if ((diff > stamp) && ((diff - stamp).tv_sec < hourSec)) {
diff = stamp;
}
if (diff <= stamp) {
mOldest[log_id] = diff;
if (mNewestDropped[log_id] < diff) {
mNewestDropped[log_id] = diff;
}
}
}
}
if (log_id == LOG_ID_KERNEL) {
return;
}
@ -135,6 +163,10 @@ void LogStatistics::subtract(LogBufferElement* element) {
--mDroppedElements[log_id];
}
if (mOldest[log_id] < element->getRealTime()) {
mOldest[log_id] = element->getRealTime();
}
if (log_id == LOG_ID_KERNEL) {
return;
}
@ -169,6 +201,10 @@ void LogStatistics::drop(LogBufferElement* element) {
mSizes[log_id] -= size;
++mDroppedElements[log_id];
if (mNewestDropped[log_id] < element->getRealTime()) {
mNewestDropped[log_id] = element->getRealTime();
}
uidTable[log_id].drop(element->getUid(), element);
if (element->getUid() == AID_SYSTEM) {
pidSystemTable[log_id].drop(element->getPid(), element);
@ -468,6 +504,45 @@ std::string TagEntry::format(const LogStatistics& /* stat */,
return formatLine(name, size, pruned);
}
static std::string formatMsec(uint64_t val) {
static const unsigned subsecDigits = 3;
static const uint64_t sec = MS_PER_SEC;
static const uint64_t minute = 60 * sec;
static const uint64_t hour = 60 * minute;
static const uint64_t day = 24 * hour;
std::string output;
if (val < sec) return output;
if (val >= day) {
output = android::base::StringPrintf("%" PRIu64 "d ", val / day);
val = (val % day) + day;
}
if (val >= minute) {
if (val >= hour) {
output += android::base::StringPrintf("%" PRIu64 ":",
(val / hour) % (day / hour));
}
output += android::base::StringPrintf(
(val >= hour) ? "%02" PRIu64 ":" : "%" PRIu64 ":",
(val / minute) % (hour / minute));
}
output +=
android::base::StringPrintf((val >= minute) ? "%02" PRIu64 : "%" PRIu64,
(val / sec) % (minute / sec));
val %= sec;
unsigned digits = subsecDigits;
while (digits && ((val % 10) == 0)) {
val /= 10;
--digits;
}
if (digits) {
output += android::base::StringPrintf(".%0*" PRIu64, digits, val);
}
return output;
}
std::string LogStatistics::format(uid_t uid, pid_t pid,
unsigned int logMask) const {
static const unsigned short spaces_total = 19;
@ -537,6 +612,67 @@ std::string LogStatistics::format(uid_t uid, pid_t pid,
output += android::base::StringPrintf("%*s%zu/%zu", spaces, "", totalSize,
totalEls);
static const char SpanStr[] = "\nLogspan";
spaces = 10 - strlen(SpanStr);
output += SpanStr;
// Total reports the greater of the individual maximum time span, or the
// validated minimum start and maximum end time span if it makes sense.
uint64_t minTime = UINT64_MAX;
uint64_t maxTime = 0;
uint64_t maxSpan = 0;
totalSize = 0;
log_id_for_each(id) {
if (!(logMask & (1 << id))) continue;
// validity checking
uint64_t oldest = mOldest[id].msec();
uint64_t newest = mNewest[id].msec();
if (newest <= oldest) {
spaces += spaces_total;
continue;
}
uint64_t span = newest - oldest;
if (span > (monthSec * MS_PER_SEC)) {
spaces += spaces_total;
continue;
}
// total span
if (minTime > oldest) minTime = oldest;
if (maxTime < newest) maxTime = newest;
if (span > maxSpan) maxSpan = span;
totalSize += span;
uint64_t dropped = mNewestDropped[id].msec();
if (dropped < oldest) dropped = oldest;
if (dropped > newest) dropped = newest;
oldLength = output.length();
output += android::base::StringPrintf("%*s%s", spaces, "",
formatMsec(span).c_str());
unsigned permille = ((newest - dropped) * 1000 + (span / 2)) / span;
if ((permille > 1) && (permille < 999)) {
output += android::base::StringPrintf("(%u", permille / 10);
permille %= 10;
if (permille) {
output += android::base::StringPrintf(".%u", permille);
}
output += android::base::StringPrintf("%%)");
}
spaces -= output.length() - oldLength;
spaces += spaces_total;
}
if ((maxTime > minTime) && ((maxTime -= minTime) < totalSize) &&
(maxTime > maxSpan)) {
maxSpan = maxTime;
}
if (spaces < 0) spaces = 0;
output += android::base::StringPrintf("%*s%s", spaces, "",
formatMsec(maxSpan).c_str());
static const char OverheadStr[] = "\nOverhead";
spaces = 10 - strlen(OverheadStr);
output += OverheadStr;

View File

@ -28,6 +28,7 @@
#include <android-base/stringprintf.h>
#include <android/log.h>
#include <log/log_time.h>
#include <private/android_filesystem_config.h>
#include "LogBufferElement.h"
@ -520,6 +521,9 @@ class LogStatistics {
size_t mDroppedElements[LOG_ID_MAX];
size_t mSizesTotal[LOG_ID_MAX];
size_t mElementsTotal[LOG_ID_MAX];
log_time mOldest[LOG_ID_MAX];
log_time mNewest[LOG_ID_MAX];
log_time mNewestDropped[LOG_ID_MAX];
static size_t SizesTotal;
bool enable;