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

Commit e1e0528d authored by Muhammad Qureshi's avatar Muhammad Qureshi Committed by Android (Google) Code Review
Browse files

Merge "Cancel Metric activations"

parents cfd519fe 3a5ebf58
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -260,6 +260,9 @@ private:
    FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
    FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
    FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
};

}  // namespace statsd
+34 −20
Original line number Diff line number Diff line
@@ -70,11 +70,11 @@ void MetricProducer::onMatchedLogEventLocked(const size_t matcherIndex, const Lo
bool MetricProducer::evaluateActiveStateLocked(int64_t elapsedTimestampNs) {
    bool isActive = mEventActivationMap.empty();
    for (auto& it : mEventActivationMap) {
        if (it.second.state == ActivationState::kActive &&
            elapsedTimestampNs > it.second.ttl_ns + it.second.activation_ns) {
            it.second.state = ActivationState::kNotActive;
        if (it.second->state == ActivationState::kActive &&
            elapsedTimestampNs > it.second->ttl_ns + it.second->activation_ns) {
            it.second->state = ActivationState::kNotActive;
        }
        if (it.second.state == ActivationState::kActive) {
        if (it.second->state == ActivationState::kActive) {
            isActive = true;
        }
    }
@@ -92,7 +92,8 @@ void MetricProducer::flushIfExpire(int64_t elapsedTimestampNs) {
    }
}

void MetricProducer::addActivation(int activationTrackerIndex, int64_t ttl_seconds) {
void MetricProducer::addActivation(int activationTrackerIndex, int64_t ttl_seconds,
                                   int deactivationTrackerIndex) {
    std::lock_guard<std::mutex> lock(mMutex);
    // When a metric producer does not depend on any activation, its mIsActive is true.
    // Therefore, if this is the 1st activation, mIsActive will turn to false. Otherwise it does not
@@ -100,7 +101,12 @@ void MetricProducer::addActivation(int activationTrackerIndex, int64_t ttl_secon
    if  (mEventActivationMap.empty()) {
        mIsActive = false;
    }
    mEventActivationMap[activationTrackerIndex].ttl_ns = ttl_seconds * NS_PER_SEC;
    std::shared_ptr<Activation> activation = std::make_shared<Activation>();
    activation->ttl_ns = ttl_seconds * NS_PER_SEC;
    mEventActivationMap.emplace(activationTrackerIndex, activation);
    if (-1 != deactivationTrackerIndex) {
        mEventDeactivationMap.emplace(deactivationTrackerIndex, activation);
    }
}

void MetricProducer::activateLocked(int activationTrackerIndex, int64_t elapsedTimestampNs) {
@@ -109,27 +115,35 @@ void MetricProducer::activateLocked(int activationTrackerIndex, int64_t elapsedT
        return;
    }
    if (mActivationType == MetricActivation::ACTIVATE_ON_BOOT &&
        it->second.state == ActivationState::kNotActive) {
        it->second.state = ActivationState::kActiveOnBoot;
        it->second->state == ActivationState::kNotActive) {
        it->second->state = ActivationState::kActiveOnBoot;
        return;
    }
    it->second.activation_ns = elapsedTimestampNs;
    it->second.state = ActivationState::kActive;
    it->second->activation_ns = elapsedTimestampNs;
    it->second->state = ActivationState::kActive;
    mIsActive = true;
}

void MetricProducer::cancelEventActivationLocked(int deactivationTrackerIndex) {
    auto it = mEventDeactivationMap.find(deactivationTrackerIndex);
    if (it == mEventDeactivationMap.end()) {
        return;
    }
    it->second->state = ActivationState::kNotActive;
}

void MetricProducer::setActiveLocked(int64_t currentTimeNs, int64_t remainingTtlNs) {
    if (mEventActivationMap.size() == 0) {
        return;
    }
    for (auto& pair : mEventActivationMap) {
        auto& activation = pair.second;
        if (activation.ttl_ns >= remainingTtlNs) {
            activation.activation_ns = currentTimeNs + remainingTtlNs - activation.ttl_ns;
            activation.state = kActive;
        if (activation->ttl_ns >= remainingTtlNs) {
            activation->activation_ns = currentTimeNs + remainingTtlNs - activation->ttl_ns;
            activation->state = kActive;
            mIsActive = true;
            VLOG("setting new activation time to %lld, %lld, %lld",
                 (long long)activation.activation_ns, (long long)currentTimeNs,
            VLOG("setting new activation->time to %lld, %lld, %lld",
                 (long long)activation->activation_ns, (long long)currentTimeNs,
                 (long long)remainingTtlNs);
            return;
        }
@@ -140,8 +154,8 @@ void MetricProducer::setActiveLocked(int64_t currentTimeNs, int64_t remainingTtl
int64_t MetricProducer::getRemainingTtlNsLocked(int64_t currentTimeNs) const {
    int64_t maxTtl = 0;
    for (const auto& activation : mEventActivationMap) {
        if (activation.second.state == kActive) {
            maxTtl = std::max(maxTtl, activation.second.ttl_ns + activation.second.activation_ns -
        if (activation.second->state == kActive) {
            maxTtl = std::max(maxTtl, activation.second->ttl_ns + activation.second->activation_ns -
                                              currentTimeNs);
        }
    }
@@ -153,9 +167,9 @@ void MetricProducer::prepActiveForBootIfNecessaryLocked(int64_t currentTimeNs) {
        return;
    }
    for (auto& activation : mEventActivationMap) {
        if (activation.second.state == kActiveOnBoot) {
            activation.second.state = kActive;
            activation.second.activation_ns = currentTimeNs;
        if (activation.second->state == kActiveOnBoot) {
            activation.second->state = kActive;
            activation.second->activation_ns = currentTimeNs;
            mIsActive = true;
        }
    }
+15 −2
Original line number Diff line number Diff line
@@ -228,6 +228,11 @@ public:
        activateLocked(activationTrackerIndex, elapsedTimestampNs);
    }

    void cancelEventActivation(int deactivationTrackerIndex) {
        std::lock_guard<std::mutex> lock(mMutex);
        cancelEventActivationLocked(deactivationTrackerIndex);
    }

    bool isActive() const {
        std::lock_guard<std::mutex> lock(mMutex);
        return isActiveLocked();
@@ -238,7 +243,8 @@ public:
        prepActiveForBootIfNecessaryLocked(currentTimeNs);
    }

    void addActivation(int activationTrackerIndex, int64_t ttl_seconds);
    void addActivation(int activationTrackerIndex, int64_t ttl_seconds,
                       int deactivationTrackerIndex = -1);

    inline void setActivationType(const MetricActivation::ActivationType& activationType) {
        mActivationType = activationType;
@@ -263,6 +269,7 @@ protected:
    bool evaluateActiveStateLocked(int64_t elapsedTimestampNs);

    void activateLocked(int activationTrackerIndex, int64_t elapsedTimestampNs);
    void cancelEventActivationLocked(int deactivationTrackerIndex);

    inline bool isActiveLocked() const {
        return mIsActive;
@@ -391,13 +398,19 @@ protected:
    };
    // When the metric producer has multiple activations, these activations are ORed to determine
    // whether the metric producer is ready to generate metrics.
    std::unordered_map<int, Activation> mEventActivationMap;
    std::unordered_map<int, std::shared_ptr<Activation>> mEventActivationMap;

    // Maps index of atom matcher for deactivation to Activation struct.
    std::unordered_map<int, std::shared_ptr<Activation>> mEventDeactivationMap;

    bool mIsActive;

    MetricActivation::ActivationType mActivationType;

    FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);

    FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
    FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
+47 −9
Original line number Diff line number Diff line
@@ -74,7 +74,8 @@ MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config,
            timeBaseNs, currentTimeNs, mTagIds, mAllAtomMatchers, mAllConditionTrackers,
            mAllMetricProducers, mAllAnomalyTrackers, mAllPeriodicAlarmTrackers,
            mConditionToMetricMap, mTrackerToMetricMap, mTrackerToConditionMap,
            mActivationAtomTrackerToMetricMap, mMetricIndexesWithActivation, mNoReportMetricIds);
            mActivationAtomTrackerToMetricMap, mDeactivationAtomTrackerToMetricMap,
            mMetricIndexesWithActivation, mNoReportMetricIds);

    mHashStringsInReport = config.hash_strings_in_metric_report();
    mVersionStringsInReport = config.version_strings_in_metric_report();
@@ -344,24 +345,61 @@ void MetricsManager::onLogEvent(const LogEvent& event) {
    int64_t eventTimeNs = event.GetElapsedTimestampNs();

    bool isActive = mIsAlwaysActive;
    for (int metric : mMetricIndexesWithActivation) {
        mAllMetricProducers[metric]->flushIfExpire(eventTimeNs);
        isActive |= mAllMetricProducers[metric]->isActive();

    // Set of metrics that are still active after flushing.
    unordered_set<int> activeMetricsIndices;

    // Update state of all metrics w/ activation conditions as of eventTimeNs.
    for (int metricIndex : mMetricIndexesWithActivation) {
        const sp<MetricProducer>& metric = mAllMetricProducers[metricIndex];
        metric->flushIfExpire(eventTimeNs);
        if (metric->isActive()) {
            // If this metric w/ activation condition is still active after
            // flushing, remember it.
            activeMetricsIndices.insert(metricIndex);
        }
    }

    mIsActive = isActive;
    mIsActive = isActive || !activeMetricsIndices.empty();

    if (mTagIds.find(tagId) == mTagIds.end()) {
        // not interesting...
        // Not interesting...
        return;
    }

    vector<MatchingState> matcherCache(mAllAtomMatchers.size(), MatchingState::kNotComputed);

    // Evaluate all atom matchers.
    for (auto& matcher : mAllAtomMatchers) {
        matcher->onLogEvent(event, mAllAtomMatchers, matcherCache);
    }

    // Set of metrics that received an activation cancellation.
    unordered_set<int> metricIndicesWithCanceledActivations;

    // Determine which metric activations received a cancellation and cancel them.
    for (const auto& it : mDeactivationAtomTrackerToMetricMap) {
        if (matcherCache[it.first] == MatchingState::kMatched) {
            for (int metricIndex : it.second) {
                mAllMetricProducers[metricIndex]->cancelEventActivation(it.first);
                metricIndicesWithCanceledActivations.insert(metricIndex);
            }
        }
    }

    // Determine whether any metrics are no longer active after cancelling metric activations.
    for (const int metricIndex : metricIndicesWithCanceledActivations) {
        const sp<MetricProducer>& metric = mAllMetricProducers[metricIndex];
        metric->flushIfExpire(eventTimeNs);
        if (!metric->isActive()) {
            activeMetricsIndices.erase(metricIndex);
        }
    }

    isActive |= !activeMetricsIndices.empty();


    // Determine which metric activations should be turned on and turn them on
    for (const auto& it : mActivationAtomTrackerToMetricMap) {
        if (matcherCache[it.first] == MatchingState::kMatched) {
            for (int metricIndex : it.second) {
@@ -406,12 +444,12 @@ void MetricsManager::onLogEvent(const LogEvent& event) {
        if (pair != mConditionToMetricMap.end()) {
            auto& metricList = pair->second;
            for (auto metricIndex : metricList) {
                // metric cares about non sliced condition, and it's changed.
                // Metric cares about non sliced condition, and it's changed.
                // Push the new condition to it directly.
                if (!mAllMetricProducers[metricIndex]->isConditionSliced()) {
                    mAllMetricProducers[metricIndex]->onConditionChanged(conditionCache[i],
                                                                         eventTimeNs);
                    // metric cares about sliced conditions, and it may have changed. Send
                    // Metric cares about sliced conditions, and it may have changed. Send
                    // notification, and the metric can query the sliced conditions that are
                    // interesting to it.
                } else {
+10 −4
Original line number Diff line number Diff line
@@ -225,18 +225,21 @@ private:

    // The following map is initialized from the statsd_config.

    // maps from the index of the LogMatchingTracker to index of MetricProducer.
    // Maps from the index of the LogMatchingTracker to index of MetricProducer.
    std::unordered_map<int, std::vector<int>> mTrackerToMetricMap;

    // maps from LogMatchingTracker to ConditionTracker
    // Maps from LogMatchingTracker to ConditionTracker
    std::unordered_map<int, std::vector<int>> mTrackerToConditionMap;

    // maps from ConditionTracker to MetricProducer
    // Maps from ConditionTracker to MetricProducer
    std::unordered_map<int, std::vector<int>> mConditionToMetricMap;

    // maps from life span triggering event to MetricProducers.
    // Maps from life span triggering event to MetricProducers.
    std::unordered_map<int, std::vector<int>> mActivationAtomTrackerToMetricMap;

    // Maps deactivation triggering event to MetricProducers.
    std::unordered_map<int, std::vector<int>> mDeactivationAtomTrackerToMetricMap;

    std::vector<int> mMetricIndexesWithActivation;

    void initLogSourceWhiteList();
@@ -281,6 +284,9 @@ private:
    FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
    FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
    FRIEND_TEST(MetricActivationE2eTest, TestCountMetric);
    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation);
    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations);
    FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);

    FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead);
    FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot);
Loading