Loading cmds/statsd/src/metrics/ValueMetricProducer.cpp +46 −2 Original line number Diff line number Diff line Loading @@ -18,12 +18,14 @@ #include "Log.h" #include "ValueMetricProducer.h" #include "../guardrail/StatsdStats.h" #include "../stats_log_util.h" #include <limits.h> #include <stdlib.h> #include "../guardrail/StatsdStats.h" #include "../stats_log_util.h" #include "metrics/parsing_utils/metrics_manager_util.h" using android::util::FIELD_COUNT_REPEATED; using android::util::FIELD_TYPE_BOOL; using android::util::FIELD_TYPE_DOUBLE; Loading Loading @@ -184,6 +186,48 @@ ValueMetricProducer::~ValueMetricProducer() { } } bool ValueMetricProducer::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 ValueMetric& metric = config.value_metric(configIndex); // Update appropriate indices: mWhatMatcherIndex, mConditionIndex and MetricsManager maps. if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, /*enforceOneAtom=*/false, allAtomMatchingTrackers, newAtomMatchingTrackerMap, trackerToMetricMap, mWhatMatcherIndex)) { return false; } if (metric.has_condition() && !handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap, metric.links(), allConditionTrackers, mConditionTrackerIndex, conditionToMetricMap)) { return false; } sp<EventMatcherWizard> tmpEventWizard = mEventMatcherWizard; mEventMatcherWizard = matcherWizard; return true; } void ValueMetricProducer::onStateChanged(int64_t eventTimeNs, int32_t atomId, const HashableDimensionKey& primaryKey, const FieldValue& oldState, const FieldValue& newState) { Loading cmds/statsd/src/metrics/ValueMetricProducer.h +20 −2 Original line number Diff line number Diff line Loading @@ -47,7 +47,7 @@ struct PastValueBucket { // - a condition change // - an app upgrade // - an alarm set to the end of the bucket class ValueMetricProducer : public virtual MetricProducer, public virtual PullDataReceiver { class ValueMetricProducer : public MetricProducer, public virtual PullDataReceiver { public: ValueMetricProducer( const ConfigKey& key, const ValueMetric& valueMetric, const int conditionIndex, Loading Loading @@ -155,7 +155,23 @@ private: // causes the bucket to be invalidated will not notify StatsdStats. void skipCurrentBucket(const int64_t dropTimeNs, const BucketDropReason reason); const int mWhatMatcherIndex; 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; int mWhatMatcherIndex; sp<EventMatcherWizard> mEventMatcherWizard; Loading Loading @@ -370,6 +386,8 @@ private: FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPulledValue); FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPulledValueWhileConditionFalse); FRIEND_TEST(ConfigUpdateTest, TestUpdateValueMetrics); friend class ValueMetricProducerTestHelper; }; Loading cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp +40 −2 Original line number Diff line number Diff line Loading @@ -580,7 +580,6 @@ bool determineAllMetricUpdateStatuses(const StatsdConfig& config, return false; } } // TODO: determine update status for value metrics. return true; } Loading Loading @@ -749,8 +748,8 @@ bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64 newMetricProducers.push_back(producer.value()); } 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); newMetricProducerMap[metric.id()] = metricIndex; optional<sp<MetricProducer>> producer; switch (metricsToUpdate[metricIndex]) { case UPDATE_PRESERVE: { Loading Loading @@ -784,6 +783,45 @@ bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64 } newMetricProducers.push_back(producer.value()); } for (int i = 0; i < config.value_metric_size(); i++, metricIndex++) { const ValueMetric& metric = config.value_metric(i); newMetricProducerMap[metric.id()] = metricIndex; optional<sp<MetricProducer>> producer; switch (metricsToUpdate[metricIndex]) { case UPDATE_PRESERVE: { producer = updateMetric( config, i, metricIndex, metric.id(), allAtomMatchingTrackers, oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard, allConditionTrackers, conditionTrackerMap, wizard, oldMetricProducerMap, oldMetricProducers, metricToActivationMap, trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, metricsWithActivation); break; } case UPDATE_REPLACE: case UPDATE_NEW: { producer = createValueMetricProducerAndUpdateMetadata( key, config, timeBaseNs, currentTimeNs, pullerManager, metric, metricIndex, allAtomMatchingTrackers, newAtomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap, initialConditionCache, wizard, matcherWizard, stateAtomIdMap, allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, metricsWithActivation); break; } default: { ALOGE("Metric \"%lld\" update state is unknown. This should never happen", (long long)metric.id()); return false; } } if (!producer) { return false; } newMetricProducers.push_back(producer.value()); } for (int i = 0; i < config.gauge_metric_size(); i++, metricIndex++) { const GaugeMetric& metric = config.gauge_metric(i); newMetricProducerMap[metric.id()] = metricIndex; Loading cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp +111 −86 Original line number Diff line number Diff line Loading @@ -599,6 +599,108 @@ optional<sp<MetricProducer>> createEventMetricProducerAndUpdateMetadata( eventDeactivationMap)}; } optional<sp<MetricProducer>> createValueMetricProducerAndUpdateMetadata( const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager, const ValueMetric& 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 sp<EventMatcherWizard>& matcherWizard, 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()) { ALOGE("cannot find metric id or \"what\" in ValueMetric \"%lld\"", (long long)metric.id()); return nullopt; } if (!metric.has_value_field()) { ALOGE("cannot find \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id()); return nullopt; } std::vector<Matcher> fieldMatchers; translateFieldMatcher(metric.value_field(), &fieldMatchers); if (fieldMatchers.size() < 1) { ALOGE("incorrect \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id()); return nullopt; } int trackerIndex; if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, metric.has_dimensions_in_what(), allAtomMatchingTrackers, atomMatchingTrackerMap, trackerToMetricMap, trackerIndex)) { return nullopt; } sp<AtomMatchingTracker> atomMatcher = allAtomMatchingTrackers.at(trackerIndex); // If it is pulled atom, it should be simple matcher with one tagId. if (atomMatcher->getAtomIds().size() != 1) { return nullopt; } int atomTagId = *(atomMatcher->getAtomIds().begin()); int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1; int conditionIndex = -1; if (metric.has_condition()) { if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap, metric.links(), allConditionTrackers, conditionIndex, conditionToMetricMap)) { return nullopt; } } else if (metric.links_size() > 0) { ALOGE("metrics has a MetricConditionLink but doesn't have a condition"); return nullopt; } 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 nullopt; } } else if (metric.state_link_size() > 0) { ALOGE("ValueMetric has a MetricStateLink but doesn't have a sliced state"); return nullopt; } // Check that all metric state links are a subset of dimensions_in_what fields. std::vector<Matcher> dimensionsInWhat; translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat); for (const auto& stateLink : metric.state_link()) { if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) { return nullopt; } } 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 nullopt; } uint64_t metricHash; if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) { return nullopt; } return {new ValueMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard, metricHash, trackerIndex, matcherWizard, pullTagId, timeBaseNs, currentTimeNs, pullerManager, eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap)}; } optional<sp<MetricProducer>> createGaugeMetricProducerAndUpdateMetadata( const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager, Loading Loading @@ -911,97 +1013,20 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t // build ValueMetricProducer for (int i = 0; i < config.value_metric_size(); i++) { const ValueMetric& metric = config.value_metric(i); if (!metric.has_what()) { ALOGW("cannot find \"what\" in ValueMetric \"%lld\"", (long long)metric.id()); return false; } if (!metric.has_value_field()) { ALOGW("cannot find \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id()); return false; } std::vector<Matcher> fieldMatchers; translateFieldMatcher(metric.value_field(), &fieldMatchers); if (fieldMatchers.size() < 1) { ALOGW("incorrect \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id()); return false; } int metricIndex = allMetricProducers.size(); const ValueMetric& metric = config.value_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; } sp<AtomMatchingTracker> atomMatcher = allAtomMatchingTrackers.at(trackerIndex); // If it is pulled atom, it should be simple matcher with one tagId. if (atomMatcher->getAtomIds().size() != 1) { return false; } int atomTagId = *(atomMatcher->getAtomIds().begin()); int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1; int conditionIndex = -1; if (metric.has_condition()) { bool good = handleMetricWithConditions( metric.condition(), metricIndex, conditionTrackerMap, metric.links(), allConditionTrackers, conditionIndex, conditionToMetricMap); if (!good) { 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("ValueMetric has a MetricStateLink but doesn't have a sliced state"); return false; } } // Check that all metric state links are a subset of dimensions_in_what fields. std::vector<Matcher> dimensionsInWhat; translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat); for (const auto& stateLink : metric.state_link()) { if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) { 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, optional<sp<MetricProducer>> producer = createValueMetricProducerAndUpdateMetadata( key, config, timeBaseTimeNs, currentTimeNs, pullerManager, metric, metricIndex, allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap, initialConditionCache, wizard, matcherWizard, 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) { return false; } sp<MetricProducer> valueProducer = new ValueMetricProducer( key, metric, conditionIndex, initialConditionCache, wizard, metricHash, trackerIndex, matcherWizard, pullTagId, timeBaseTimeNs, currentTimeNs, pullerManager, eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap); allMetricProducers.push_back(valueProducer); allMetricProducers.push_back(producer.value()); } // Gauge metrics. Loading cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h +21 −0 Original line number Diff line number Diff line Loading @@ -148,6 +148,27 @@ optional<sp<MetricProducer>> createEventMetricProducerAndUpdateMetadata( std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap, std::vector<int>& metricsWithActivation); // Creates a CountMetricProducer and updates the vectors/maps used by MetricsManager with // the appropriate indices. Returns an sp to the producer, or nullopt if there was an error. optional<sp<MetricProducer>> createValueMetricProducerAndUpdateMetadata( const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager, const ValueMetric& metric, const int metricIndex, const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, const std::unordered_map<int64_t, int>& atomMatchingTrackerMap, std::vector<sp<ConditionTracker>>& allConditionTrackers, const std::unordered_map<int64_t, int>& conditionTrackerMap, const std::vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard, const sp<EventMatcherWizard>& matcherWizard, const std::unordered_map<int64_t, int>& stateAtomIdMap, const std::unordered_map<int64_t, std::unordered_map<int, int64_t>>& allStateGroupMaps, 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); // Creates a GaugeMetricProducer and updates the vectors/maps used by MetricsManager with // the appropriate indices. Returns an sp to the producer, or nullopt if there was an error. optional<sp<MetricProducer>> createGaugeMetricProducerAndUpdateMetadata( Loading Loading
cmds/statsd/src/metrics/ValueMetricProducer.cpp +46 −2 Original line number Diff line number Diff line Loading @@ -18,12 +18,14 @@ #include "Log.h" #include "ValueMetricProducer.h" #include "../guardrail/StatsdStats.h" #include "../stats_log_util.h" #include <limits.h> #include <stdlib.h> #include "../guardrail/StatsdStats.h" #include "../stats_log_util.h" #include "metrics/parsing_utils/metrics_manager_util.h" using android::util::FIELD_COUNT_REPEATED; using android::util::FIELD_TYPE_BOOL; using android::util::FIELD_TYPE_DOUBLE; Loading Loading @@ -184,6 +186,48 @@ ValueMetricProducer::~ValueMetricProducer() { } } bool ValueMetricProducer::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 ValueMetric& metric = config.value_metric(configIndex); // Update appropriate indices: mWhatMatcherIndex, mConditionIndex and MetricsManager maps. if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, /*enforceOneAtom=*/false, allAtomMatchingTrackers, newAtomMatchingTrackerMap, trackerToMetricMap, mWhatMatcherIndex)) { return false; } if (metric.has_condition() && !handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap, metric.links(), allConditionTrackers, mConditionTrackerIndex, conditionToMetricMap)) { return false; } sp<EventMatcherWizard> tmpEventWizard = mEventMatcherWizard; mEventMatcherWizard = matcherWizard; return true; } void ValueMetricProducer::onStateChanged(int64_t eventTimeNs, int32_t atomId, const HashableDimensionKey& primaryKey, const FieldValue& oldState, const FieldValue& newState) { Loading
cmds/statsd/src/metrics/ValueMetricProducer.h +20 −2 Original line number Diff line number Diff line Loading @@ -47,7 +47,7 @@ struct PastValueBucket { // - a condition change // - an app upgrade // - an alarm set to the end of the bucket class ValueMetricProducer : public virtual MetricProducer, public virtual PullDataReceiver { class ValueMetricProducer : public MetricProducer, public virtual PullDataReceiver { public: ValueMetricProducer( const ConfigKey& key, const ValueMetric& valueMetric, const int conditionIndex, Loading Loading @@ -155,7 +155,23 @@ private: // causes the bucket to be invalidated will not notify StatsdStats. void skipCurrentBucket(const int64_t dropTimeNs, const BucketDropReason reason); const int mWhatMatcherIndex; 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; int mWhatMatcherIndex; sp<EventMatcherWizard> mEventMatcherWizard; Loading Loading @@ -370,6 +386,8 @@ private: FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPulledValue); FRIEND_TEST(ValueMetricProducerTest_PartialBucket, TestPulledValueWhileConditionFalse); FRIEND_TEST(ConfigUpdateTest, TestUpdateValueMetrics); friend class ValueMetricProducerTestHelper; }; Loading
cmds/statsd/src/metrics/parsing_utils/config_update_utils.cpp +40 −2 Original line number Diff line number Diff line Loading @@ -580,7 +580,6 @@ bool determineAllMetricUpdateStatuses(const StatsdConfig& config, return false; } } // TODO: determine update status for value metrics. return true; } Loading Loading @@ -749,8 +748,8 @@ bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64 newMetricProducers.push_back(producer.value()); } 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); newMetricProducerMap[metric.id()] = metricIndex; optional<sp<MetricProducer>> producer; switch (metricsToUpdate[metricIndex]) { case UPDATE_PRESERVE: { Loading Loading @@ -784,6 +783,45 @@ bool updateMetrics(const ConfigKey& key, const StatsdConfig& config, const int64 } newMetricProducers.push_back(producer.value()); } for (int i = 0; i < config.value_metric_size(); i++, metricIndex++) { const ValueMetric& metric = config.value_metric(i); newMetricProducerMap[metric.id()] = metricIndex; optional<sp<MetricProducer>> producer; switch (metricsToUpdate[metricIndex]) { case UPDATE_PRESERVE: { producer = updateMetric( config, i, metricIndex, metric.id(), allAtomMatchingTrackers, oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard, allConditionTrackers, conditionTrackerMap, wizard, oldMetricProducerMap, oldMetricProducers, metricToActivationMap, trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, metricsWithActivation); break; } case UPDATE_REPLACE: case UPDATE_NEW: { producer = createValueMetricProducerAndUpdateMetadata( key, config, timeBaseNs, currentTimeNs, pullerManager, metric, metricIndex, allAtomMatchingTrackers, newAtomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap, initialConditionCache, wizard, matcherWizard, stateAtomIdMap, allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap, metricsWithActivation); break; } default: { ALOGE("Metric \"%lld\" update state is unknown. This should never happen", (long long)metric.id()); return false; } } if (!producer) { return false; } newMetricProducers.push_back(producer.value()); } for (int i = 0; i < config.gauge_metric_size(); i++, metricIndex++) { const GaugeMetric& metric = config.gauge_metric(i); newMetricProducerMap[metric.id()] = metricIndex; Loading
cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp +111 −86 Original line number Diff line number Diff line Loading @@ -599,6 +599,108 @@ optional<sp<MetricProducer>> createEventMetricProducerAndUpdateMetadata( eventDeactivationMap)}; } optional<sp<MetricProducer>> createValueMetricProducerAndUpdateMetadata( const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager, const ValueMetric& 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 sp<EventMatcherWizard>& matcherWizard, 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()) { ALOGE("cannot find metric id or \"what\" in ValueMetric \"%lld\"", (long long)metric.id()); return nullopt; } if (!metric.has_value_field()) { ALOGE("cannot find \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id()); return nullopt; } std::vector<Matcher> fieldMatchers; translateFieldMatcher(metric.value_field(), &fieldMatchers); if (fieldMatchers.size() < 1) { ALOGE("incorrect \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id()); return nullopt; } int trackerIndex; if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, metric.has_dimensions_in_what(), allAtomMatchingTrackers, atomMatchingTrackerMap, trackerToMetricMap, trackerIndex)) { return nullopt; } sp<AtomMatchingTracker> atomMatcher = allAtomMatchingTrackers.at(trackerIndex); // If it is pulled atom, it should be simple matcher with one tagId. if (atomMatcher->getAtomIds().size() != 1) { return nullopt; } int atomTagId = *(atomMatcher->getAtomIds().begin()); int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1; int conditionIndex = -1; if (metric.has_condition()) { if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap, metric.links(), allConditionTrackers, conditionIndex, conditionToMetricMap)) { return nullopt; } } else if (metric.links_size() > 0) { ALOGE("metrics has a MetricConditionLink but doesn't have a condition"); return nullopt; } 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 nullopt; } } else if (metric.state_link_size() > 0) { ALOGE("ValueMetric has a MetricStateLink but doesn't have a sliced state"); return nullopt; } // Check that all metric state links are a subset of dimensions_in_what fields. std::vector<Matcher> dimensionsInWhat; translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat); for (const auto& stateLink : metric.state_link()) { if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) { return nullopt; } } 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 nullopt; } uint64_t metricHash; if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) { return nullopt; } return {new ValueMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard, metricHash, trackerIndex, matcherWizard, pullTagId, timeBaseNs, currentTimeNs, pullerManager, eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap)}; } optional<sp<MetricProducer>> createGaugeMetricProducerAndUpdateMetadata( const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager, Loading Loading @@ -911,97 +1013,20 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t // build ValueMetricProducer for (int i = 0; i < config.value_metric_size(); i++) { const ValueMetric& metric = config.value_metric(i); if (!metric.has_what()) { ALOGW("cannot find \"what\" in ValueMetric \"%lld\"", (long long)metric.id()); return false; } if (!metric.has_value_field()) { ALOGW("cannot find \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id()); return false; } std::vector<Matcher> fieldMatchers; translateFieldMatcher(metric.value_field(), &fieldMatchers); if (fieldMatchers.size() < 1) { ALOGW("incorrect \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id()); return false; } int metricIndex = allMetricProducers.size(); const ValueMetric& metric = config.value_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; } sp<AtomMatchingTracker> atomMatcher = allAtomMatchingTrackers.at(trackerIndex); // If it is pulled atom, it should be simple matcher with one tagId. if (atomMatcher->getAtomIds().size() != 1) { return false; } int atomTagId = *(atomMatcher->getAtomIds().begin()); int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1; int conditionIndex = -1; if (metric.has_condition()) { bool good = handleMetricWithConditions( metric.condition(), metricIndex, conditionTrackerMap, metric.links(), allConditionTrackers, conditionIndex, conditionToMetricMap); if (!good) { 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("ValueMetric has a MetricStateLink but doesn't have a sliced state"); return false; } } // Check that all metric state links are a subset of dimensions_in_what fields. std::vector<Matcher> dimensionsInWhat; translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat); for (const auto& stateLink : metric.state_link()) { if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) { 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, optional<sp<MetricProducer>> producer = createValueMetricProducerAndUpdateMetadata( key, config, timeBaseTimeNs, currentTimeNs, pullerManager, metric, metricIndex, allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap, initialConditionCache, wizard, matcherWizard, 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) { return false; } sp<MetricProducer> valueProducer = new ValueMetricProducer( key, metric, conditionIndex, initialConditionCache, wizard, metricHash, trackerIndex, matcherWizard, pullTagId, timeBaseTimeNs, currentTimeNs, pullerManager, eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap); allMetricProducers.push_back(valueProducer); allMetricProducers.push_back(producer.value()); } // Gauge metrics. Loading
cmds/statsd/src/metrics/parsing_utils/metrics_manager_util.h +21 −0 Original line number Diff line number Diff line Loading @@ -148,6 +148,27 @@ optional<sp<MetricProducer>> createEventMetricProducerAndUpdateMetadata( std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap, std::vector<int>& metricsWithActivation); // Creates a CountMetricProducer and updates the vectors/maps used by MetricsManager with // the appropriate indices. Returns an sp to the producer, or nullopt if there was an error. optional<sp<MetricProducer>> createValueMetricProducerAndUpdateMetadata( const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager, const ValueMetric& metric, const int metricIndex, const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, const std::unordered_map<int64_t, int>& atomMatchingTrackerMap, std::vector<sp<ConditionTracker>>& allConditionTrackers, const std::unordered_map<int64_t, int>& conditionTrackerMap, const std::vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard, const sp<EventMatcherWizard>& matcherWizard, const std::unordered_map<int64_t, int>& stateAtomIdMap, const std::unordered_map<int64_t, std::unordered_map<int, int64_t>>& allStateGroupMaps, 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); // Creates a GaugeMetricProducer and updates the vectors/maps used by MetricsManager with // the appropriate indices. Returns an sp to the producer, or nullopt if there was an error. optional<sp<MetricProducer>> createGaugeMetricProducerAndUpdateMetadata( Loading