From 2e8f3807379f5d5d151ad2cb434d8a7aca910238 Mon Sep 17 00:00:00 2001 From: David Chen Date: Wed, 22 Nov 2017 10:56:48 -0800 Subject: [PATCH] Adds new API to retrieve statsd metadata. This API can be used by clients to gather stats about statsd, eg. memory usage, number of metrics/matchers, etc. This data can be used to debug if devices are not providing expected metrics. The metadata will be for all configurations, but will not contain the actual collected metrics since those might have privacy implications. Test: Tests that statsd and Android still build. Bug: 69522276 Change-Id: I8e0fedc142f5deed7be6e6309f9444e67d8369ce --- api/system-current.txt | 1 + cmds/statsd/src/StatsService.cpp | 12 ++++++++++ cmds/statsd/src/StatsService.h | 5 ++++ core/java/android/os/IStatsManager.aidl | 7 +++++- core/java/android/util/StatsManager.java | 29 ++++++++++++++++++++++-- 5 files changed, 51 insertions(+), 3 deletions(-) diff --git a/api/system-current.txt b/api/system-current.txt index 50a8ea4717cb5..16404e47ebec0 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4332,6 +4332,7 @@ package android.util { public final class StatsManager { method public boolean addConfiguration(java.lang.String, byte[], java.lang.String, java.lang.String); method public byte[] getData(java.lang.String); + method public byte[] getMetadata(); method public boolean removeConfiguration(java.lang.String); } diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp index eb3ea0ba0d13f..0e9cd3b2a1481 100644 --- a/cmds/statsd/src/StatsService.cpp +++ b/cmds/statsd/src/StatsService.cpp @@ -715,6 +715,18 @@ Status StatsService::getData(const String16& key, vector* output) { } } +Status StatsService::getMetadata(vector* output) { + IPCThreadState* ipc = IPCThreadState::self(); + VLOG("StatsService::getMetadata with Pid %i, Uid %i", ipc->getCallingPid(), + ipc->getCallingUid()); + if (checkCallingPermission(String16(kPermissionDump))) { + StatsdStats::getInstance().dumpStats(output, false); // Don't reset the counters. + return Status::ok(); + } else { + return Status::fromExceptionCode(binder::Status::EX_SECURITY); + } +} + Status StatsService::addConfiguration(const String16& key, const vector & config, const String16& package, const String16& cls, diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h index 007227e325f73..03bc6d93ee036 100644 --- a/cmds/statsd/src/StatsService.h +++ b/cmds/statsd/src/StatsService.h @@ -75,6 +75,11 @@ public: */ virtual Status getData(const String16& key, vector* output) override; + /** + * Binder call for clients to get metadata across all configs in statsd. + */ + virtual Status getMetadata(vector* output) override; + /** * Binder call to let clients send a configuration and indicate they're interested when they * should requestData for this configuration. diff --git a/core/java/android/os/IStatsManager.aidl b/core/java/android/os/IStatsManager.aidl index b814b46a31828..c8c428e9417bc 100644 --- a/core/java/android/os/IStatsManager.aidl +++ b/core/java/android/os/IStatsManager.aidl @@ -69,10 +69,15 @@ interface IStatsManager { /** * Fetches data for the specified configuration key. Returns a byte array representing proto - * wire-encoded of ConfigMetricsReport. + * wire-encoded of ConfigMetricsReportList. */ byte[] getData(in String key); + /** + * Fetches metadata across statsd. Returns byte array representing wire-encoded proto. + */ + byte[] getMetadata(); + /** * Sets a configuration with the specified config key and subscribes to updates for this * configuration key. Broadcasts will be sent if this configuration needs to be collected. diff --git a/core/java/android/util/StatsManager.java b/core/java/android/util/StatsManager.java index 2bcd863cd4094..26a3c361e8c14 100644 --- a/core/java/android/util/StatsManager.java +++ b/core/java/android/util/StatsManager.java @@ -93,10 +93,11 @@ public final class StatsManager { } /** - * Clients can request data with a binder call. + * Clients can request data with a binder call. This getter is destructive and also clears + * the retrieved metrics from statsd memory. * * @param configKey Configuration key to retrieve data from. - * @return Serialized ConfigMetricsReport proto. Returns null on failure. + * @return Serialized ConfigMetricsReportList proto. Returns null on failure. */ @RequiresPermission(Manifest.permission.DUMP) public byte[] getData(String configKey) { @@ -115,6 +116,30 @@ public final class StatsManager { } } + /** + * Clients can request metadata for statsd. Will contain stats across all configurations but not + * the actual metrics themselves (metrics must be collected via {@link #getData(String)}. + * This getter is not destructive and will not reset any metrics/counters. + * + * @return Serialized StatsdStatsReport proto. Returns null on failure. + */ + @RequiresPermission(Manifest.permission.DUMP) + public byte[] getMetadata() { + synchronized (this) { + try { + IStatsManager service = getIStatsManagerLocked(); + if (service == null) { + Slog.d(TAG, "Failed to find statsd when getting metadata"); + return null; + } + return service.getMetadata(); + } catch (RemoteException e) { + Slog.d(TAG, "Failed to connecto statsd when getting metadata"); + return null; + } + } + } + private class StatsdDeathRecipient implements IBinder.DeathRecipient { @Override public void binderDied() {