Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b8f5403d authored by Jeffrey Huang's avatar Jeffrey Huang
Browse files

Save metadata to Disk

Bug: 148280505
Test: bit statsd_test:*
Change-Id: Ib9c6b9b4f22e7380717b480c7ae4a37bb3364619
parent dd8e9d80
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ cc_defaults {
        "src/matchers/EventMatcherWizard.cpp",
        "src/matchers/matcher_util.cpp",
        "src/matchers/SimpleLogMatchingTracker.cpp",
        "src/metadata_util.cpp",
        "src/metrics/CountMetricProducer.cpp",
        "src/metrics/duration_helper/MaxDurationTracker.cpp",
        "src/metrics/duration_helper/OringDurationTracker.cpp",
+51 −0
Original line number Diff line number Diff line
@@ -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
@@ -851,6 +852,56 @@ 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::WriteActiveConfigsToProtoOutputStream(
        int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto) {
    std::lock_guard<std::mutex> lock(mMetricsMutex);
+19 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include "external/StatsPullerManager.h"

#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "frameworks/base/cmds/statsd/src/statsd_metadata.pb.h"

#include <stdio.h>
#include <unordered_map>
@@ -89,6 +90,14 @@ public:
    /* Load configs containing metrics with active activations from disk. */
    void LoadActiveConfigsFromDisk();

    /* Persist metadata for configs and metrics to disk. */
    void SaveMetadataToDisk(int64_t currentWallClockTimeNs, int64_t systemElapsedTimeNs);

    /* Writes the statsd metadata for all configs and metrics to StatsMetadataList. */
    void WriteMetadataToProto(int64_t currentWallClockTimeNs,
                              int64_t systemElapsedTimeNs,
                              metadata::StatsMetadataList* metadataList);

    /* Sets the active status/ttl for all configs and metrics to the status in ActiveConfigList. */
    void SetConfigsActiveState(const ActiveConfigList& activeConfigList, int64_t currentTimeNs);

@@ -173,8 +182,13 @@ private:
    void SetConfigsActiveStateLocked(const ActiveConfigList& activeConfigList,
                                     int64_t currentTimeNs);

    void WriteMetadataToProtoLocked(int64_t currentWallClockTimeNs,
                                    int64_t systemElapsedTimeNs,
                                    metadata::StatsMetadataList* metadataList);

    void WriteDataToDiskLocked(const DumpReportReason dumpReportReason,
                               const DumpLatency dumpLatency);

    void WriteDataToDiskLocked(const ConfigKey& key, const int64_t timestampNs,
                               const DumpReportReason dumpReportReason,
                               const DumpLatency dumpLatency);
@@ -241,6 +255,9 @@ private:
    // Last time we wrote active metrics to disk.
    int64_t mLastActiveMetricsWriteNs = 0;

    //Last time we wrote metadata to disk.
    int64_t mLastMetadataWriteNs = 0;

#ifdef VERY_VERBOSE_PRINTING
    bool mPrintAllLogs = false;
#endif
@@ -278,6 +295,8 @@ private:

    FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_single_bucket);
    FRIEND_TEST(AnomalyDetectionE2eTest, TestSlicedCountMetric_multiple_buckets);
    FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk_no_data_written);
    FRIEND_TEST(AnomalyDetectionE2eTest, TestCountMetric_save_refractory_to_disk);
    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
    FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
+8 −4
Original line number Diff line number Diff line
@@ -1007,6 +1007,7 @@ Status StatsService::informDeviceShutdown() {
    VLOG("StatsService::informDeviceShutdown");
    mProcessor->WriteDataToDisk(DEVICE_SHUTDOWN, FAST);
    mProcessor->SaveActiveConfigsToDisk(getElapsedRealtimeNs());
    mProcessor->SaveMetadataToDisk(getWallClockNs(), getElapsedRealtimeNs());
    return Status::ok();
}

@@ -1048,6 +1049,7 @@ void StatsService::Terminate() {
    if (mProcessor != nullptr) {
        mProcessor->WriteDataToDisk(TERMINATION_SIGNAL_RECEIVED, FAST);
        mProcessor->SaveActiveConfigsToDisk(getElapsedRealtimeNs());
        mProcessor->SaveMetadataToDisk(getWallClockNs(), getElapsedRealtimeNs());
    }
}

@@ -1280,15 +1282,17 @@ void StatsService::statsCompanionServiceDiedImpl() {
    if (mProcessor != nullptr) {
        ALOGW("Reset statsd upon system server restarts.");
        int64_t systemServerRestartNs = getElapsedRealtimeNs();
        ProtoOutputStream proto;
        ProtoOutputStream activeConfigsProto;
        mProcessor->WriteActiveConfigsToProtoOutputStream(systemServerRestartNs,
                STATSCOMPANION_DIED, &proto);

                STATSCOMPANION_DIED, &activeConfigsProto);
        metadata::StatsMetadataList metadataList;
        mProcessor->WriteMetadataToProto(getWallClockNs(),
                systemServerRestartNs, &metadataList);
        mProcessor->WriteDataToDisk(STATSCOMPANION_DIED, FAST);
        mProcessor->resetConfigs();

        std::string serializedActiveConfigs;
        if (proto.serializeToString(&serializedActiveConfigs)) {
        if (activeConfigsProto.serializeToString(&serializedActiveConfigs)) {
            ActiveConfigList activeConfigs;
            if (activeConfigs.ParseFromString(serializedActiveConfigs)) {
                mProcessor->SetConfigsActiveState(activeConfigs, systemServerRestartNs);
+37 −1
Original line number Diff line number Diff line
@@ -18,9 +18,11 @@
#include "Log.h"

#include "AnomalyTracker.h"
#include "subscriber_util.h"
#include "external/Perfetto.h"
#include "guardrail/StatsdStats.h"
#include "metadata_util.h"
#include "stats_log_util.h"
#include "subscriber_util.h"
#include "subscriber/IncidentdReporter.h"
#include "subscriber/SubscriberReporter.h"

@@ -262,6 +264,40 @@ void AnomalyTracker::informSubscribers(const MetricDimensionKey& key, int64_t me
    triggerSubscribers(mAlert.id(), metric_id, key, metricValue, mConfigKey, mSubscriptions);
}

bool AnomalyTracker::writeAlertMetadataToProto(int64_t currentWallClockTimeNs,
                                               int64_t systemElapsedTimeNs,
                                               metadata::AlertMetadata* alertMetadata) {
    bool metadataWritten = false;

    if (mRefractoryPeriodEndsSec.empty()) {
        return false;
    }

    for (const auto& it: mRefractoryPeriodEndsSec) {
        // Do not write the timestamp to disk if it has already expired
        if (it.second < systemElapsedTimeNs / NS_PER_SEC) {
            continue;
        }

        metadataWritten = true;
        if (alertMetadata->alert_dim_keyed_data_size() == 0) {
            alertMetadata->set_alert_id(mAlert.id());
        }

        metadata::AlertDimensionKeyedData* keyedData = alertMetadata->add_alert_dim_keyed_data();
        // We convert and write the refractory_end_sec to wall clock time because we do not know
        // when statsd will start again.
        int32_t refractoryEndWallClockSec = (int32_t) ((currentWallClockTimeNs / NS_PER_SEC) +
                (it.second - systemElapsedTimeNs / NS_PER_SEC));

        keyedData->set_last_refractory_ends_sec(refractoryEndWallClockSec);
        writeMetricDimensionKeyToMetadataDimensionKey(
                it.first, keyedData->mutable_dimension_key());
    }

    return metadataWritten;
}

}  // namespace statsd
}  // namespace os
}  // namespace android
Loading