Captures metrics on disk when devices reboot and shutdown. Specifically,
1. Create intent receiver in StatsCompanionService to listen to shutdown
events.
2. Create StatsWriter class to handle disk writes and deleting files.
3. Update StatsLogProcessor, ConfigManager, and StatsService to handle
files on disk using StatsWriter.
4. Add a wrapper for ConfigMetricsReport.
Still TODO is to be able to add a guardrail to prevent accumulating
excessive amount files on disk, which will be followed up by another
change.
Test: statsd, statsd_test
Change-Id: Ia0b3af315af545daa8b0078b3700c600aa7c285f
diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp
index 0013506..ac2192c 100644
--- a/cmds/statsd/src/config/ConfigManager.cpp
+++ b/cmds/statsd/src/config/ConfigManager.cpp
@@ -15,6 +15,7 @@
*/
#include "config/ConfigManager.h"
+#include "storage/StorageManager.h"
#include "stats_util.h"
@@ -40,7 +41,7 @@
}
void ConfigManager::Startup() {
- readConfigFromDisk();
+ StorageManager::readConfigFromDisk(mConfigs);
// this should be called from StatsService when it receives a statsd_config
UpdateConfig(ConfigKey(1000, "fake"), build_fake_config());
@@ -90,21 +91,8 @@
}
void ConfigManager::remove_saved_configs(const ConfigKey& key) {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_SERVICE_DIR), closedir);
- if (dir == NULL) {
- ALOGD("no default config on disk");
- return;
- }
string prefix = StringPrintf("%d-%s", key.GetUid(), key.GetName().c_str());
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] != '.' && strncmp(name, prefix.c_str(), prefix.size()) == 0) {
- if (remove(StringPrintf("%s/%s", STATS_SERVICE_DIR, name).c_str()) != 0) {
- ALOGD("no file found");
- }
- }
- }
+ StorageManager::deletePrefixedFiles(STATS_SERVICE_DIR, prefix.c_str());
}
void ConfigManager::RemoveConfigs(int uid) {
@@ -162,50 +150,6 @@
}
}
-void ConfigManager::readConfigFromDisk() {
- unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_SERVICE_DIR), closedir);
- if (dir == NULL) {
- ALOGD("no default config on disk");
- return;
- }
-
- dirent* de;
- while ((de = readdir(dir.get()))) {
- char* name = de->d_name;
- if (name[0] == '.') continue;
- ALOGD("file %s", name);
-
- int index = 0;
- int uid = 0;
- string configName;
- char* substr = strtok(name, "-");
- // Timestamp lives at index 2 but we skip parsing it as it's not needed.
- while (substr != nullptr && index < 2) {
- if (index) {
- uid = atoi(substr);
- } else {
- configName = substr;
- }
- index++;
- }
- if (index < 2) continue;
- string file_name = StringPrintf("%s/%s", STATS_SERVICE_DIR, name);
- ALOGD("full file %s", file_name.c_str());
- int fd = open(file_name.c_str(), O_RDONLY | O_CLOEXEC);
- if (fd != -1) {
- string content;
- if (android::base::ReadFdToString(fd, &content)) {
- StatsdConfig config;
- if (config.ParseFromString(content)) {
- mConfigs[ConfigKey(uid, configName)] = config;
- ALOGD("map key uid=%d|name=%s", uid, name);
- }
- }
- close(fd);
- }
- }
-}
-
void ConfigManager::update_saved_configs(const ConfigKey& key, const StatsdConfig& config) {
mkdir(STATS_SERVICE_DIR, S_IRWXU);
@@ -215,16 +159,10 @@
// Then we save the latest config.
string file_name = StringPrintf("%s/%d-%s-%ld", STATS_SERVICE_DIR, key.GetUid(),
key.GetName().c_str(), time(nullptr));
- int fd = open(file_name.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR);
- if (fd != -1) {
- const int numBytes = config.ByteSize();
- vector<uint8_t> buffer(numBytes);
- config.SerializeToArray(&buffer[0], numBytes);
- int result = write(fd, &buffer[0], numBytes);
- close(fd);
- bool wroteKey = (result == numBytes);
- ALOGD("wrote to file %d", wroteKey);
- }
+ const int numBytes = config.ByteSize();
+ vector<uint8_t> buffer(numBytes);
+ config.SerializeToArray(&buffer[0], numBytes);
+ StorageManager::writeFile(file_name.c_str(), &buffer[0], numBytes);
}
StatsdConfig build_fake_config() {