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

Commit 933b6e35 authored by Tej Singh's avatar Tej Singh
Browse files

Init duration metric if condition existed

Initialize a duration metric with the dimensions that are true if the
"what" predicate previously existed.

Assumes that the internal dimensions are a superset of the
dimensions_in_what, the condition links, and the state links

Test: atest statsd_test
Bug: 167491517
Change-Id: I8dd984fb9cb575d6d541f80cb3b1e626ce4e5f27
parent e935342b
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -85,16 +85,14 @@ public:
        const std::vector<sp<ConditionTracker>>& allConditions,
        const vector<Matcher>& dimensions) const override;

    void getTrueSlicedDimensions(
            const std::vector<sp<ConditionTracker>>& allConditions,
            std::set<HashableDimensionKey>* dimensions) const override {
    const std::map<HashableDimensionKey, int>* getSlicedDimensionMap(
            const std::vector<sp<ConditionTracker>>& allConditions) const override {
        if (mSlicedChildren.size() == 1) {
            return allConditions[mSlicedChildren.front()]->getTrueSlicedDimensions(
                allConditions, dimensions);
            return allConditions[mSlicedChildren.front()]->getSlicedDimensionMap(allConditions);
        }
        return nullptr;
    }


private:
    LogicalOperation mLogicalOperation;

+2 −3
Original line number Diff line number Diff line
@@ -135,9 +135,8 @@ public:
        return mProtoHash;
    }

    virtual void getTrueSlicedDimensions(
        const std::vector<sp<ConditionTracker>>& allConditions,
        std::set<HashableDimensionKey>* dimensions) const = 0;
    virtual const std::map<HashableDimensionKey, int>* getSlicedDimensionMap(
            const std::vector<sp<ConditionTracker>>& allConditions) const = 0;

    virtual bool IsChangedDimensionTrackable() const = 0;

+3 −3
Original line number Diff line number Diff line
@@ -53,9 +53,9 @@ public:
    ConditionState getUnSlicedPartConditionState(const int index) {
        return mAllConditions[index]->getUnSlicedPartConditionState();
    }
    void getTrueSlicedDimensions(const int index,
        std::set<HashableDimensionKey>* trueDimensions) const {
        return mAllConditions[index]->getTrueSlicedDimensions(mAllConditions, trueDimensions);

    const std::map<HashableDimensionKey, int>* getSlicedDimensionMap(const int index) const {
        return mAllConditions[index]->getSlicedDimensionMap(mAllConditions);
    }

private:
+3 −8
Original line number Diff line number Diff line
@@ -74,14 +74,9 @@ public:
        }
    }

    void getTrueSlicedDimensions(
            const std::vector<sp<ConditionTracker>>& allConditions,
            std::set<HashableDimensionKey>* dimensions) const override {
        for (const auto& itr : mSlicedConditionState) {
            if (itr.second > 0) {
                dimensions->insert(itr.first);
            }
        }
    const std::map<HashableDimensionKey, int>* getSlicedDimensionMap(
            const std::vector<sp<ConditionTracker>>& allConditions) const override {
        return &mSlicedConditionState;
    }

    bool IsChangedDimensionTrackable() const  override { return true; }
+48 −26
Original line number Diff line number Diff line
@@ -67,8 +67,8 @@ const int FIELD_ID_END_BUCKET_ELAPSED_MILLIS = 6;

DurationMetricProducer::DurationMetricProducer(
        const ConfigKey& key, const DurationMetric& metric, const int conditionIndex,
        const vector<ConditionState>& initialConditionCache, const int startIndex,
        const int stopIndex, const int stopAllIndex, const bool nesting,
        const vector<ConditionState>& initialConditionCache, const int whatIndex,
        const int startIndex, const int stopIndex, const int stopAllIndex, const bool nesting,
        const sp<ConditionWizard>& wizard, const uint64_t protoHash,
        const FieldMatcher& internalDimensions, const int64_t timeBaseNs, const int64_t startTimeNs,
        const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
@@ -140,6 +140,8 @@ DurationMetricProducer::DurationMetricProducer(
    mCurrentBucketStartTimeNs = startTimeNs;
    VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
         (long long)mBucketSizeNs, (long long)mTimeBaseNs);

    initTrueDimensions(whatIndex, startTimeNs);
}

DurationMetricProducer::~DurationMetricProducer() {
@@ -224,6 +226,23 @@ bool DurationMetricProducer::onConfigUpdatedLocked(
    return true;
}

void DurationMetricProducer::initTrueDimensions(const int whatIndex, const int64_t startTimeNs) {
    std::lock_guard<std::mutex> lock(mMutex);
    // Currently whatIndex will only be -1 in tests. In the future, we might want to avoid creating
    // a ConditionTracker if the condition is only used in the "what" of a duration metric. In that
    // scenario, -1 can also be passed.
    if (whatIndex == -1) {
        return;
    }
    const map<HashableDimensionKey, int>* slicedWhatMap = mWizard->getSlicedDimensionMap(whatIndex);
    for (const auto& [internalDimKey, count] : *slicedWhatMap) {
        for (int i = 0; i < count; i++) {
            // Fake start events.
            handleMatchedLogEventValuesLocked(mStartIndex, internalDimKey.getValues(), startTimeNs);
        }
    }
}

sp<AnomalyTracker> DurationMetricProducer::addAnomalyTracker(
        const Alert &alert, const sp<AlarmMonitor>& anomalyAlarmMonitor) {
    std::lock_guard<std::mutex> lock(mMutex);
@@ -330,14 +349,14 @@ void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt1(bool conditio
    // state based on the new unsliced condition state.
    if (dimensionsChangedToTrue == nullptr || dimensionsChangedToFalse == nullptr ||
        (dimensionsChangedToTrue->empty() && dimensionsChangedToFalse->empty())) {
        std::set<HashableDimensionKey> trueConditionDimensions;
        mWizard->getTrueSlicedDimensions(mConditionTrackerIndex, &trueConditionDimensions);
        const map<HashableDimensionKey, int>* slicedConditionMap =
                mWizard->getSlicedDimensionMap(mConditionTrackerIndex);
        for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
            HashableDimensionKey linkedConditionDimensionKey;
            getDimensionForCondition(whatIt.first.getValues(), mMetric2ConditionLinks[0],
                                     &linkedConditionDimensionKey);
            if (trueConditionDimensions.find(linkedConditionDimensionKey) !=
                    trueConditionDimensions.end()) {
            const auto& slicedConditionIt = slicedConditionMap->find(linkedConditionDimensionKey);
            if (slicedConditionIt != slicedConditionMap->end() && slicedConditionIt->second > 0) {
                whatIt.second->onConditionChanged(currentUnSlicedPartCondition, eventTime);
            }
        }
@@ -595,8 +614,9 @@ bool DurationMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey
}

void DurationMetricProducer::handleStartEvent(const MetricDimensionKey& eventKey,
                                              const ConditionKey& conditionKeys,
                                              bool condition, const LogEvent& event) {
                                              const ConditionKey& conditionKeys, bool condition,
                                              const int64_t eventTimeNs,
                                              const vector<FieldValue>& eventValues) {
    const auto& whatKey = eventKey.getDimensionKeyInWhat();
    auto whatIt = mCurrentSlicedDurationTrackerMap.find(whatKey);
    if (whatIt == mCurrentSlicedDurationTrackerMap.end()) {
@@ -608,20 +628,17 @@ void DurationMetricProducer::handleStartEvent(const MetricDimensionKey& eventKey

    auto it = mCurrentSlicedDurationTrackerMap.find(whatKey);
    if (mUseWhatDimensionAsInternalDimension) {
        it->second->noteStart(whatKey, condition, event.GetElapsedTimestampNs(), conditionKeys);
        it->second->noteStart(whatKey, condition, eventTimeNs, conditionKeys);
        return;
    }

    if (mInternalDimensions.empty()) {
        it->second->noteStart(DEFAULT_DIMENSION_KEY, condition, event.GetElapsedTimestampNs(),
                              conditionKeys);
        it->second->noteStart(DEFAULT_DIMENSION_KEY, condition, eventTimeNs, conditionKeys);
    } else {
        HashableDimensionKey dimensionKey = DEFAULT_DIMENSION_KEY;
        filterValues(mInternalDimensions, event.getValues(), &dimensionKey);
        it->second->noteStart(dimensionKey, condition, event.GetElapsedTimestampNs(),
                              conditionKeys);
        filterValues(mInternalDimensions, eventValues, &dimensionKey);
        it->second->noteStart(dimensionKey, condition, eventTimeNs, conditionKeys);
    }

}

void DurationMetricProducer::onMatchedLogEventInternalLocked(
@@ -633,26 +650,32 @@ void DurationMetricProducer::onMatchedLogEventInternalLocked(

void DurationMetricProducer::onMatchedLogEventLocked(const size_t matcherIndex,
                                                     const LogEvent& event) {
    int64_t eventTimeNs = event.GetElapsedTimestampNs();
    handleMatchedLogEventValuesLocked(matcherIndex, event.getValues(),
                                      event.GetElapsedTimestampNs());
}

void DurationMetricProducer::handleMatchedLogEventValuesLocked(const size_t matcherIndex,
                                                               const vector<FieldValue>& values,
                                                               const int64_t eventTimeNs) {
    if (eventTimeNs < mTimeBaseNs) {
        return;
    }

    if (mIsActive) {
        flushIfNeededLocked(event.GetElapsedTimestampNs());
        flushIfNeededLocked(eventTimeNs);
    }

    // Handles Stopall events.
    if ((int)matcherIndex == mStopAllIndex) {
        for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
            whatIt.second->noteStopAll(event.GetElapsedTimestampNs());
            whatIt.second->noteStopAll(eventTimeNs);
        }
        return;
    }

    HashableDimensionKey dimensionInWhat = DEFAULT_DIMENSION_KEY;
    if (!mDimensionsInWhat.empty()) {
        filterValues(mDimensionsInWhat, event.getValues(), &dimensionInWhat);
        filterValues(mDimensionsInWhat, values, &dimensionInWhat);
    }

    // Stores atom id to primary key pairs for each state atom that the metric is
@@ -663,8 +686,7 @@ void DurationMetricProducer::onMatchedLogEventLocked(const size_t matcherIndex,
    // field values from the log event. These values will form a primary key
    // that will be used to query StateTracker for the correct state value.
    for (const auto& stateLink : mMetric2StateLinks) {
        getDimensionForState(event.getValues(), stateLink,
                             &statePrimaryKeys[stateLink.stateAtomId]);
        getDimensionForState(values, stateLink, &statePrimaryKeys[stateLink.stateAtomId]);
    }

    // For each sliced state, query StateTracker for the state value using
@@ -695,19 +717,19 @@ void DurationMetricProducer::onMatchedLogEventLocked(const size_t matcherIndex,
        if (mUseWhatDimensionAsInternalDimension) {
            auto whatIt = mCurrentSlicedDurationTrackerMap.find(dimensionInWhat);
            if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
                whatIt->second->noteStop(dimensionInWhat, event.GetElapsedTimestampNs(), false);
                whatIt->second->noteStop(dimensionInWhat, eventTimeNs, false);
            }
            return;
        }

        HashableDimensionKey internalDimensionKey = DEFAULT_DIMENSION_KEY;
        if (!mInternalDimensions.empty()) {
            filterValues(mInternalDimensions, event.getValues(), &internalDimensionKey);
            filterValues(mInternalDimensions, values, &internalDimensionKey);
        }

        auto whatIt = mCurrentSlicedDurationTrackerMap.find(dimensionInWhat);
        if (whatIt != mCurrentSlicedDurationTrackerMap.end()) {
            whatIt->second->noteStop(internalDimensionKey, event.GetElapsedTimestampNs(), false);
            whatIt->second->noteStop(internalDimensionKey, eventTimeNs, false);
        }
        return;
    }
@@ -716,7 +738,7 @@ void DurationMetricProducer::onMatchedLogEventLocked(const size_t matcherIndex,
    ConditionKey conditionKey;
    if (mConditionSliced) {
        for (const auto& link : mMetric2ConditionLinks) {
            getDimensionForCondition(event.getValues(), link, &conditionKey[link.conditionId]);
            getDimensionForCondition(values, link, &conditionKey[link.conditionId]);
        }

        auto conditionState =
@@ -731,7 +753,7 @@ void DurationMetricProducer::onMatchedLogEventLocked(const size_t matcherIndex,
    condition = condition && mIsActive;

    handleStartEvent(MetricDimensionKey(dimensionInWhat, stateValuesKey), conditionKey, condition,
                     event);
                     eventTimeNs, values);
}

size_t DurationMetricProducer::byteSizeLocked() const {
Loading