summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/statsd/src/StatsLogProcessor.cpp8
-rw-r--r--cmds/statsd/src/StatsLogProcessor.h2
-rw-r--r--cmds/statsd/src/StatsService.cpp11
-rw-r--r--cmds/statsd/src/StatsService.h2
-rw-r--r--cmds/statsd/src/guardrail/StatsdStats.cpp31
-rw-r--r--cmds/statsd/src/guardrail/StatsdStats.h10
-rw-r--r--cmds/statsd/src/logd/LogReader.cpp8
-rw-r--r--cmds/statsd/src/metrics/CountMetricProducer.h2
-rw-r--r--cmds/statsd/src/metrics/DurationMetricProducer.cpp15
-rw-r--r--cmds/statsd/src/metrics/DurationMetricProducer.h2
-rw-r--r--cmds/statsd/src/metrics/EventMetricProducer.h2
-rw-r--r--cmds/statsd/src/metrics/GaugeMetricProducer.h2
-rw-r--r--cmds/statsd/src/metrics/MetricProducer.h6
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.cpp14
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.h3
-rw-r--r--cmds/statsd/src/metrics/ValueMetricProducer.h2
-rw-r--r--cmds/statsd/src/metrics/duration_helper/DurationTracker.h2
-rw-r--r--cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp5
-rw-r--r--cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h1
-rw-r--r--cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp6
-rw-r--r--cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h1
-rw-r--r--cmds/statsd/src/stats_log.proto6
22 files changed, 132 insertions, 9 deletions
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index edc9f2ce6b3c..3e71b5368134 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -196,6 +196,14 @@ size_t StatsLogProcessor::GetMetricsSize(const ConfigKey& key) const {
return it->second->byteSize();
}
+void StatsLogProcessor::dumpStates(FILE* out, bool verbose) {
+ std::lock_guard<std::mutex> lock(mMetricsMutex);
+ fprintf(out, "MetricsManager count: %lu\n", (unsigned long)mMetricsManagers.size());
+ for (auto metricsManager : mMetricsManagers) {
+ metricsManager.second->dumpStates(out, verbose);
+ }
+}
+
void StatsLogProcessor::onDumpReport(const ConfigKey& key, const uint64_t& dumpTimeStampNs,
ConfigMetricsReportList* report) {
std::lock_guard<std::mutex> lock(mMetricsMutex);
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index fb85aa837242..c19ff63e2858 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -61,6 +61,8 @@ public:
return mUidMap;
}
+ void dumpStates(FILE* out, bool verbose);
+
private:
mutable mutex mMetricsMutex;
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 31994e1a92d1..f545bb0738e9 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -175,8 +175,13 @@ status_t StatsService::dump(int fd, const Vector<String16>& args) {
return NO_MEMORY; // the fd is already open
}
+ bool verbose = false;
+ if (args.size() > 0 && !args[0].compare(String16("-v"))) {
+ verbose = true;
+ }
+
// TODO: Proto format for incident reports
- dump_impl(out);
+ dump_impl(out, verbose);
fclose(out);
return NO_ERROR;
@@ -185,9 +190,9 @@ status_t StatsService::dump(int fd, const Vector<String16>& args) {
/**
* Write debugging data about statsd in text format.
*/
-void StatsService::dump_impl(FILE* out) {
- mConfigManager->Dump(out);
+void StatsService::dump_impl(FILE* out, bool verbose) {
StatsdStats::getInstance().dumpStats(out);
+ mProcessor->dumpStates(out, verbose);
}
/**
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index ba6bd2499820..be20893994f1 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -140,7 +140,7 @@ private:
/**
* Text output of dumpsys.
*/
- void dump_impl(FILE* out);
+ void dump_impl(FILE* out, bool verbose);
/**
* Print usage information for the commands
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index 63bde7d82372..77f54569cb47 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -45,6 +45,8 @@ const int FIELD_ID_CONFIG_STATS = 3;
const int FIELD_ID_ATOM_STATS = 7;
const int FIELD_ID_UIDMAP_STATS = 8;
const int FIELD_ID_ANOMALY_ALARM_STATS = 9;
+const int FIELD_ID_PULLED_ATOM_STATS = 10;
+const int FIELD_ID_LOGGER_ERROR_STATS = 11;
const int FIELD_ID_MATCHER_STATS_NAME = 1;
const int FIELD_ID_MATCHER_STATS_COUNT = 2;
@@ -60,6 +62,9 @@ const int FIELD_ID_ATOM_STATS_COUNT = 2;
const int FIELD_ID_ANOMALY_ALARMS_REGISTERED = 1;
+const int FIELD_ID_LOGGER_STATS_TIME = 1;
+const int FIELD_ID_LOGGER_STATS_ERROR_CODE = 2;
+
std::map<int, long> StatsdStats::kPullerCooldownMap = {
{android::util::KERNEL_WAKELOCK, 1},
{android::util::WIFI_BYTES_TRANSFER, 1},
@@ -282,6 +287,15 @@ void StatsdStats::noteAtomLogged(int atomId, int32_t timeSec) {
mPushedAtomStats[atomId]++;
}
+void StatsdStats::noteLoggerError(int error) {
+ lock_guard<std::mutex> lock(mLock);
+ // grows strictly one at a time. so it won't > kMaxLoggerErrors
+ if (mLoggerErrors.size() == kMaxLoggerErrors) {
+ mLoggerErrors.pop_front();
+ }
+ mLoggerErrors.push_back(std::make_pair(time(nullptr), error));
+}
+
void StatsdStats::reset() {
lock_guard<std::mutex> lock(mLock);
resetInternalLocked();
@@ -297,6 +311,7 @@ void StatsdStats::resetInternalLocked() {
mAlertStats.clear();
mAnomalyAlarmRegisteredStats = 0;
mMatcherStats.clear();
+ mLoggerErrors.clear();
for (auto& config : mConfigStats) {
config.second.clear_broadcast_sent_time_sec();
config.second.clear_data_drop_time_sec();
@@ -465,6 +480,14 @@ void StatsdStats::dumpStats(FILE* out) const {
"lost=%d\n",
mUidMapStats.bytes_used(), mUidMapStats.snapshots(), mUidMapStats.changes(),
mUidMapStats.dropped_snapshots(), mUidMapStats.dropped_changes());
+
+ for (const auto& error : mLoggerErrors) {
+ time_t error_time = error.first;
+ struct tm* error_tm = localtime(&error_time);
+ char buffer[80];
+ strftime(buffer, sizeof(buffer), "%Y-%m-%d %I:%M%p\n", error_tm);
+ fprintf(out, "Logger error %d at %s\n", error.second, buffer);
+ }
}
void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
@@ -526,6 +549,14 @@ void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) {
mUidMapStats.SerializeToArray(&buffer[0], numBytes);
proto.write(FIELD_TYPE_MESSAGE | FIELD_ID_UIDMAP_STATS, &buffer[0], buffer.size());
+ for (const auto& error : mLoggerErrors) {
+ long long token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_LOGGER_ERROR_STATS |
+ FIELD_COUNT_REPEATED);
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOGGER_STATS_TIME, error.first);
+ proto.write(FIELD_TYPE_INT32 | FIELD_ID_LOGGER_STATS_ERROR_CODE, error.second);
+ proto.end(token);
+ }
+
output->clear();
size_t bufferSize = proto.size();
output->resize(bufferSize);
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 7cb48ead55d8..1f4bfa62c453 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -49,6 +49,8 @@ public:
// The max number of old config stats we keep.
const static int kMaxIceBoxSize = 20;
+ const static int kMaxLoggerErrors = 10;
+
const static int kMaxTimestampCount = 20;
const static int kMaxLogSourceCount = 50;
@@ -185,6 +187,11 @@ public:
void notePullFromCache(int pullAtomId);
/**
+ * Records statsd met an error while reading from logd.
+ */
+ void noteLoggerError(int error);
+
+ /**
* Reset the historical stats. Including all stats in icebox, and the tracked stats about
* metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
* to collect stats after reset() has been called.
@@ -246,6 +253,9 @@ private:
// Maps PullAtomId to its stats. The size is capped by the puller atom counts.
std::map<int, PulledAtomStats> mPulledAtomStats;
+ // Logd errors. Size capped by kMaxLoggerErrors.
+ std::list<const std::pair<int, int>> mLoggerErrors;
+
// Stores the number of times statsd modified the anomaly alarm registered with
// StatsCompanionService.
int mAnomalyAlarmRegisteredStats = 0;
diff --git a/cmds/statsd/src/logd/LogReader.cpp b/cmds/statsd/src/logd/LogReader.cpp
index 5d43ef3f88bd..0fe896bb10c3 100644
--- a/cmds/statsd/src/logd/LogReader.cpp
+++ b/cmds/statsd/src/logd/LogReader.cpp
@@ -16,10 +16,11 @@
#include "logd/LogReader.h"
-#include <utils/Errors.h>
+#include "guardrail/StatsdStats.h"
#include <time.h>
#include <unistd.h>
+#include <utils/Errors.h>
using namespace android;
using namespace std;
@@ -92,16 +93,15 @@ int LogReader::connect_and_read() {
// Read forever
if (eventLogger) {
-
+ log_msg msg;
while (true) {
- log_msg msg;
-
// Read a message
err = android_logger_list_read(loggers, &msg);
// err = 0 - no content, unexpected connection drop or EOF.
// err = +ive number - size of retrieved data from logger
// err = -ive number, OS supplied error _except_ for -EAGAIN
if (err <= 0) {
+ StatsdStats::getInstance().noteLoggerError(err);
fprintf(stderr, "logcat read failure: %s\n", strerror(err));
break;
}
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index 16fc7ee3c6e9..061b7a36817c 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -68,6 +68,8 @@ private:
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
+ void dumpStatesLocked(FILE* out, bool verbose) const override{};
+
// Util function to flush the old packet.
void flushIfNeededLocked(const uint64_t& newEventTime);
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index e26fe5649090..bfab9e6e490f 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -233,6 +233,21 @@ void DurationMetricProducer::flushIfNeededLocked(const uint64_t& eventTime) {
mCurrentBucketNum += numBucketsForward;
}
+void DurationMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
+ if (mCurrentSlicedDuration.size() == 0) {
+ return;
+ }
+
+ fprintf(out, "DurationMetric %lld dimension size %lu\n", (long long)mMetricId,
+ (unsigned long)mCurrentSlicedDuration.size());
+ if (verbose) {
+ for (const auto& slice : mCurrentSlicedDuration) {
+ fprintf(out, "\t%s\n", slice.first.c_str());
+ slice.second->dumpStates(out, verbose);
+ }
+ }
+}
+
bool DurationMetricProducer::hitGuardRailLocked(const HashableDimensionKey& newKey) {
// the key is not new, we are good.
if (mCurrentSlicedDuration.find(newKey) != mCurrentSlicedDuration.end()) {
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index e06b9a14563d..d8cab92a2b84 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -68,6 +68,8 @@ private:
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
+ void dumpStatesLocked(FILE* out, bool verbose) const override;
+
// Util function to flush the old packet.
void flushIfNeededLocked(const uint64_t& eventTime);
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h
index a57b07d6648e..9da0dd0569d6 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.h
+++ b/cmds/statsd/src/metrics/EventMetricProducer.h
@@ -62,6 +62,8 @@ private:
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
+ void dumpStatesLocked(FILE* out, bool verbose) const override{};
+
// Maps to a EventMetricDataWrapper. Storing atom events in ProtoOutputStream
// is more space efficient than storing LogEvent.
std::unique_ptr<android::util::ProtoOutputStream> mProto;
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index f267e987f464..1895edf8f729 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -83,6 +83,8 @@ private:
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
+ void dumpStatesLocked(FILE* out, bool verbose) const override{};
+
// Util function to flush the old packet.
void flushIfNeededLocked(const uint64_t& eventTime);
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 3779c4487d23..6f33073c633c 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -96,6 +96,11 @@ public:
return onDumpReportLocked(dumpTimeNs, report);
}
+ void dumpStates(FILE* out, bool verbose) const {
+ std::lock_guard<std::mutex> lock(mMutex);
+ dumpStatesLocked(out, verbose);
+ }
+
// Returns the memory in bytes currently used to store this metric's data. Does not change
// state.
size_t byteSize() const {
@@ -128,6 +133,7 @@ protected:
android::util::ProtoOutputStream* protoOutput) = 0;
virtual void onDumpReportLocked(const uint64_t dumpTimeNs, StatsLogReport* report) = 0;
virtual size_t byteSizeLocked() const = 0;
+ virtual void dumpStatesLocked(FILE* out, bool verbose) const = 0;
const int64_t mMetricId;
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index f92951703030..d0737de8acf3 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -154,6 +154,20 @@ void MetricsManager::onDumpReport(const uint64_t& dumpTimeStampNs, ConfigMetrics
}
}
+void MetricsManager::dumpStates(FILE* out, bool verbose) {
+ fprintf(out, "ConfigKey %s, allowed source:", mConfigKey.ToString().c_str());
+ {
+ std::lock_guard<std::mutex> lock(mAllowedLogSourcesMutex);
+ for (const auto& source : mAllowedLogSources) {
+ fprintf(out, "%d ", source);
+ }
+ }
+ fprintf(out, "\n");
+ for (const auto& producer : mAllMetricProducers) {
+ producer->dumpStates(out, verbose);
+ }
+}
+
void MetricsManager::onDumpReport(ProtoOutputStream* protoOutput) {
VLOG("=========================Metric Reports Start==========================");
uint64_t dumpTimeStampNs = time(nullptr) * NS_PER_SEC;
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index a0239fcd1127..9cdbafc75fb1 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -61,6 +61,8 @@ public:
return !mAllowedPkg.empty();
}
+ void dumpStates(FILE* out, bool verbose);
+
// Config source owner can call onDumpReport() to get all the metrics collected.
virtual void onDumpReport(android::util::ProtoOutputStream* protoOutput);
virtual void onDumpReport(const uint64_t& dumpTimeStampNs, ConfigMetricsReport* report);
@@ -68,7 +70,6 @@ public:
// Computes the total byte size of all metrics managed by a single config source.
// Does not change the state.
virtual size_t byteSize();
-
private:
const ConfigKey mConfigKey;
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index 3e7032d8cf2d..9f750cf419b5 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -67,6 +67,8 @@ private:
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
+ void dumpStatesLocked(FILE* out, bool verbose) const override{};
+
// Util function to flush the old packet.
void flushIfNeededLocked(const uint64_t& eventTime);
diff --git a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
index 371460e804bd..c2d2cea2a1ff 100644
--- a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
@@ -97,6 +97,8 @@ public:
// Predict the anomaly timestamp given the current status.
virtual int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
const uint64_t currentTimestamp) const = 0;
+ // Dump internal states for debugging
+ virtual void dumpStates(FILE* out, bool verbose) const = 0;
protected:
// Starts the anomaly alarm.
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
index 0c99391d491f..412a0c935766 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
@@ -291,6 +291,11 @@ int64_t MaxDurationTracker::predictAnomalyTimestampNs(const DurationAnomalyTrack
return currentTimestamp;
}
+void MaxDurationTracker::dumpStates(FILE* out, bool verbose) const {
+ fprintf(out, "\t\t sub-durations %lu\n", (unsigned long)mInfos.size());
+ fprintf(out, "\t\t current duration %lld\n", (long long)mDuration);
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
index 5d3c15804638..e988ebc06307 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
@@ -48,6 +48,7 @@ public:
int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
const uint64_t currentTimestamp) const override;
+ void dumpStates(FILE* out, bool verbose) const override;
private:
std::map<HashableDimensionKey, DurationInfo> mInfos;
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
index 6bf42287e6dd..75d7c0898d78 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
@@ -314,6 +314,12 @@ int64_t OringDurationTracker::predictAnomalyTimestampNs(
return eventTimestampNs + thresholdNs;
}
+void OringDurationTracker::dumpStates(FILE* out, bool verbose) const {
+ fprintf(out, "\t\t started count %lu\n", (unsigned long)mStarted.size());
+ fprintf(out, "\t\t paused count %lu\n", (unsigned long)mPaused.size());
+ fprintf(out, "\t\t current duration %lld\n", (long long)mDuration);
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
index 638b7ad7af26..1b74ed1addca 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
@@ -48,6 +48,7 @@ public:
int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
const uint64_t currentTimestamp) const override;
+ void dumpStates(FILE* out, bool verbose) const override;
private:
// We don't need to keep track of individual durations. The information that's needed is:
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index f73c4a5303cf..a4ccbd42883d 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -262,4 +262,10 @@ message StatsdStatsReport {
optional int64 min_pull_interval_sec = 4;
}
repeated PulledAtomStats pulled_atom_stats = 10;
+
+ message LoggerErrorStats {
+ optional int32 logger_disconnection_sec = 1;
+ optional int32 error_code = 2;
+ }
+ repeated LoggerErrorStats logger_error_stats = 11;
} \ No newline at end of file