diff options
Diffstat (limited to 'cmds/statsd/src/StatsLogProcessor.cpp')
-rw-r--r-- | cmds/statsd/src/StatsLogProcessor.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp index 4966b2e1a018..982a63e3e08c 100644 --- a/cmds/statsd/src/StatsLogProcessor.cpp +++ b/cmds/statsd/src/StatsLogProcessor.cpp @@ -79,6 +79,7 @@ constexpr const char* kPermissionUsage = "android.permission.PACKAGE_USAGE_STATS #define NS_PER_HOUR 3600 * NS_PER_SEC #define STATS_ACTIVE_METRIC_DIR "/data/misc/stats-active-metric" +#define STATS_METADATA_DIR "/data/misc/stats-metadata" // Cool down period for writing data to disk to avoid overwriting files. #define WRITE_DATA_COOL_DOWN_SEC 5 @@ -852,6 +853,110 @@ void StatsLogProcessor::SaveActiveConfigsToDisk(int64_t currentTimeNs) { proto.flush(fd.get()); } +void StatsLogProcessor::SaveMetadataToDisk(int64_t currentWallClockTimeNs, + int64_t systemElapsedTimeNs) { + std::lock_guard<std::mutex> lock(mMetricsMutex); + // Do not write to disk if we already have in the last few seconds. + if (static_cast<unsigned long long> (systemElapsedTimeNs) < + mLastMetadataWriteNs + WRITE_DATA_COOL_DOWN_SEC * NS_PER_SEC) { + ALOGI("Statsd skipping writing metadata to disk. Already wrote data in last %d seconds", + WRITE_DATA_COOL_DOWN_SEC); + return; + } + mLastMetadataWriteNs = systemElapsedTimeNs; + + metadata::StatsMetadataList metadataList; + WriteMetadataToProtoLocked( + currentWallClockTimeNs, systemElapsedTimeNs, &metadataList); + + string file_name = StringPrintf("%s/metadata", STATS_METADATA_DIR); + StorageManager::deleteFile(file_name.c_str()); + + if (metadataList.stats_metadata_size() == 0) { + // Skip the write if we have nothing to write. + return; + } + + std::string data; + metadataList.SerializeToString(&data); + StorageManager::writeFile(file_name.c_str(), data.c_str(), data.size()); +} + +void StatsLogProcessor::WriteMetadataToProto(int64_t currentWallClockTimeNs, + int64_t systemElapsedTimeNs, + metadata::StatsMetadataList* metadataList) { + std::lock_guard<std::mutex> lock(mMetricsMutex); + WriteMetadataToProtoLocked(currentWallClockTimeNs, systemElapsedTimeNs, metadataList); +} + +void StatsLogProcessor::WriteMetadataToProtoLocked(int64_t currentWallClockTimeNs, + int64_t systemElapsedTimeNs, + metadata::StatsMetadataList* metadataList) { + for (const auto& pair : mMetricsManagers) { + const sp<MetricsManager>& metricsManager = pair.second; + metadata::StatsMetadata* statsMetadata = metadataList->add_stats_metadata(); + bool metadataWritten = metricsManager->writeMetadataToProto(currentWallClockTimeNs, + systemElapsedTimeNs, statsMetadata); + if (!metadataWritten) { + metadataList->mutable_stats_metadata()->RemoveLast(); + } + } +} + +void StatsLogProcessor::LoadMetadataFromDisk(int64_t currentWallClockTimeNs, + int64_t systemElapsedTimeNs) { + std::lock_guard<std::mutex> lock(mMetricsMutex); + string file_name = StringPrintf("%s/metadata", STATS_METADATA_DIR); + int fd = open(file_name.c_str(), O_RDONLY | O_CLOEXEC); + if (-1 == fd) { + VLOG("Attempt to read %s but failed", file_name.c_str()); + StorageManager::deleteFile(file_name.c_str()); + return; + } + string content; + if (!android::base::ReadFdToString(fd, &content)) { + ALOGE("Attempt to read %s but failed", file_name.c_str()); + close(fd); + StorageManager::deleteFile(file_name.c_str()); + return; + } + + close(fd); + + metadata::StatsMetadataList statsMetadataList; + if (!statsMetadataList.ParseFromString(content)) { + ALOGE("Attempt to read %s but failed; failed to metadata", file_name.c_str()); + StorageManager::deleteFile(file_name.c_str()); + return; + } + SetMetadataStateLocked(statsMetadataList, currentWallClockTimeNs, systemElapsedTimeNs); + StorageManager::deleteFile(file_name.c_str()); +} + +void StatsLogProcessor::SetMetadataState(const metadata::StatsMetadataList& statsMetadataList, + int64_t currentWallClockTimeNs, + int64_t systemElapsedTimeNs) { + std::lock_guard<std::mutex> lock(mMetricsMutex); + SetMetadataStateLocked(statsMetadataList, currentWallClockTimeNs, systemElapsedTimeNs); +} + +void StatsLogProcessor::SetMetadataStateLocked( + const metadata::StatsMetadataList& statsMetadataList, + int64_t currentWallClockTimeNs, + int64_t systemElapsedTimeNs) { + for (const metadata::StatsMetadata& metadata : statsMetadataList.stats_metadata()) { + ConfigKey key(metadata.config_key().uid(), metadata.config_key().config_id()); + auto it = mMetricsManagers.find(key); + if (it == mMetricsManagers.end()) { + ALOGE("No config found for configKey %s", key.ToString().c_str()); + continue; + } + VLOG("Setting metadata %s", key.ToString().c_str()); + it->second->loadMetadata(metadata, currentWallClockTimeNs, systemElapsedTimeNs); + } + VLOG("Successfully loaded %d metadata.", statsMetadataList.stats_metadata_size()); +} + void StatsLogProcessor::WriteActiveConfigsToProtoOutputStream( int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) { std::lock_guard<std::mutex> lock(mMetricsMutex); |