Loading cmds/statsd/src/StatsService.cpp +3 −9 Original line number Diff line number Diff line Loading @@ -185,6 +185,7 @@ status_t StatsService::dump(int fd, const Vector<String16>& args) { */ void StatsService::dump_impl(FILE* out) { mConfigManager->Dump(out); StatsdStats::getInstance().dumpStats(out); } /** Loading Loading @@ -296,9 +297,8 @@ void StatsService::print_cmd_help(FILE* out) { fprintf(out, " NAME The name of the configuration\n"); fprintf(out, "\n"); fprintf(out, "\n"); fprintf(out, "usage: adb shell cmd stats print-stats [reset]\n"); fprintf(out, "usage: adb shell cmd stats print-stats\n"); fprintf(out, " Prints some basic stats.\n"); fprintf(out, " reset: 1 to reset the statsd stats. default=0.\n"); } status_t StatsService::cmd_trigger_broadcast(FILE* out, Vector<String8>& args) { Loading Loading @@ -487,14 +487,8 @@ status_t StatsService::cmd_print_stats(FILE* out, const Vector<String8>& args) { fprintf(out, "Config %s uses %zu bytes\n", key.ToString().c_str(), mProcessor->GetMetricsSize(key)); } fprintf(out, "Detailed statsd stats in logcat...\n"); StatsdStats& statsdStats = StatsdStats::getInstance(); bool reset = false; if (args.size() > 1) { reset = strtol(args[1].string(), NULL, 10); } vector<uint8_t> output; statsdStats.dumpStats(&output, reset); statsdStats.dumpStats(out); return NO_ERROR; } Loading cmds/statsd/src/guardrail/StatsdStats.cpp +112 −62 Original line number Diff line number Diff line Loading @@ -355,73 +355,135 @@ void StatsdStats::addSubStatsToConfigLocked(const ConfigKey& key, } } void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) { void StatsdStats::dumpStats(FILE* out) const { lock_guard<std::mutex> lock(mLock); if (DEBUG) { time_t t = mStartTimeSec; struct tm* tm = localtime(&t); char timeBuffer[80]; strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p", tm); VLOG("=================StatsdStats dump begins===================="); VLOG("Stats collection start second: %s", timeBuffer); } ProtoOutputStream proto; proto.write(FIELD_TYPE_INT32 | FIELD_ID_BEGIN_TIME, mStartTimeSec); proto.write(FIELD_TYPE_INT32 | FIELD_ID_END_TIME, (int32_t)time(nullptr)); VLOG("%lu Config in icebox: ", (unsigned long)mIceBox.size()); strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p\n", tm); fprintf(out, "Stats collection start second: %s\n", timeBuffer); fprintf(out, "%lu Config in icebox: \n", (unsigned long)mIceBox.size()); for (const auto& configStats : mIceBox) { const int numBytes = configStats.ByteSize(); vector<char> buffer(numBytes); configStats.SerializeToArray(&buffer[0], numBytes); proto.write(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CONFIG_STATS, &buffer[0], buffer.size()); // surround the whole block with DEBUG, so that compiler can strip out the code // in production. if (DEBUG) { VLOG("*****ICEBOX*****"); VLOG("Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, " "#matcher=%d, #alert=%d, #valid=%d", fprintf(out, "Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, " "#matcher=%d, #alert=%d, valid=%d\n", configStats.uid(), (long long)configStats.id(), configStats.creation_time_sec(), configStats.deletion_time_sec(), configStats.metric_count(), configStats.condition_count(), configStats.matcher_count(), configStats.alert_count(), configStats.is_valid()); for (const auto& broadcastTime : configStats.broadcast_sent_time_sec()) { VLOG("\tbroadcast time: %d", broadcastTime); fprintf(out, "\tbroadcast time: %d\n", broadcastTime); } for (const auto& dataDropTime : configStats.data_drop_time_sec()) { VLOG("\tdata drop time: %d", dataDropTime); fprintf(out, "\tdata drop time: %d\n", dataDropTime); } } } fprintf(out, "%lu Active Configs\n", (unsigned long)mConfigStats.size()); for (auto& pair : mConfigStats) { auto& key = pair.first; auto& configStats = pair.second; if (DEBUG) { VLOG("********Active Configs***********"); VLOG("Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, " "#matcher=%d, #alert=%d, #valid=%d", fprintf(out, "Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, " "#matcher=%d, #alert=%d, valid=%d\n", configStats.uid(), (long long)configStats.id(), configStats.creation_time_sec(), configStats.deletion_time_sec(), configStats.metric_count(), configStats.condition_count(), configStats.matcher_count(), configStats.alert_count(), configStats.is_valid()); for (const auto& broadcastTime : configStats.broadcast_sent_time_sec()) { VLOG("\tbroadcast time: %d", broadcastTime); fprintf(out, "\tbroadcast time: %d\n", broadcastTime); } for (const auto& dataDropTime : configStats.data_drop_time_sec()) { VLOG("\tdata drop time: %d", dataDropTime); fprintf(out, "\tdata drop time: %d\n", dataDropTime); } for (const auto& dumpTime : configStats.dump_report_time_sec()) { VLOG("\tdump report time: %d", dumpTime); fprintf(out, "\tdump report time: %d\n", dumpTime); } // Add matcher stats auto matcherIt = mMatcherStats.find(key); if (matcherIt != mMatcherStats.end()) { const auto& matcherStats = matcherIt->second; for (const auto& stats : matcherStats) { fprintf(out, "matcher %lld matched %d times\n", (long long)stats.first, stats.second); } } // Add condition stats auto conditionIt = mConditionStats.find(key); if (conditionIt != mConditionStats.end()) { const auto& conditionStats = conditionIt->second; for (const auto& stats : conditionStats) { fprintf(out, "condition %lld max output tuple size %d\n", (long long)stats.first, stats.second); } } // Add metrics stats auto metricIt = mMetricsStats.find(key); if (metricIt != mMetricsStats.end()) { const auto& conditionStats = metricIt->second; for (const auto& stats : conditionStats) { fprintf(out, "metrics %lld max output tuple size %d\n", (long long)stats.first, stats.second); } } // Add anomaly detection alert stats auto alertIt = mAlertStats.find(key); if (alertIt != mAlertStats.end()) { const auto& alertStats = alertIt->second; for (const auto& stats : alertStats) { fprintf(out, "alert %lld declared %d times\n", (long long)stats.first, stats.second); } } } fprintf(out, "********Pushed Atom stats***********\n"); const size_t atomCounts = mPushedAtomStats.size(); for (size_t i = 2; i < atomCounts; i++) { if (mPushedAtomStats[i] > 0) { fprintf(out, "Atom %lu->%d\n", (unsigned long)i, mPushedAtomStats[i]); } } fprintf(out, "********Pulled Atom stats***********\n"); for (const auto& pair : mPulledAtomStats) { fprintf(out, "Atom %d->%ld, %ld, %ld\n", (int)pair.first, (long)pair.second.totalPull, (long)pair.second.totalPullFromCache, (long)pair.second.minPullIntervalSec); } if (mAnomalyAlarmRegisteredStats > 0) { fprintf(out, "********AnomalyAlarmStats stats***********\n"); fprintf(out, "Anomaly alarm registrations: %d\n", mAnomalyAlarmRegisteredStats); } fprintf(out, "UID map stats: bytes=%d, snapshots=%d, changes=%d, snapshots lost=%d, changes " "lost=%d\n", mUidMapStats.bytes_used(), mUidMapStats.snapshots(), mUidMapStats.changes(), mUidMapStats.dropped_snapshots(), mUidMapStats.dropped_changes()); } void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) { lock_guard<std::mutex> lock(mLock); ProtoOutputStream proto; proto.write(FIELD_TYPE_INT32 | FIELD_ID_BEGIN_TIME, mStartTimeSec); proto.write(FIELD_TYPE_INT32 | FIELD_ID_END_TIME, (int32_t)time(nullptr)); for (const auto& configStats : mIceBox) { const int numBytes = configStats.ByteSize(); vector<char> buffer(numBytes); configStats.SerializeToArray(&buffer[0], numBytes); proto.write(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CONFIG_STATS, &buffer[0], buffer.size()); } for (auto& pair : mConfigStats) { auto& configStats = pair.second; addSubStatsToConfigLocked(pair.first, configStats); const int numBytes = configStats.ByteSize(); Loading @@ -437,7 +499,6 @@ void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) { configStats.clear_alert_stats(); } VLOG("********Pushed Atom stats***********"); const size_t atomCounts = mPushedAtomStats.size(); for (size_t i = 2; i < atomCounts; i++) { if (mPushedAtomStats[i] > 0) { Loading @@ -446,34 +507,24 @@ void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) { proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_TAG, (int32_t)i); proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_COUNT, mPushedAtomStats[i]); proto.end(token); VLOG("Atom %lu->%d\n", (unsigned long)i, mPushedAtomStats[i]); } } VLOG("********Pulled Atom stats***********"); for (const auto& pair : mPulledAtomStats) { android::os::statsd::writePullerStatsToStream(pair, &proto); VLOG("Atom %d->%ld, %ld, %ld\n", (int) pair.first, (long) pair.second.totalPull, (long) pair.second.totalPullFromCache, (long) pair.second.minPullIntervalSec); } if (mAnomalyAlarmRegisteredStats > 0) { VLOG("********AnomalyAlarmStats stats***********"); long long token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ANOMALY_ALARM_STATS); proto.write(FIELD_TYPE_INT32 | FIELD_ID_ANOMALY_ALARMS_REGISTERED, mAnomalyAlarmRegisteredStats); proto.end(token); VLOG("Anomaly alarm registrations: %d", mAnomalyAlarmRegisteredStats); } const int numBytes = mUidMapStats.ByteSize(); vector<char> buffer(numBytes); mUidMapStats.SerializeToArray(&buffer[0], numBytes); proto.write(FIELD_TYPE_MESSAGE | FIELD_ID_UIDMAP_STATS, &buffer[0], buffer.size()); VLOG("UID map stats: bytes=%d, snapshots=%d, changes=%d, snapshots lost=%d, changes " "lost=%d", mUidMapStats.bytes_used(), mUidMapStats.snapshots(), mUidMapStats.changes(), mUidMapStats.dropped_snapshots(), mUidMapStats.dropped_changes()); output->clear(); size_t bufferSize = proto.size(); Loading @@ -493,7 +544,6 @@ void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) { } VLOG("reset=%d, returned proto size %lu", reset, (unsigned long)bufferSize); VLOG("=================StatsdStats dump ends===================="); } } // namespace statsd Loading cmds/statsd/src/guardrail/StatsdStats.h +5 −0 Original line number Diff line number Diff line Loading @@ -189,6 +189,11 @@ public: */ void dumpStats(std::vector<uint8_t>* buffer, bool reset); /** * Output statsd stats in human readable format to [out] file. */ void dumpStats(FILE* out) const; typedef struct { long totalPull; long totalPullFromCache; Loading Loading
cmds/statsd/src/StatsService.cpp +3 −9 Original line number Diff line number Diff line Loading @@ -185,6 +185,7 @@ status_t StatsService::dump(int fd, const Vector<String16>& args) { */ void StatsService::dump_impl(FILE* out) { mConfigManager->Dump(out); StatsdStats::getInstance().dumpStats(out); } /** Loading Loading @@ -296,9 +297,8 @@ void StatsService::print_cmd_help(FILE* out) { fprintf(out, " NAME The name of the configuration\n"); fprintf(out, "\n"); fprintf(out, "\n"); fprintf(out, "usage: adb shell cmd stats print-stats [reset]\n"); fprintf(out, "usage: adb shell cmd stats print-stats\n"); fprintf(out, " Prints some basic stats.\n"); fprintf(out, " reset: 1 to reset the statsd stats. default=0.\n"); } status_t StatsService::cmd_trigger_broadcast(FILE* out, Vector<String8>& args) { Loading Loading @@ -487,14 +487,8 @@ status_t StatsService::cmd_print_stats(FILE* out, const Vector<String8>& args) { fprintf(out, "Config %s uses %zu bytes\n", key.ToString().c_str(), mProcessor->GetMetricsSize(key)); } fprintf(out, "Detailed statsd stats in logcat...\n"); StatsdStats& statsdStats = StatsdStats::getInstance(); bool reset = false; if (args.size() > 1) { reset = strtol(args[1].string(), NULL, 10); } vector<uint8_t> output; statsdStats.dumpStats(&output, reset); statsdStats.dumpStats(out); return NO_ERROR; } Loading
cmds/statsd/src/guardrail/StatsdStats.cpp +112 −62 Original line number Diff line number Diff line Loading @@ -355,73 +355,135 @@ void StatsdStats::addSubStatsToConfigLocked(const ConfigKey& key, } } void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) { void StatsdStats::dumpStats(FILE* out) const { lock_guard<std::mutex> lock(mLock); if (DEBUG) { time_t t = mStartTimeSec; struct tm* tm = localtime(&t); char timeBuffer[80]; strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p", tm); VLOG("=================StatsdStats dump begins===================="); VLOG("Stats collection start second: %s", timeBuffer); } ProtoOutputStream proto; proto.write(FIELD_TYPE_INT32 | FIELD_ID_BEGIN_TIME, mStartTimeSec); proto.write(FIELD_TYPE_INT32 | FIELD_ID_END_TIME, (int32_t)time(nullptr)); VLOG("%lu Config in icebox: ", (unsigned long)mIceBox.size()); strftime(timeBuffer, sizeof(timeBuffer), "%Y-%m-%d %I:%M%p\n", tm); fprintf(out, "Stats collection start second: %s\n", timeBuffer); fprintf(out, "%lu Config in icebox: \n", (unsigned long)mIceBox.size()); for (const auto& configStats : mIceBox) { const int numBytes = configStats.ByteSize(); vector<char> buffer(numBytes); configStats.SerializeToArray(&buffer[0], numBytes); proto.write(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CONFIG_STATS, &buffer[0], buffer.size()); // surround the whole block with DEBUG, so that compiler can strip out the code // in production. if (DEBUG) { VLOG("*****ICEBOX*****"); VLOG("Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, " "#matcher=%d, #alert=%d, #valid=%d", fprintf(out, "Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, " "#matcher=%d, #alert=%d, valid=%d\n", configStats.uid(), (long long)configStats.id(), configStats.creation_time_sec(), configStats.deletion_time_sec(), configStats.metric_count(), configStats.condition_count(), configStats.matcher_count(), configStats.alert_count(), configStats.is_valid()); for (const auto& broadcastTime : configStats.broadcast_sent_time_sec()) { VLOG("\tbroadcast time: %d", broadcastTime); fprintf(out, "\tbroadcast time: %d\n", broadcastTime); } for (const auto& dataDropTime : configStats.data_drop_time_sec()) { VLOG("\tdata drop time: %d", dataDropTime); fprintf(out, "\tdata drop time: %d\n", dataDropTime); } } } fprintf(out, "%lu Active Configs\n", (unsigned long)mConfigStats.size()); for (auto& pair : mConfigStats) { auto& key = pair.first; auto& configStats = pair.second; if (DEBUG) { VLOG("********Active Configs***********"); VLOG("Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, " "#matcher=%d, #alert=%d, #valid=%d", fprintf(out, "Config {%d-%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, " "#matcher=%d, #alert=%d, valid=%d\n", configStats.uid(), (long long)configStats.id(), configStats.creation_time_sec(), configStats.deletion_time_sec(), configStats.metric_count(), configStats.condition_count(), configStats.matcher_count(), configStats.alert_count(), configStats.is_valid()); for (const auto& broadcastTime : configStats.broadcast_sent_time_sec()) { VLOG("\tbroadcast time: %d", broadcastTime); fprintf(out, "\tbroadcast time: %d\n", broadcastTime); } for (const auto& dataDropTime : configStats.data_drop_time_sec()) { VLOG("\tdata drop time: %d", dataDropTime); fprintf(out, "\tdata drop time: %d\n", dataDropTime); } for (const auto& dumpTime : configStats.dump_report_time_sec()) { VLOG("\tdump report time: %d", dumpTime); fprintf(out, "\tdump report time: %d\n", dumpTime); } // Add matcher stats auto matcherIt = mMatcherStats.find(key); if (matcherIt != mMatcherStats.end()) { const auto& matcherStats = matcherIt->second; for (const auto& stats : matcherStats) { fprintf(out, "matcher %lld matched %d times\n", (long long)stats.first, stats.second); } } // Add condition stats auto conditionIt = mConditionStats.find(key); if (conditionIt != mConditionStats.end()) { const auto& conditionStats = conditionIt->second; for (const auto& stats : conditionStats) { fprintf(out, "condition %lld max output tuple size %d\n", (long long)stats.first, stats.second); } } // Add metrics stats auto metricIt = mMetricsStats.find(key); if (metricIt != mMetricsStats.end()) { const auto& conditionStats = metricIt->second; for (const auto& stats : conditionStats) { fprintf(out, "metrics %lld max output tuple size %d\n", (long long)stats.first, stats.second); } } // Add anomaly detection alert stats auto alertIt = mAlertStats.find(key); if (alertIt != mAlertStats.end()) { const auto& alertStats = alertIt->second; for (const auto& stats : alertStats) { fprintf(out, "alert %lld declared %d times\n", (long long)stats.first, stats.second); } } } fprintf(out, "********Pushed Atom stats***********\n"); const size_t atomCounts = mPushedAtomStats.size(); for (size_t i = 2; i < atomCounts; i++) { if (mPushedAtomStats[i] > 0) { fprintf(out, "Atom %lu->%d\n", (unsigned long)i, mPushedAtomStats[i]); } } fprintf(out, "********Pulled Atom stats***********\n"); for (const auto& pair : mPulledAtomStats) { fprintf(out, "Atom %d->%ld, %ld, %ld\n", (int)pair.first, (long)pair.second.totalPull, (long)pair.second.totalPullFromCache, (long)pair.second.minPullIntervalSec); } if (mAnomalyAlarmRegisteredStats > 0) { fprintf(out, "********AnomalyAlarmStats stats***********\n"); fprintf(out, "Anomaly alarm registrations: %d\n", mAnomalyAlarmRegisteredStats); } fprintf(out, "UID map stats: bytes=%d, snapshots=%d, changes=%d, snapshots lost=%d, changes " "lost=%d\n", mUidMapStats.bytes_used(), mUidMapStats.snapshots(), mUidMapStats.changes(), mUidMapStats.dropped_snapshots(), mUidMapStats.dropped_changes()); } void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) { lock_guard<std::mutex> lock(mLock); ProtoOutputStream proto; proto.write(FIELD_TYPE_INT32 | FIELD_ID_BEGIN_TIME, mStartTimeSec); proto.write(FIELD_TYPE_INT32 | FIELD_ID_END_TIME, (int32_t)time(nullptr)); for (const auto& configStats : mIceBox) { const int numBytes = configStats.ByteSize(); vector<char> buffer(numBytes); configStats.SerializeToArray(&buffer[0], numBytes); proto.write(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_CONFIG_STATS, &buffer[0], buffer.size()); } for (auto& pair : mConfigStats) { auto& configStats = pair.second; addSubStatsToConfigLocked(pair.first, configStats); const int numBytes = configStats.ByteSize(); Loading @@ -437,7 +499,6 @@ void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) { configStats.clear_alert_stats(); } VLOG("********Pushed Atom stats***********"); const size_t atomCounts = mPushedAtomStats.size(); for (size_t i = 2; i < atomCounts; i++) { if (mPushedAtomStats[i] > 0) { Loading @@ -446,34 +507,24 @@ void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) { proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_TAG, (int32_t)i); proto.write(FIELD_TYPE_INT32 | FIELD_ID_ATOM_STATS_COUNT, mPushedAtomStats[i]); proto.end(token); VLOG("Atom %lu->%d\n", (unsigned long)i, mPushedAtomStats[i]); } } VLOG("********Pulled Atom stats***********"); for (const auto& pair : mPulledAtomStats) { android::os::statsd::writePullerStatsToStream(pair, &proto); VLOG("Atom %d->%ld, %ld, %ld\n", (int) pair.first, (long) pair.second.totalPull, (long) pair.second.totalPullFromCache, (long) pair.second.minPullIntervalSec); } if (mAnomalyAlarmRegisteredStats > 0) { VLOG("********AnomalyAlarmStats stats***********"); long long token = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_ANOMALY_ALARM_STATS); proto.write(FIELD_TYPE_INT32 | FIELD_ID_ANOMALY_ALARMS_REGISTERED, mAnomalyAlarmRegisteredStats); proto.end(token); VLOG("Anomaly alarm registrations: %d", mAnomalyAlarmRegisteredStats); } const int numBytes = mUidMapStats.ByteSize(); vector<char> buffer(numBytes); mUidMapStats.SerializeToArray(&buffer[0], numBytes); proto.write(FIELD_TYPE_MESSAGE | FIELD_ID_UIDMAP_STATS, &buffer[0], buffer.size()); VLOG("UID map stats: bytes=%d, snapshots=%d, changes=%d, snapshots lost=%d, changes " "lost=%d", mUidMapStats.bytes_used(), mUidMapStats.snapshots(), mUidMapStats.changes(), mUidMapStats.dropped_snapshots(), mUidMapStats.dropped_changes()); output->clear(); size_t bufferSize = proto.size(); Loading @@ -493,7 +544,6 @@ void StatsdStats::dumpStats(std::vector<uint8_t>* output, bool reset) { } VLOG("reset=%d, returned proto size %lu", reset, (unsigned long)bufferSize); VLOG("=================StatsdStats dump ends===================="); } } // namespace statsd Loading
cmds/statsd/src/guardrail/StatsdStats.h +5 −0 Original line number Diff line number Diff line Loading @@ -189,6 +189,11 @@ public: */ void dumpStats(std::vector<uint8_t>* buffer, bool reset); /** * Output statsd stats in human readable format to [out] file. */ void dumpStats(FILE* out) const; typedef struct { long totalPull; long totalPullFromCache; Loading