diff options
| author | 2020-04-03 18:13:06 +0000 | |
|---|---|---|
| committer | 2020-04-03 18:13:06 +0000 | |
| commit | d4abb2f9ff318bc6cb84157d587f40a6afb9a7de (patch) | |
| tree | a4e42414f072b6f5e8f47e6643b754ea9c5f225f | |
| parent | 85ac2217f82f9358e4aecd4821dc3630c18e0561 (diff) | |
| parent | 3d8e12a5ef5ec1d53addc13fc36fd5b53777fb4f (diff) | |
Merge "Remove StateConditionTracker from statsd" into rvc-dev
| -rw-r--r-- | cmds/statsd/Android.bp | 2 | ||||
| -rw-r--r-- | cmds/statsd/src/condition/StateConditionTracker.cpp | 207 | ||||
| -rw-r--r-- | cmds/statsd/src/condition/StateConditionTracker.h | 117 | ||||
| -rw-r--r-- | cmds/statsd/src/metrics/metrics_manager_util.cpp | 56 | ||||
| -rw-r--r-- | cmds/statsd/src/metrics/metrics_manager_util.h | 2 | ||||
| -rw-r--r-- | cmds/statsd/tests/condition/StateConditionTracker_test.cpp | 113 |
6 files changed, 2 insertions, 495 deletions
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp index 20f9e76b4436..d3d7e1d483e8 100644 --- a/cmds/statsd/Android.bp +++ b/cmds/statsd/Android.bp @@ -56,7 +56,6 @@ cc_defaults { "src/condition/condition_util.cpp", "src/condition/ConditionWizard.cpp", "src/condition/SimpleConditionTracker.cpp", - "src/condition/StateConditionTracker.cpp", "src/config/ConfigKey.cpp", "src/config/ConfigListener.cpp", "src/config/ConfigManager.cpp", @@ -315,7 +314,6 @@ cc_test { "tests/condition/CombinationConditionTracker_test.cpp", "tests/condition/ConditionTimer_test.cpp", "tests/condition/SimpleConditionTracker_test.cpp", - "tests/condition/StateConditionTracker_test.cpp", "tests/ConfigManager_test.cpp", "tests/e2e/Alarm_e2e_test.cpp", "tests/e2e/Anomaly_count_e2e_test.cpp", diff --git a/cmds/statsd/src/condition/StateConditionTracker.cpp b/cmds/statsd/src/condition/StateConditionTracker.cpp deleted file mode 100644 index d19a1761ac00..000000000000 --- a/cmds/statsd/src/condition/StateConditionTracker.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2018, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#define DEBUG false // STOPSHIP if true -#include "Log.h" - -#include "StateConditionTracker.h" -#include "guardrail/StatsdStats.h" - -namespace android { -namespace os { -namespace statsd { - -using std::vector; - -StateConditionTracker::StateConditionTracker(const ConfigKey& key, const int64_t& id, const int index, - const SimplePredicate& simplePredicate, - const unordered_map<int64_t, int>& trackerNameIndexMap, - const vector<Matcher> primaryKeys) - : ConditionTracker(id, index), mConfigKey(key), mPrimaryKeys(primaryKeys) { - if (simplePredicate.has_start()) { - auto pair = trackerNameIndexMap.find(simplePredicate.start()); - if (pair == trackerNameIndexMap.end()) { - ALOGW("Start matcher %lld not found in the config", (long long)simplePredicate.start()); - return; - } - mStartLogMatcherIndex = pair->second; - mTrackerIndex.insert(mStartLogMatcherIndex); - } else { - ALOGW("Condition %lld must have a start matcher", (long long)id); - return; - } - - if (simplePredicate.has_dimensions()) { - translateFieldMatcher(simplePredicate.dimensions(), &mOutputDimensions); - if (mOutputDimensions.size() > 0) { - mSliced = true; - mDimensionTag = mOutputDimensions[0].mMatcher.getTag(); - } else { - ALOGW("Condition %lld has invalid dimensions", (long long)id); - return; - } - } else { - ALOGW("Condition %lld being a state tracker, but has no dimension", (long long)id); - return; - } - - if (simplePredicate.initial_value() == SimplePredicate_InitialValue_FALSE) { - mInitialValue = ConditionState::kFalse; - } else { - mInitialValue = ConditionState::kUnknown; - } - - mNonSlicedConditionState = mInitialValue; - mInitialized = true; -} - -StateConditionTracker::~StateConditionTracker() { - VLOG("~StateConditionTracker()"); -} - -bool StateConditionTracker::init(const vector<Predicate>& allConditionConfig, - const vector<sp<ConditionTracker>>& allConditionTrackers, - const unordered_map<int64_t, int>& conditionIdIndexMap, - vector<bool>& stack) { - return mInitialized; -} - -void StateConditionTracker::dumpState() { - VLOG("StateConditionTracker %lld DUMP:", (long long)mConditionId); - for (const auto& value : mSlicedState) { - VLOG("\t%s -> %s", value.first.toString().c_str(), value.second.toString().c_str()); - } - VLOG("Last Changed to True: "); - for (const auto& value : mLastChangedToTrueDimensions) { - VLOG("%s", value.toString().c_str()); - } - VLOG("Last Changed to False: "); - for (const auto& value : mLastChangedToFalseDimensions) { - VLOG("%s", value.toString().c_str()); - } -} - -bool StateConditionTracker::hitGuardRail(const HashableDimensionKey& newKey) { - if (mSlicedState.find(newKey) != mSlicedState.end()) { - // if the condition is not sliced or the key is not new, we are good! - return false; - } - // 1. Report the tuple count if the tuple count > soft limit - if (mSlicedState.size() > StatsdStats::kDimensionKeySizeSoftLimit - 1) { - size_t newTupleCount = mSlicedState.size() + 1; - StatsdStats::getInstance().noteConditionDimensionSize(mConfigKey, mConditionId, newTupleCount); - // 2. Don't add more tuples, we are above the allowed threshold. Drop the data. - if (newTupleCount > StatsdStats::kDimensionKeySizeHardLimit) { - ALOGE("Predicate %lld dropping data for dimension key %s", - (long long)mConditionId, newKey.toString().c_str()); - return true; - } - } - return false; -} - -void StateConditionTracker::evaluateCondition(const LogEvent& event, - const vector<MatchingState>& eventMatcherValues, - const vector<sp<ConditionTracker>>& mAllConditions, - vector<ConditionState>& conditionCache, - vector<bool>& conditionChangedCache) { - mLastChangedToTrueDimensions.clear(); - mLastChangedToFalseDimensions.clear(); - if (conditionCache[mIndex] != ConditionState::kNotEvaluated) { - // it has been evaluated. - VLOG("Yes, already evaluated, %lld %d", (long long)mConditionId, conditionCache[mIndex]); - return; - } - - if (mStartLogMatcherIndex >= 0 && - eventMatcherValues[mStartLogMatcherIndex] != MatchingState::kMatched) { - conditionCache[mIndex] = - mSlicedState.size() > 0 ? ConditionState::kTrue : ConditionState::kFalse; - conditionChangedCache[mIndex] = false; - return; - } - - VLOG("StateConditionTracker evaluate event %s", event.ToString().c_str()); - - // Primary key can exclusive fields must be simple fields. so there won't be more than - // one keys matched. - HashableDimensionKey primaryKey; - HashableDimensionKey state; - if ((mPrimaryKeys.size() > 0 && !filterValues(mPrimaryKeys, event.getValues(), &primaryKey)) || - !filterValues(mOutputDimensions, event.getValues(), &state)) { - ALOGE("Failed to filter fields in the event?? panic now!"); - conditionCache[mIndex] = - mSlicedState.size() > 0 ? ConditionState::kTrue : ConditionState::kFalse; - conditionChangedCache[mIndex] = false; - return; - } - hitGuardRail(primaryKey); - - VLOG("StateConditionTracker: key %s state %s", primaryKey.toString().c_str(), state.toString().c_str()); - - auto it = mSlicedState.find(primaryKey); - if (it == mSlicedState.end()) { - mSlicedState[primaryKey] = state; - conditionCache[mIndex] = ConditionState::kTrue; - mLastChangedToTrueDimensions.insert(state); - conditionChangedCache[mIndex] = true; - } else if (!(it->second == state)) { - mLastChangedToFalseDimensions.insert(it->second); - mLastChangedToTrueDimensions.insert(state); - mSlicedState[primaryKey] = state; - conditionCache[mIndex] = ConditionState::kTrue; - conditionChangedCache[mIndex] = true; - } else { - conditionCache[mIndex] = ConditionState::kTrue; - conditionChangedCache[mIndex] = false; - } - - if (DEBUG) { - dumpState(); - } - return; -} - -void StateConditionTracker::isConditionMet( - const ConditionKey& conditionParameters, const vector<sp<ConditionTracker>>& allConditions, - const bool isPartialLink, - vector<ConditionState>& conditionCache) const { - if (conditionCache[mIndex] != ConditionState::kNotEvaluated) { - // it has been evaluated. - VLOG("Yes, already evaluated, %lld %d", (long long)mConditionId, conditionCache[mIndex]); - return; - } - - const auto pair = conditionParameters.find(mConditionId); - if (pair == conditionParameters.end()) { - if (mSlicedState.size() > 0) { - conditionCache[mIndex] = ConditionState::kTrue; - } else { - conditionCache[mIndex] = ConditionState::kUnknown; - } - return; - } - - const auto& primaryKey = pair->second; - conditionCache[mIndex] = mInitialValue; - auto it = mSlicedState.find(primaryKey); - if (it != mSlicedState.end()) { - conditionCache[mIndex] = ConditionState::kTrue; - } -} - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/src/condition/StateConditionTracker.h b/cmds/statsd/src/condition/StateConditionTracker.h deleted file mode 100644 index 0efe1fb3fcb2..000000000000 --- a/cmds/statsd/src/condition/StateConditionTracker.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2018, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include <gtest/gtest_prod.h> -#include "ConditionTracker.h" -#include "config/ConfigKey.h" -#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" -#include "stats_util.h" - -namespace android { -namespace os { -namespace statsd { - -class StateConditionTracker : public virtual ConditionTracker { -public: - StateConditionTracker(const ConfigKey& key, const int64_t& id, const int index, - const SimplePredicate& simplePredicate, - const std::unordered_map<int64_t, int>& trackerNameIndexMap, - const vector<Matcher> primaryKeys); - - ~StateConditionTracker(); - - bool init(const std::vector<Predicate>& allConditionConfig, - const std::vector<sp<ConditionTracker>>& allConditionTrackers, - const std::unordered_map<int64_t, int>& conditionIdIndexMap, - std::vector<bool>& stack) override; - - void evaluateCondition(const LogEvent& event, - const std::vector<MatchingState>& eventMatcherValues, - const std::vector<sp<ConditionTracker>>& mAllConditions, - std::vector<ConditionState>& conditionCache, - std::vector<bool>& changedCache) override; - - /** - * Note: dimensionFields will be ignored in StateConditionTracker, because we demand metrics - * must take the entire dimension fields from StateConditionTracker. This is to make implementation - * simple and efficient. - * - * For example: wakelock duration by uid process states: - * dimension in condition must be {uid, process state}. - */ - void isConditionMet(const ConditionKey& conditionParameters, - const std::vector<sp<ConditionTracker>>& allConditions, - const bool isPartialLink, - std::vector<ConditionState>& conditionCache) const override; - - virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions( - const std::vector<sp<ConditionTracker>>& allConditions) const { - return &mLastChangedToTrueDimensions; - } - - virtual const std::set<HashableDimensionKey>* getChangedToFalseDimensions( - const std::vector<sp<ConditionTracker>>& allConditions) const { - return &mLastChangedToFalseDimensions; - } - - bool IsChangedDimensionTrackable() const override { return true; } - - bool IsSimpleCondition() const override { return true; } - - bool equalOutputDimensions( - const std::vector<sp<ConditionTracker>>& allConditions, - const vector<Matcher>& dimensions) const override { - return equalDimensions(mOutputDimensions, dimensions); - } - - void getTrueSlicedDimensions( - const std::vector<sp<ConditionTracker>>& allConditions, - std::set<HashableDimensionKey>* dimensions) const override { - for (const auto& itr : mSlicedState) { - dimensions->insert(itr.second); - } - } - -private: - const ConfigKey mConfigKey; - - // The index of the LogEventMatcher which defines the start. - int mStartLogMatcherIndex; - - std::set<HashableDimensionKey> mLastChangedToTrueDimensions; - std::set<HashableDimensionKey> mLastChangedToFalseDimensions; - - std::vector<Matcher> mOutputDimensions; - std::vector<Matcher> mPrimaryKeys; - - ConditionState mInitialValue; - - int mDimensionTag; - - void dumpState(); - - bool hitGuardRail(const HashableDimensionKey& newKey); - - // maps from [primary_key] to [primary_key, exclusive_state]. - std::unordered_map<HashableDimensionKey, HashableDimensionKey> mSlicedState; - - FRIEND_TEST(StateConditionTrackerTest, TestStateChange); -}; - -} // namespace statsd -} // namespace os -} // namespace android diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp index 0d0788e05e0a..2fcb13b709f9 100644 --- a/cmds/statsd/src/metrics/metrics_manager_util.cpp +++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp @@ -26,7 +26,6 @@ #include "MetricProducer.h" #include "condition/CombinationConditionTracker.h" #include "condition/SimpleConditionTracker.h" -#include "condition/StateConditionTracker.h" #include "external/StatsPullerManager.h" #include "matchers/CombinationLogMatchingTracker.h" #include "matchers/EventMatcherWizard.h" @@ -283,49 +282,6 @@ bool initLogTrackers(const StatsdConfig& config, const UidMap& uidMap, return true; } -/** - * A StateConditionTracker is built from a SimplePredicate which has only "start", and no "stop" - * or "stop_all". The start must be an atom matcher that matches a state atom. It must - * have dimension, the dimension must be the state atom's primary fields plus exclusive state - * field. For example, the StateConditionTracker is used in tracking UidProcessState and ScreenState. - * - */ -bool isStateConditionTracker(const SimplePredicate& simplePredicate, vector<Matcher>* primaryKeys) { - // 1. must not have "stop". must have "dimension" - if (!simplePredicate.has_stop() && simplePredicate.has_dimensions()) { - auto it = android::util::AtomsInfo::kStateAtomsFieldOptions.find( - simplePredicate.dimensions().field()); - // 2. must be based on a state atom. - if (it != android::util::AtomsInfo::kStateAtomsFieldOptions.end()) { - // 3. dimension must be primary fields + state field IN ORDER - size_t expectedDimensionCount = it->second.primaryFields.size() + 1; - vector<Matcher> dimensions; - translateFieldMatcher(simplePredicate.dimensions(), &dimensions); - if (dimensions.size() != expectedDimensionCount) { - return false; - } - // 3.1 check the primary fields first. - size_t index = 0; - for (const auto& field : it->second.primaryFields) { - Matcher matcher = getSimpleMatcher(it->first, field); - if (!(matcher == dimensions[index])) { - return false; - } - primaryKeys->push_back(matcher); - index++; - } - Matcher stateFieldMatcher = - getSimpleMatcher(it->first, it->second.exclusiveField); - // 3.2 last dimension should be the exclusive field. - if (!(dimensions.back() == stateFieldMatcher)) { - return false; - } - return true; - } - } - return false; -} // namespace statsd - bool initConditions(const ConfigKey& key, const StatsdConfig& config, const unordered_map<int64_t, int>& logTrackerMap, unordered_map<int64_t, int>& conditionTrackerMap, @@ -341,16 +297,8 @@ bool initConditions(const ConfigKey& key, const StatsdConfig& config, int index = allConditionTrackers.size(); switch (condition.contents_case()) { case Predicate::ContentsCase::kSimplePredicate: { - vector<Matcher> primaryKeys; - if (isStateConditionTracker(condition.simple_predicate(), &primaryKeys)) { - allConditionTrackers.push_back(new StateConditionTracker(key, condition.id(), index, - condition.simple_predicate(), - logTrackerMap, primaryKeys)); - } else { - allConditionTrackers.push_back(new SimpleConditionTracker( - key, condition.id(), index, condition.simple_predicate(), - logTrackerMap)); - } + allConditionTrackers.push_back(new SimpleConditionTracker( + key, condition.id(), index, condition.simple_predicate(), logTrackerMap)); break; } case Predicate::ContentsCase::kCombination: { diff --git a/cmds/statsd/src/metrics/metrics_manager_util.h b/cmds/statsd/src/metrics/metrics_manager_util.h index a8ccc6289b9a..6af7a9adca20 100644 --- a/cmds/statsd/src/metrics/metrics_manager_util.h +++ b/cmds/statsd/src/metrics/metrics_manager_util.h @@ -132,8 +132,6 @@ bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& vector<int>& metricsWithActivation, std::set<int64_t>& noReportMetricIds); -bool isStateConditionTracker(const SimplePredicate& simplePredicate, std::vector<Matcher>* primaryKeys); - } // namespace statsd } // namespace os } // namespace android diff --git a/cmds/statsd/tests/condition/StateConditionTracker_test.cpp b/cmds/statsd/tests/condition/StateConditionTracker_test.cpp deleted file mode 100644 index 86b50ae82ff4..000000000000 --- a/cmds/statsd/tests/condition/StateConditionTracker_test.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (C) 2017 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "src/condition/StateConditionTracker.h" -#include "tests/statsd_test_util.h" - -#include <gmock/gmock.h> -#include <gtest/gtest.h> -#include <stdio.h> -#include <numeric> -#include <vector> - -using std::map; -using std::unordered_map; -using std::vector; - -#ifdef __ANDROID__ -namespace android { -namespace os { -namespace statsd { - -const int kUidProcTag = 27; - -SimplePredicate getUidProcStatePredicate() { - SimplePredicate simplePredicate; - simplePredicate.set_start(StringToId("UidProcState")); - - simplePredicate.mutable_dimensions()->set_field(kUidProcTag); - simplePredicate.mutable_dimensions()->add_child()->set_field(1); - simplePredicate.mutable_dimensions()->add_child()->set_field(2); - - simplePredicate.set_count_nesting(false); - return simplePredicate; -} - -// TODO(b/149590301): Update these tests to use new socket schema. -//void makeUidProcStateEvent(int32_t uid, int32_t state, LogEvent* event) { -// event->write(uid); -// event->write(state); -// event->init(); -//} -// -//TEST(StateConditionTrackerTest, TestStateChange) { -// int uid1 = 111; -// int uid2 = 222; -// -// int state1 = 1001; -// int state2 = 1002; -// unordered_map<int64_t, int> trackerNameIndexMap; -// trackerNameIndexMap[StringToId("UidProcState")] = 0; -// vector<Matcher> primaryFields; -// primaryFields.push_back(getSimpleMatcher(kUidProcTag, 1)); -// StateConditionTracker tracker(ConfigKey(12, 123), 123, 0, getUidProcStatePredicate(), -// trackerNameIndexMap, primaryFields); -// -// LogEvent event(kUidProcTag, 0 /*timestamp*/); -// makeUidProcStateEvent(uid1, state1, &event); -// -// vector<MatchingState> matcherState; -// matcherState.push_back(MatchingState::kMatched); -// vector<sp<ConditionTracker>> allPredicates; -// vector<ConditionState> conditionCache(1, ConditionState::kNotEvaluated); -// vector<bool> changedCache(1, false); -// -// tracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, changedCache); -// EXPECT_EQ(1ULL, tracker.mLastChangedToTrueDimensions.size()); -// EXPECT_EQ(0ULL, tracker.mLastChangedToFalseDimensions.size()); -// EXPECT_TRUE(changedCache[0]); -// -// changedCache[0] = false; -// conditionCache[0] = ConditionState::kNotEvaluated; -// tracker.evaluateCondition(event, matcherState, allPredicates, conditionCache, changedCache); -// EXPECT_EQ(0ULL, tracker.mLastChangedToTrueDimensions.size()); -// EXPECT_EQ(0ULL, tracker.mLastChangedToFalseDimensions.size()); -// EXPECT_FALSE(changedCache[0]); -// -// LogEvent event2(kUidProcTag, 0 /*timestamp*/); -// makeUidProcStateEvent(uid1, state2, &event2); -// -// changedCache[0] = false; -// conditionCache[0] = ConditionState::kNotEvaluated; -// tracker.evaluateCondition(event2, matcherState, allPredicates, conditionCache, changedCache); -// EXPECT_EQ(1ULL, tracker.mLastChangedToTrueDimensions.size()); -// EXPECT_EQ(1ULL, tracker.mLastChangedToFalseDimensions.size()); -// EXPECT_TRUE(changedCache[0]); -// -// LogEvent event3(kUidProcTag, 0 /*timestamp*/); -// makeUidProcStateEvent(uid2, state1, &event3); -// changedCache[0] = false; -// conditionCache[0] = ConditionState::kNotEvaluated; -// tracker.evaluateCondition(event3, matcherState, allPredicates, conditionCache, changedCache); -// EXPECT_EQ(1ULL, tracker.mLastChangedToTrueDimensions.size()); -// EXPECT_EQ(0ULL, tracker.mLastChangedToFalseDimensions.size()); -// EXPECT_TRUE(changedCache[0]); -//} - -} // namespace statsd -} // namespace os -} // namespace android -#else -GTEST_LOG_(INFO) << "This test does nothing.\n"; -#endif |