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

Commit ef6cd7f5 authored by Tej Singh's avatar Tej Singh
Browse files

Perform partial update for count metric

Partial update for count metric.
Added a test for updating multiple metric types

Test: m statsd
Bug: 162322532
Change-Id: Iac1880d8c296334cacd1d5ab9545412efa5ccd4d
parent caaca26f
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
#include <stdlib.h>

#include "guardrail/StatsdStats.h"
#include "metrics/parsing_utils/metrics_manager_util.h"
#include "stats_log_util.h"
#include "stats_util.h"

@@ -122,6 +123,47 @@ CountMetricProducer::~CountMetricProducer() {
    VLOG("~CountMetricProducer() called");
}

bool CountMetricProducer::onConfigUpdatedLocked(
        const StatsdConfig& config, const int configIndex, const int metricIndex,
        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
        const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
        const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
        const sp<EventMatcherWizard>& matcherWizard,
        const vector<sp<ConditionTracker>>& allConditionTrackers,
        const unordered_map<int64_t, int>& conditionTrackerMap, const sp<ConditionWizard>& wizard,
        const unordered_map<int64_t, int>& metricToActivationMap,
        unordered_map<int, vector<int>>& trackerToMetricMap,
        unordered_map<int, vector<int>>& conditionToMetricMap,
        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
        vector<int>& metricsWithActivation) {
    if (!MetricProducer::onConfigUpdatedLocked(
                config, configIndex, metricIndex, allAtomMatchingTrackers,
                oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
                allConditionTrackers, conditionTrackerMap, wizard, metricToActivationMap,
                trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap,
                deactivationAtomTrackerToMetricMap, metricsWithActivation)) {
        return false;
    }

    const CountMetric& metric = config.count_metric(configIndex);
    int trackerIndex;
    // Update appropriate indices, specifically mConditionIndex and MetricsManager maps.
    if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, false,
                                              allAtomMatchingTrackers, newAtomMatchingTrackerMap,
                                              trackerToMetricMap, trackerIndex)) {
        return false;
    }

    if (metric.has_condition() &&
        !handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
                                    metric.links(), allConditionTrackers, mConditionTrackerIndex,
                                    conditionToMetricMap)) {
        return false;
    }
    return true;
}

void CountMetricProducer::onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
                                         const HashableDimensionKey& primaryKey,
                                         const FieldValue& oldState, const FieldValue& newState) {
+16 −0
Original line number Diff line number Diff line
@@ -97,6 +97,22 @@ private:
    void flushCurrentBucketLocked(const int64_t& eventTimeNs,
                                  const int64_t& nextBucketStartTimeNs) override;

    bool onConfigUpdatedLocked(
            const StatsdConfig& config, const int configIndex, const int metricIndex,
            const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
            const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
            const std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
            const sp<EventMatcherWizard>& matcherWizard,
            const std::vector<sp<ConditionTracker>>& allConditionTrackers,
            const std::unordered_map<int64_t, int>& conditionTrackerMap,
            const sp<ConditionWizard>& wizard,
            const std::unordered_map<int64_t, int>& metricToActivationMap,
            std::unordered_map<int, std::vector<int>>& trackerToMetricMap,
            std::unordered_map<int, std::vector<int>>& conditionToMetricMap,
            std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
            std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
            std::vector<int>& metricsWithActivation) override;

    std::unordered_map<MetricDimensionKey, std::vector<CountBucket>> mPastBuckets;

    // The current bucket (may be a partial bucket).
+2 −0
Original line number Diff line number Diff line
@@ -566,7 +566,9 @@ protected:
    FRIEND_TEST(MetricsManagerTest, TestInitialConditions);

    FRIEND_TEST(ConfigUpdateTest, TestUpdateMetricActivations);
    FRIEND_TEST(ConfigUpdateTest, TestUpdateCountMetrics);
    FRIEND_TEST(ConfigUpdateTest, TestUpdateEventMetrics);
    FRIEND_TEST(ConfigUpdateTest, TestUpdateMetricsMultipleTypes);
};

}  // namespace statsd
+45 −0
Original line number Diff line number Diff line
@@ -587,6 +587,51 @@ bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64

    // Now, perform the update. Must iterate the metric types in the same order
    int metricIndex = 0;
    for (int i = 0; i < config.count_metric_size(); i++, metricIndex++) {
        newMetricProducerMap[config.count_metric(i).id()] = metricIndex;
        const CountMetric& metric = config.count_metric(i);
        switch (metricsToUpdate[metricIndex]) {
            case UPDATE_PRESERVE: {
                const auto& oldMetricProducerIt = oldMetricProducerMap.find(metric.id());
                if (oldMetricProducerIt == oldMetricProducerMap.end()) {
                    ALOGE("Could not find Metric %lld in the previous config, but expected it "
                          "to be there",
                          (long long)metric.id());
                    return false;
                }
                const int oldIndex = oldMetricProducerIt->second;
                sp<MetricProducer> producer = oldMetricProducers[oldIndex];
                producer->onConfigUpdated(
                        config, i, metricIndex, allAtomMatchingTrackers, oldAtomMatchingTrackerMap,
                        newAtomMatchingTrackerMap, matcherWizard, allConditionTrackers,
                        conditionTrackerMap, wizard, metricToActivationMap, trackerToMetricMap,
                        conditionToMetricMap, activationAtomTrackerToMetricMap,
                        deactivationAtomTrackerToMetricMap, metricsWithActivation);
                newMetricProducers.push_back(producer);
                break;
            }
            case UPDATE_REPLACE:
            case UPDATE_NEW: {
                sp<MetricProducer> producer = createCountMetricProducerAndUpdateMetadata(
                        key, config, timeBaseNs, currentTimeNs, metric, metricIndex,
                        allAtomMatchingTrackers, newAtomMatchingTrackerMap, allConditionTrackers,
                        conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap,
                        allStateGroupMaps, metricToActivationMap, trackerToMetricMap,
                        conditionToMetricMap, activationAtomTrackerToMetricMap,
                        deactivationAtomTrackerToMetricMap, metricsWithActivation);
                if (producer == nullptr) {
                    return false;
                }
                newMetricProducers.push_back(producer);
                break;
            }
            default: {
                ALOGE("Metric \"%lld\" update state is unknown. This should never happen",
                      (long long)metric.id());
                return false;
            }
        }
    }
    for (int i = 0; i < config.event_metric_size(); i++, metricIndex++) {
        newMetricProducerMap[config.event_metric(i).id()] = metricIndex;
        const EventMetric& metric = config.event_metric(i);
+84 −57
Original line number Diff line number Diff line
@@ -348,6 +348,81 @@ bool handleMetricActivationOnConfigUpdate(
    return true;
}

sp<MetricProducer> createCountMetricProducerAndUpdateMetadata(
        const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
        const int64_t currentTimeNs, const CountMetric& metric, const int metricIndex,
        const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
        const unordered_map<int64_t, int>& atomMatchingTrackerMap,
        vector<sp<ConditionTracker>>& allConditionTrackers,
        const unordered_map<int64_t, int>& conditionTrackerMap,
        const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
        const unordered_map<int64_t, int>& stateAtomIdMap,
        const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
        const unordered_map<int64_t, int>& metricToActivationMap,
        unordered_map<int, vector<int>>& trackerToMetricMap,
        unordered_map<int, vector<int>>& conditionToMetricMap,
        unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
        unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
        vector<int>& metricsWithActivation) {
    if (!metric.has_id() || !metric.has_what()) {
        ALOGW("cannot find metric id or \"what\" in CountMetric \"%lld\"", (long long)metric.id());
        return nullptr;
    }
    int trackerIndex;
    if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex,
                                              metric.has_dimensions_in_what(),
                                              allAtomMatchingTrackers, atomMatchingTrackerMap,
                                              trackerToMetricMap, trackerIndex)) {
        return nullptr;
    }

    int conditionIndex = -1;
    if (metric.has_condition()) {
        if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
                                        metric.links(), allConditionTrackers, conditionIndex,
                                        conditionToMetricMap)) {
            return nullptr;
        }
    } else {
        if (metric.links_size() > 0) {
            ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
            return nullptr;
        }
    }

    std::vector<int> slicedStateAtoms;
    unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
    if (metric.slice_by_state_size() > 0) {
        if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
                                    allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
            return nullptr;
        }
    } else {
        if (metric.state_link_size() > 0) {
            ALOGW("CountMetric has a MetricStateLink but doesn't have a slice_by_state");
            return nullptr;
        }
    }

    unordered_map<int, shared_ptr<Activation>> eventActivationMap;
    unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
    if (!handleMetricActivation(config, metric.id(), metricIndex, metricToActivationMap,
                                atomMatchingTrackerMap, activationAtomTrackerToMetricMap,
                                deactivationAtomTrackerToMetricMap, metricsWithActivation,
                                eventActivationMap, eventDeactivationMap)) {
        return nullptr;
    }

    uint64_t metricHash;
    if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) {
        return nullptr;
    }

    return new CountMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
                                   metricHash, timeBaseNs, currentTimeNs, eventActivationMap,
                                   eventDeactivationMap, slicedStateAtoms, stateGroupMap);
}

sp<MetricProducer> createEventMetricProducerAndUpdateMetadata(
        const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
        const EventMetric& metric, const int metricIndex,
@@ -550,68 +625,20 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t
    // Build MetricProducers for each metric defined in config.
    // build CountMetricProducer
    for (int i = 0; i < config.count_metric_size(); i++) {
        const CountMetric& metric = config.count_metric(i);
        if (!metric.has_what()) {
            ALOGW("cannot find \"what\" in CountMetric \"%lld\"", (long long)metric.id());
            return false;
        }

        int metricIndex = allMetricProducers.size();
        const CountMetric& metric = config.count_metric(i);
        metricMap.insert({metric.id(), metricIndex});
        int trackerIndex;
        if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex,
                                                  metric.has_dimensions_in_what(),
                                                  allAtomMatchingTrackers, atomMatchingTrackerMap,
                                                  trackerToMetricMap, trackerIndex)) {
            return false;
        }

        int conditionIndex = -1;
        if (metric.has_condition()) {
            if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
                                            metric.links(), allConditionTrackers, conditionIndex,
                                            conditionToMetricMap)) {
                return false;
            }
        } else {
            if (metric.links_size() > 0) {
                ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
                return false;
            }
        }

        std::vector<int> slicedStateAtoms;
        unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
        if (metric.slice_by_state_size() > 0) {
            if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
                                        allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
                return false;
            }
        } else {
            if (metric.state_link_size() > 0) {
                ALOGW("CountMetric has a MetricStateLink but doesn't have a slice_by_state");
                return false;
            }
        }

        unordered_map<int, shared_ptr<Activation>> eventActivationMap;
        unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
        bool success = handleMetricActivation(
                config, metric.id(), metricIndex, metricToActivationMap, atomMatchingTrackerMap,
        sp<MetricProducer> producer = createCountMetricProducerAndUpdateMetadata(
                key, config, timeBaseTimeNs, currentTimeNs, metric, metricIndex,
                allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
                conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap,
                allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
                activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
                metricsWithActivation, eventActivationMap, eventDeactivationMap);
        if (!success) return false;

        uint64_t metricHash;
        if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) {
                metricsWithActivation);
        if (producer == nullptr) {
            return false;
        }

        sp<MetricProducer> countProducer = new CountMetricProducer(
                key, metric, conditionIndex, initialConditionCache, wizard, metricHash,
                timeBaseTimeNs, currentTimeNs, eventActivationMap, eventDeactivationMap,
                slicedStateAtoms, stateGroupMap);
        allMetricProducers.push_back(countProducer);
        allMetricProducers.push_back(producer);
    }

    // build DurationMetricProducer
Loading