Loading cmds/statsd/src/StatsLogProcessor.cpp +26 −13 Original line number Diff line number Diff line Loading @@ -276,22 +276,21 @@ void StatsLogProcessor::dumpStates(int out, bool verbose) { */ void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs, const bool include_current_partial_bucket, const bool erase_data, const DumpReportReason dumpReportReason, vector<uint8_t>* outData) { ProtoOutputStream* proto) { std::lock_guard<std::mutex> lock(mMetricsMutex); ProtoOutputStream proto; // Start of ConfigKey. uint64_t configKeyToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY); proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID, key.GetUid()); proto.write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)key.GetId()); proto.end(configKeyToken); uint64_t configKeyToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY); proto->write(FIELD_TYPE_INT32 | FIELD_ID_UID, key.GetUid()); proto->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)key.GetId()); proto->end(configKeyToken); // End of ConfigKey. // Then, check stats-data directory to see there's any file containing // ConfigMetricsReport from previous shutdowns to concatenate to reports. StorageManager::appendConfigMetricsReport(key, &proto); StorageManager::appendConfigMetricsReport(key, proto); auto it = mMetricsManagers.find(key); if (it != mMetricsManagers.end()) { Loading @@ -301,14 +300,27 @@ void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTim // Start of ConfigMetricsReport (reports). uint64_t reportsToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS); proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS); onConfigMetricsReportLocked(key, dumpTimeStampNs, include_current_partial_bucket, dumpReportReason, &proto); proto.end(reportsToken); erase_data, dumpReportReason, proto); proto->end(reportsToken); // End of ConfigMetricsReport (reports). } else { ALOGW("Config source %s does not exist", key.ToString().c_str()); } } /* * onDumpReport dumps serialized ConfigMetricsReportList into outData. */ void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs, const bool include_current_partial_bucket, const bool erase_data, const DumpReportReason dumpReportReason, vector<uint8_t>* outData) { ProtoOutputStream proto; onDumpReport(key, dumpTimeStampNs, include_current_partial_bucket, erase_data, dumpReportReason, &proto); if (outData != nullptr) { outData->clear(); Loading @@ -332,6 +344,7 @@ void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTim void StatsLogProcessor::onConfigMetricsReportLocked(const ConfigKey& key, const int64_t dumpTimeStampNs, const bool include_current_partial_bucket, const bool erase_data, const DumpReportReason dumpReportReason, ProtoOutputStream* proto) { // We already checked whether key exists in mMetricsManagers in Loading @@ -348,7 +361,7 @@ void StatsLogProcessor::onConfigMetricsReportLocked(const ConfigKey& key, // First, fill in ConfigMetricsReport using current data on memory, which // starts from filling in StatsLogReport's. it->second->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, &str_set, proto); erase_data, &str_set, proto); // Fill in UidMap if there is at least one metric to report. // This skips the uid map if it's an empty config. Loading Loading @@ -479,7 +492,7 @@ void StatsLogProcessor::WriteDataToDiskLocked(const ConfigKey& key, } ProtoOutputStream proto; onConfigMetricsReportLocked(key, timestampNs, true /* include_current_partial_bucket*/, dumpReportReason, &proto); true /* erase_data */, dumpReportReason, &proto); string file_name = StringPrintf("%s/%ld_%d_%lld", STATS_DATA_DIR, (long)getWallClockSec(), key.GetUid(), (long long)key.GetId()); android::base::unique_fd fd(open(file_name.c_str(), Loading cmds/statsd/src/StatsLogProcessor.h +5 −1 Original line number Diff line number Diff line Loading @@ -61,8 +61,11 @@ public: size_t GetMetricsSize(const ConfigKey& key) const; void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs, const bool include_current_partial_bucket, const bool include_current_partial_bucket, const bool erase_data, const DumpReportReason dumpReportReason, vector<uint8_t>* outData); void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs, const bool include_current_partial_bucket, const bool erase_data, const DumpReportReason dumpReportReason, ProtoOutputStream* proto); /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */ void onAnomalyAlarmFired( Loading Loading @@ -141,6 +144,7 @@ private: void onConfigMetricsReportLocked(const ConfigKey& key, const int64_t dumpTimeStampNs, const bool include_current_partial_bucket, const bool erase_data, const DumpReportReason dumpReportReason, util::ProtoOutputStream* proto); Loading cmds/statsd/src/StatsService.cpp +54 −17 Original line number Diff line number Diff line Loading @@ -46,6 +46,8 @@ using namespace android; using android::base::StringPrintf; using android::util::FIELD_COUNT_REPEATED; using android::util::FIELD_TYPE_MESSAGE; namespace android { namespace os { Loading @@ -58,6 +60,9 @@ constexpr const char* kOpUsage = "android:get_usage_stats"; #define STATS_SERVICE_DIR "/data/misc/stats-service" // for StatsDataDumpProto const int FIELD_ID_REPORTS_LIST = 1; static binder::Status ok() { return binder::Status::ok(); } Loading Loading @@ -224,23 +229,40 @@ status_t StatsService::onTransact(uint32_t code, const Parcel& data, Parcel* rep } /** * Write debugging data about statsd. * Write data from statsd. * Format for statsdStats: adb shell dumpsys stats --metadata [-v] [--proto] * Format for data report: adb shell dumpsys stats [anything other than --metadata] [--proto] * Anything ending in --proto will be in proto format. * Anything without --metadata as the first argument will be report information. * (bugreports call "adb shell dumpsys stats --dump-priority NORMAL -a --proto") * TODO: Come up with a more robust method of enacting <serviceutils/PriorityDumper.h>. */ status_t StatsService::dump(int fd, const Vector<String16>& args) { if (!checkCallingPermission(String16(kPermissionDump))) { return PERMISSION_DENIED; } int lastArg = args.size() - 1; bool asProto = false; if (lastArg >= 0 && !args[lastArg].compare(String16("--proto"))) { // last argument asProto = true; lastArg--; } if (args.size() > 0 && !args[0].compare(String16("--metadata"))) { // first argument // Request is to dump statsd stats. bool verbose = false; bool proto = false; if (args.size() > 0 && !args[0].compare(String16("-v"))) { if (lastArg >= 0 && !args[lastArg].compare(String16("-v"))) { verbose = true; lastArg--; } dumpStatsdStats(fd, verbose, asProto); } else { // Request is to dump statsd report data. if (asProto) { dumpIncidentSection(fd); } else { dprintf(fd, "Non-proto format of stats data dump not available; see proto version.\n"); } if (args.size() > 0 && !args[args.size()-1].compare(String16("--proto"))) { proto = true; } dump_impl(fd, verbose, proto); return NO_ERROR; } Loading @@ -248,7 +270,7 @@ status_t StatsService::dump(int fd, const Vector<String16>& args) { /** * Write debugging data about statsd in text or proto format. */ void StatsService::dump_impl(int out, bool verbose, bool proto) { void StatsService::dumpStatsdStats(int out, bool verbose, bool proto) { if (proto) { vector<uint8_t> data; StatsdStats::getInstance().dumpStats(&data, false); // does not reset statsdStats. Loading @@ -261,6 +283,22 @@ void StatsService::dump_impl(int out, bool verbose, bool proto) { } } /** * Write stats report data in StatsDataDumpProto incident section format. */ void StatsService::dumpIncidentSection(int out) { ProtoOutputStream proto; for (const ConfigKey& configKey : mConfigManager->GetAllConfigKeys()) { uint64_t reportsListToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS_LIST); mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), true /* includeCurrentBucket */, false /* erase_data */, ADB_DUMP, &proto); proto.end(reportsListToken); proto.flush(out); } } /** * Implementation of the adb shell cmd stats command. */ Loading @@ -283,7 +321,7 @@ status_t StatsService::command(int in, int out, int err, Vector<String8>& args, } if (!args[0].compare(String8("dump-report"))) { return cmd_dump_report(out, err, args); return cmd_dump_report(out, args); } if (!args[0].compare(String8("pull-source")) && args.size() > 1) { Loading Loading @@ -546,7 +584,7 @@ status_t StatsService::cmd_config(int in, int out, int err, Vector<String8>& arg return UNKNOWN_ERROR; } status_t StatsService::cmd_dump_report(int out, int err, const Vector<String8>& args) { status_t StatsService::cmd_dump_report(int out, const Vector<String8>& args) { if (mProcessor != nullptr) { int argCount = args.size(); bool good = false; Loading Loading @@ -589,14 +627,13 @@ status_t StatsService::cmd_dump_report(int out, int err, const Vector<String8>& if (good) { vector<uint8_t> data; mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), getElapsedRealtimeNs(), includeCurrentBucket, ADB_DUMP, &data); includeCurrentBucket, true /* erase_data */, ADB_DUMP, &data); if (proto) { for (size_t i = 0; i < data.size(); i ++) { dprintf(out, "%c", data[i]); } } else { dprintf(out, "Dump report for Config [%d,%s]\n", uid, name.c_str()); dprintf(out, "See the StatsLogReport in logcat...\n"); dprintf(out, "Non-proto stats data dump not currently supported.\n"); } return android::OK; } else { Loading Loading @@ -888,7 +925,7 @@ Status StatsService::getData(int64_t key, const String16& packageName, vector<ui VLOG("StatsService::getData with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid()); ConfigKey configKey(ipc->getCallingUid(), key); mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), false /* include_current_bucket*/, GET_DATA_CALLED, output); true /* erase_data */, GET_DATA_CALLED, output); return Status::ok(); } Loading cmds/statsd/src/StatsService.h +8 −3 Original line number Diff line number Diff line Loading @@ -213,9 +213,14 @@ private: uint32_t serial); /** * Text or proto output of dumpsys. * Proto output of statsd report data dumpsys, wrapped in a StatsDataDumpProto. */ void dump_impl(int outFd, bool verbose, bool proto); void dumpIncidentSection(int outFd); /** * Text or proto output of statsdStats dumpsys. */ void dumpStatsdStats(int outFd, bool verbose, bool proto); /** * Print usage information for the commands Loading @@ -240,7 +245,7 @@ private: /** * Print the event log. */ status_t cmd_dump_report(int outFd, int err, const Vector<String8>& args); status_t cmd_dump_report(int outFd, const Vector<String8>& args); /** * Print the mapping of uids to package names. Loading cmds/statsd/src/main.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -82,7 +82,9 @@ int main(int /*argc*/, char** /*argv*/) { // Create the service gStatsService = new StatsService(looper); if (defaultServiceManager()->addService(String16("stats"), gStatsService) != 0) { if (defaultServiceManager()->addService(String16("stats"), gStatsService, false, IServiceManager::DUMP_FLAG_PRIORITY_NORMAL | IServiceManager::DUMP_FLAG_PROTO) != 0) { ALOGE("Failed to add service as AIDL service"); return -1; } Loading Loading
cmds/statsd/src/StatsLogProcessor.cpp +26 −13 Original line number Diff line number Diff line Loading @@ -276,22 +276,21 @@ void StatsLogProcessor::dumpStates(int out, bool verbose) { */ void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs, const bool include_current_partial_bucket, const bool erase_data, const DumpReportReason dumpReportReason, vector<uint8_t>* outData) { ProtoOutputStream* proto) { std::lock_guard<std::mutex> lock(mMetricsMutex); ProtoOutputStream proto; // Start of ConfigKey. uint64_t configKeyToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY); proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID, key.GetUid()); proto.write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)key.GetId()); proto.end(configKeyToken); uint64_t configKeyToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY); proto->write(FIELD_TYPE_INT32 | FIELD_ID_UID, key.GetUid()); proto->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)key.GetId()); proto->end(configKeyToken); // End of ConfigKey. // Then, check stats-data directory to see there's any file containing // ConfigMetricsReport from previous shutdowns to concatenate to reports. StorageManager::appendConfigMetricsReport(key, &proto); StorageManager::appendConfigMetricsReport(key, proto); auto it = mMetricsManagers.find(key); if (it != mMetricsManagers.end()) { Loading @@ -301,14 +300,27 @@ void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTim // Start of ConfigMetricsReport (reports). uint64_t reportsToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS); proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS); onConfigMetricsReportLocked(key, dumpTimeStampNs, include_current_partial_bucket, dumpReportReason, &proto); proto.end(reportsToken); erase_data, dumpReportReason, proto); proto->end(reportsToken); // End of ConfigMetricsReport (reports). } else { ALOGW("Config source %s does not exist", key.ToString().c_str()); } } /* * onDumpReport dumps serialized ConfigMetricsReportList into outData. */ void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs, const bool include_current_partial_bucket, const bool erase_data, const DumpReportReason dumpReportReason, vector<uint8_t>* outData) { ProtoOutputStream proto; onDumpReport(key, dumpTimeStampNs, include_current_partial_bucket, erase_data, dumpReportReason, &proto); if (outData != nullptr) { outData->clear(); Loading @@ -332,6 +344,7 @@ void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTim void StatsLogProcessor::onConfigMetricsReportLocked(const ConfigKey& key, const int64_t dumpTimeStampNs, const bool include_current_partial_bucket, const bool erase_data, const DumpReportReason dumpReportReason, ProtoOutputStream* proto) { // We already checked whether key exists in mMetricsManagers in Loading @@ -348,7 +361,7 @@ void StatsLogProcessor::onConfigMetricsReportLocked(const ConfigKey& key, // First, fill in ConfigMetricsReport using current data on memory, which // starts from filling in StatsLogReport's. it->second->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, &str_set, proto); erase_data, &str_set, proto); // Fill in UidMap if there is at least one metric to report. // This skips the uid map if it's an empty config. Loading Loading @@ -479,7 +492,7 @@ void StatsLogProcessor::WriteDataToDiskLocked(const ConfigKey& key, } ProtoOutputStream proto; onConfigMetricsReportLocked(key, timestampNs, true /* include_current_partial_bucket*/, dumpReportReason, &proto); true /* erase_data */, dumpReportReason, &proto); string file_name = StringPrintf("%s/%ld_%d_%lld", STATS_DATA_DIR, (long)getWallClockSec(), key.GetUid(), (long long)key.GetId()); android::base::unique_fd fd(open(file_name.c_str(), Loading
cmds/statsd/src/StatsLogProcessor.h +5 −1 Original line number Diff line number Diff line Loading @@ -61,8 +61,11 @@ public: size_t GetMetricsSize(const ConfigKey& key) const; void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs, const bool include_current_partial_bucket, const bool include_current_partial_bucket, const bool erase_data, const DumpReportReason dumpReportReason, vector<uint8_t>* outData); void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs, const bool include_current_partial_bucket, const bool erase_data, const DumpReportReason dumpReportReason, ProtoOutputStream* proto); /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */ void onAnomalyAlarmFired( Loading Loading @@ -141,6 +144,7 @@ private: void onConfigMetricsReportLocked(const ConfigKey& key, const int64_t dumpTimeStampNs, const bool include_current_partial_bucket, const bool erase_data, const DumpReportReason dumpReportReason, util::ProtoOutputStream* proto); Loading
cmds/statsd/src/StatsService.cpp +54 −17 Original line number Diff line number Diff line Loading @@ -46,6 +46,8 @@ using namespace android; using android::base::StringPrintf; using android::util::FIELD_COUNT_REPEATED; using android::util::FIELD_TYPE_MESSAGE; namespace android { namespace os { Loading @@ -58,6 +60,9 @@ constexpr const char* kOpUsage = "android:get_usage_stats"; #define STATS_SERVICE_DIR "/data/misc/stats-service" // for StatsDataDumpProto const int FIELD_ID_REPORTS_LIST = 1; static binder::Status ok() { return binder::Status::ok(); } Loading Loading @@ -224,23 +229,40 @@ status_t StatsService::onTransact(uint32_t code, const Parcel& data, Parcel* rep } /** * Write debugging data about statsd. * Write data from statsd. * Format for statsdStats: adb shell dumpsys stats --metadata [-v] [--proto] * Format for data report: adb shell dumpsys stats [anything other than --metadata] [--proto] * Anything ending in --proto will be in proto format. * Anything without --metadata as the first argument will be report information. * (bugreports call "adb shell dumpsys stats --dump-priority NORMAL -a --proto") * TODO: Come up with a more robust method of enacting <serviceutils/PriorityDumper.h>. */ status_t StatsService::dump(int fd, const Vector<String16>& args) { if (!checkCallingPermission(String16(kPermissionDump))) { return PERMISSION_DENIED; } int lastArg = args.size() - 1; bool asProto = false; if (lastArg >= 0 && !args[lastArg].compare(String16("--proto"))) { // last argument asProto = true; lastArg--; } if (args.size() > 0 && !args[0].compare(String16("--metadata"))) { // first argument // Request is to dump statsd stats. bool verbose = false; bool proto = false; if (args.size() > 0 && !args[0].compare(String16("-v"))) { if (lastArg >= 0 && !args[lastArg].compare(String16("-v"))) { verbose = true; lastArg--; } dumpStatsdStats(fd, verbose, asProto); } else { // Request is to dump statsd report data. if (asProto) { dumpIncidentSection(fd); } else { dprintf(fd, "Non-proto format of stats data dump not available; see proto version.\n"); } if (args.size() > 0 && !args[args.size()-1].compare(String16("--proto"))) { proto = true; } dump_impl(fd, verbose, proto); return NO_ERROR; } Loading @@ -248,7 +270,7 @@ status_t StatsService::dump(int fd, const Vector<String16>& args) { /** * Write debugging data about statsd in text or proto format. */ void StatsService::dump_impl(int out, bool verbose, bool proto) { void StatsService::dumpStatsdStats(int out, bool verbose, bool proto) { if (proto) { vector<uint8_t> data; StatsdStats::getInstance().dumpStats(&data, false); // does not reset statsdStats. Loading @@ -261,6 +283,22 @@ void StatsService::dump_impl(int out, bool verbose, bool proto) { } } /** * Write stats report data in StatsDataDumpProto incident section format. */ void StatsService::dumpIncidentSection(int out) { ProtoOutputStream proto; for (const ConfigKey& configKey : mConfigManager->GetAllConfigKeys()) { uint64_t reportsListToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS_LIST); mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), true /* includeCurrentBucket */, false /* erase_data */, ADB_DUMP, &proto); proto.end(reportsListToken); proto.flush(out); } } /** * Implementation of the adb shell cmd stats command. */ Loading @@ -283,7 +321,7 @@ status_t StatsService::command(int in, int out, int err, Vector<String8>& args, } if (!args[0].compare(String8("dump-report"))) { return cmd_dump_report(out, err, args); return cmd_dump_report(out, args); } if (!args[0].compare(String8("pull-source")) && args.size() > 1) { Loading Loading @@ -546,7 +584,7 @@ status_t StatsService::cmd_config(int in, int out, int err, Vector<String8>& arg return UNKNOWN_ERROR; } status_t StatsService::cmd_dump_report(int out, int err, const Vector<String8>& args) { status_t StatsService::cmd_dump_report(int out, const Vector<String8>& args) { if (mProcessor != nullptr) { int argCount = args.size(); bool good = false; Loading Loading @@ -589,14 +627,13 @@ status_t StatsService::cmd_dump_report(int out, int err, const Vector<String8>& if (good) { vector<uint8_t> data; mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), getElapsedRealtimeNs(), includeCurrentBucket, ADB_DUMP, &data); includeCurrentBucket, true /* erase_data */, ADB_DUMP, &data); if (proto) { for (size_t i = 0; i < data.size(); i ++) { dprintf(out, "%c", data[i]); } } else { dprintf(out, "Dump report for Config [%d,%s]\n", uid, name.c_str()); dprintf(out, "See the StatsLogReport in logcat...\n"); dprintf(out, "Non-proto stats data dump not currently supported.\n"); } return android::OK; } else { Loading Loading @@ -888,7 +925,7 @@ Status StatsService::getData(int64_t key, const String16& packageName, vector<ui VLOG("StatsService::getData with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid()); ConfigKey configKey(ipc->getCallingUid(), key); mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), false /* include_current_bucket*/, GET_DATA_CALLED, output); true /* erase_data */, GET_DATA_CALLED, output); return Status::ok(); } Loading
cmds/statsd/src/StatsService.h +8 −3 Original line number Diff line number Diff line Loading @@ -213,9 +213,14 @@ private: uint32_t serial); /** * Text or proto output of dumpsys. * Proto output of statsd report data dumpsys, wrapped in a StatsDataDumpProto. */ void dump_impl(int outFd, bool verbose, bool proto); void dumpIncidentSection(int outFd); /** * Text or proto output of statsdStats dumpsys. */ void dumpStatsdStats(int outFd, bool verbose, bool proto); /** * Print usage information for the commands Loading @@ -240,7 +245,7 @@ private: /** * Print the event log. */ status_t cmd_dump_report(int outFd, int err, const Vector<String8>& args); status_t cmd_dump_report(int outFd, const Vector<String8>& args); /** * Print the mapping of uids to package names. Loading
cmds/statsd/src/main.cpp +3 −1 Original line number Diff line number Diff line Loading @@ -82,7 +82,9 @@ int main(int /*argc*/, char** /*argv*/) { // Create the service gStatsService = new StatsService(looper); if (defaultServiceManager()->addService(String16("stats"), gStatsService) != 0) { if (defaultServiceManager()->addService(String16("stats"), gStatsService, false, IServiceManager::DUMP_FLAG_PRIORITY_NORMAL | IServiceManager::DUMP_FLAG_PROTO) != 0) { ALOGE("Failed to add service as AIDL service"); return -1; } Loading