/* * 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. */ #pragma once #include <set> #include <unordered_map> #include <vector> #include "anomaly/AlarmTracker.h" #include "condition/ConditionTracker.h" #include "external/StatsPullerManager.h" #include "matchers/AtomMatchingTracker.h" #include "metrics/MetricProducer.h" namespace android { namespace os { namespace statsd { // Helper functions for creating, validating, and updating config components from StatsdConfig. // Should only be called from metrics_manager_util and config_update_utils. // Create a AtomMatchingTracker. // input: // [logMatcher]: the input AtomMatcher from the StatsdConfig // [index]: the index of the matcher // [invalidConfigReason]: logging ids if config is invalid // output: // new AtomMatchingTracker, or null if the tracker is unable to be created sp<AtomMatchingTracker> createAtomMatchingTracker( const AtomMatcher& logMatcher, const int index, const sp<UidMap>& uidMap, optional<InvalidConfigReason>& invalidConfigReason); // Create a ConditionTracker. // input: // [predicate]: the input Predicate from the StatsdConfig // [index]: the index of the condition tracker // [atomMatchingTrackerMap]: map of atom matcher id to its index in allAtomMatchingTrackers // [invalidConfigReason]: logging ids if config is invalid // output: // new ConditionTracker, or null if the tracker is unable to be created sp<ConditionTracker> createConditionTracker( const ConfigKey& key, const Predicate& predicate, const int index, const unordered_map<int64_t, int>& atomMatchingTrackerMap, optional<InvalidConfigReason>& invalidConfigReason); // Get the hash of a metric, combining the activation if the metric has one. optional<InvalidConfigReason> getMetricProtoHash( const StatsdConfig& config, const google::protobuf::MessageLite& metric, const int64_t id, const std::unordered_map<int64_t, int>& metricToActivationMap, uint64_t& metricHash); // 1. Validates matcher existence // 2. Enforces matchers with dimensions and those used for trigger_event are about one atom // 3. Gets matcher index and updates tracker to metric map optional<InvalidConfigReason> handleMetricWithAtomMatchingTrackers( const int64_t matcherId, const int64_t metricId, const int metricIndex, const bool enforceOneAtom, const std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, const std::unordered_map<int64_t, int>& atomMatchingTrackerMap, std::unordered_map<int, std::vector<int>>& trackerToMetricMap, int& logTrackerIndex); // 1. Validates condition existence, including those in links // 2. Gets condition index and updates condition to metric map optional<InvalidConfigReason> handleMetricWithConditions( const int64_t condition, const int64_t metricId, const int metricIndex, const std::unordered_map<int64_t, int>& conditionTrackerMap, const ::google::protobuf::RepeatedPtrField<MetricConditionLink>& links, const std::vector<sp<ConditionTracker>>& allConditionTrackers, int& conditionIndex, std::unordered_map<int, std::vector<int>>& conditionToMetricMap); // Validates a metricActivation and populates state. // Fills the new event activation/deactivation maps, preserving the existing activations. // Returns nullopt if successful and InvalidConfigReason if not. optional<InvalidConfigReason> handleMetricActivationOnConfigUpdate( const StatsdConfig& config, const int64_t metricId, const int metricIndex, const std::unordered_map<int64_t, int>& metricToActivationMap, const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap, const std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap, const std::unordered_map<int, shared_ptr<Activation>>& oldEventActivationMap, std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap, std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap, std::vector<int>& metricsWithActivation, std::unordered_map<int, shared_ptr<Activation>>& newEventActivationMap, std::unordered_map<int, std::vector<shared_ptr<Activation>>>& newEventDeactivationMap); // 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>> createCountMetricProducerAndUpdateMetadata( const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, const int64_t currentTimeNs, const CountMetric& 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 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, optional<InvalidConfigReason>& invalidConfigReason); // Creates a DurationMetricProducer 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>> createDurationMetricProducerAndUpdateMetadata( const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, const int64_t currentTimeNs, const DurationMetric& 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 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, optional<InvalidConfigReason>& invalidConfigReason); // Creates an EventMetricProducer 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>> createEventMetricProducerAndUpdateMetadata( const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, const EventMetric& 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 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, optional<InvalidConfigReason>& invalidConfigReason); // Creates a NumericValueMetricProducer 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>> createNumericValueMetricProducerAndUpdateMetadata( 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, optional<InvalidConfigReason>& invalidConfigReason); // 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( const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager, const GaugeMetric& 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>& 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, optional<InvalidConfigReason>& invalidConfigReason); // Creates a KllMetricProducer 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>> createKllMetricProducerAndUpdateMetadata( const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs, const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager, const KllMetric& 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, optional<InvalidConfigReason>& invalidConfigReason); // Creates an AnomalyTracker and adds it to the appropriate metric. // Returns an sp to the AnomalyTracker, or nullopt if there was an error. optional<sp<AnomalyTracker>> createAnomalyTracker( const Alert& alert, const sp<AlarmMonitor>& anomalyAlarmMonitor, const UpdateStatus& updateStatus, const int64_t currentTimeNs, const std::unordered_map<int64_t, int>& metricProducerMap, std::vector<sp<MetricProducer>>& allMetricProducers, optional<InvalidConfigReason>& invalidConfigReason); // Templated function for adding subscriptions to alarms or alerts. Returns nullopt if successful // and InvalidConfigReason if not. template <typename T> optional<InvalidConfigReason> initSubscribersForSubscriptionType( const StatsdConfig& config, const Subscription_RuleType ruleType, const std::unordered_map<int64_t, int>& ruleMap, std::vector<T>& allRules) { for (int i = 0; i < config.subscription_size(); ++i) { const Subscription& subscription = config.subscription(i); if (subscription.rule_type() != ruleType) { continue; } if (subscription.subscriber_information_case() == Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) { ALOGW("subscription \"%lld\" has no subscriber info.\"", (long long)subscription.id()); return createInvalidConfigReasonWithSubscription( INVALID_CONFIG_REASON_SUBSCRIPTION_SUBSCRIBER_INFO_MISSING, subscription.id()); } const auto& itr = ruleMap.find(subscription.rule_id()); if (itr == ruleMap.end()) { ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"", (long long)subscription.id(), (long long)subscription.rule_id()); switch (subscription.rule_type()) { case Subscription::ALARM: return createInvalidConfigReasonWithSubscriptionAndAlarm( INVALID_CONFIG_REASON_SUBSCRIPTION_RULE_NOT_FOUND, subscription.id(), subscription.rule_id()); case Subscription::ALERT: return createInvalidConfigReasonWithSubscriptionAndAlert( INVALID_CONFIG_REASON_SUBSCRIPTION_RULE_NOT_FOUND, subscription.id(), subscription.rule_id()); case Subscription::RULE_TYPE_UNSPECIFIED: return createInvalidConfigReasonWithSubscription( INVALID_CONFIG_REASON_SUBSCRIPTION_RULE_NOT_FOUND, subscription.id()); } } const int ruleIndex = itr->second; allRules[ruleIndex]->addSubscription(subscription); } return nullopt; } // Helper functions for MetricsManager to initialize from StatsdConfig. // *Note*: only initStatsdConfig() should be called from outside. // All other functions are intermediate // steps, created to make unit tests easier. And most of the parameters in these // functions are temporary objects in the initialization phase. // Initialize the AtomMatchingTrackers. // input: // [key]: the config key that this config belongs to // [config]: the input StatsdConfig // output: // [atomMatchingTrackerMap]: this map should contain matcher name to index mapping // [allAtomMatchingTrackers]: should store the sp to all the AtomMatchingTracker // [allTagIdsToMatchersMap]: maps of tag ids to atom matchers // Returns nullopt if successful and InvalidConfigReason if not. optional<InvalidConfigReason> initAtomMatchingTrackers( const StatsdConfig& config, const sp<UidMap>& uidMap, std::unordered_map<int64_t, int>& atomMatchingTrackerMap, std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, std::unordered_map<int, std::vector<int>>& allTagIdsToMatchersMap); // Initialize ConditionTrackers // input: // [key]: the config key that this config belongs to // [config]: the input config // [atomMatchingTrackerMap]: AtomMatchingTracker name to index mapping from previous step. // output: // [conditionTrackerMap]: this map should contain condition name to index mapping // [allConditionTrackers]: stores the sp to all the ConditionTrackers // [trackerToConditionMap]: contain the mapping from index of // log tracker to condition trackers that use the log tracker // [initialConditionCache]: stores the initial conditions for each ConditionTracker // Returns nullopt if successful and InvalidConfigReason if not. optional<InvalidConfigReason> initConditions( const ConfigKey& key, const StatsdConfig& config, const std::unordered_map<int64_t, int>& atomMatchingTrackerMap, std::unordered_map<int64_t, int>& conditionTrackerMap, std::vector<sp<ConditionTracker>>& allConditionTrackers, std::unordered_map<int, std::vector<int>>& trackerToConditionMap, std::vector<ConditionState>& initialConditionCache); // Initialize State maps using State protos in the config. These maps will // eventually be passed to MetricProducers to initialize their state info. // input: // [config]: the input config // output: // [stateAtomIdMap]: this map should contain the mapping from state ids to atom ids // [allStateGroupMaps]: this map should contain the mapping from states ids and state // values to state group ids for all states // [stateProtoHashes]: contains a map of state id to the hash of the State proto from the config // Returns nullopt if successful and InvalidConfigReason if not. optional<InvalidConfigReason> initStates( const StatsdConfig& config, unordered_map<int64_t, int>& stateAtomIdMap, unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps, std::map<int64_t, uint64_t>& stateProtoHashes); // Initialize MetricProducers. // input: // [key]: the config key that this config belongs to // [config]: the input config // [timeBaseSec]: start time base for all metrics // [atomMatchingTrackerMap]: AtomMatchingTracker name to index mapping from previous step. // [conditionTrackerMap]: condition name to index mapping // [stateAtomIdMap]: contains the mapping from state ids to atom ids // [allStateGroupMaps]: contains the mapping from atom ids and state values to // state group ids for all states // output: // [allMetricProducers]: contains the list of sp to the MetricProducers created. // [conditionToMetricMap]: contains the mapping from condition tracker index to // the list of MetricProducer index // [trackerToMetricMap]: contains the mapping from log tracker to MetricProducer index. // Returns nullopt if successful and InvalidConfigReason if not. optional<InvalidConfigReason> initMetrics( const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseTimeNs, const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager, const std::unordered_map<int64_t, int>& atomMatchingTrackerMap, const std::unordered_map<int64_t, int>& conditionTrackerMap, const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, const unordered_map<int64_t, int>& stateAtomIdMap, const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps, vector<sp<ConditionTracker>>& allConditionTrackers, const std::vector<ConditionState>& initialConditionCache, std::vector<sp<MetricProducer>>& allMetricProducers, std::unordered_map<int, std::vector<int>>& conditionToMetricMap, std::unordered_map<int, std::vector<int>>& trackerToMetricMap, std::set<int64_t>& noReportMetricIds, std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap, std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap, std::vector<int>& metricsWithActivation); // Initialize alarms // Is called both on initialize new configs and config updates since alarms do not have any state. optional<InvalidConfigReason> initAlarms(const StatsdConfig& config, const ConfigKey& key, const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs, const int64_t currentTimeNs, std::vector<sp<AlarmTracker>>& allAlarmTrackers); // Initialize MetricsManager from StatsdConfig. // Parameters are the members of MetricsManager. See MetricsManager for declaration. optional<InvalidConfigReason> initStatsdConfig( const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap, const sp<StatsPullerManager>& pullerManager, const sp<AlarmMonitor>& anomalyAlarmMonitor, const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs, const int64_t currentTimeNs, std::unordered_map<int, std::vector<int>>& allTagIdsToMatchersMap, std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers, std::unordered_map<int64_t, int>& atomMatchingTrackerMap, std::vector<sp<ConditionTracker>>& allConditionTrackers, std::unordered_map<int64_t, int>& conditionTrackerMap, std::vector<sp<MetricProducer>>& allMetricProducers, std::unordered_map<int64_t, int>& metricProducerMap, vector<sp<AnomalyTracker>>& allAnomalyTrackers, vector<sp<AlarmTracker>>& allPeriodicAlarmTrackers, std::unordered_map<int, std::vector<int>>& conditionToMetricMap, std::unordered_map<int, std::vector<int>>& trackerToMetricMap, std::unordered_map<int, std::vector<int>>& trackerToConditionMap, std::unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap, std::unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap, std::unordered_map<int64_t, int>& alertTrackerMap, std::vector<int>& metricsWithActivation, std::map<int64_t, uint64_t>& stateProtoHashes, std::set<int64_t>& noReportMetricIds); } // namespace statsd } // namespace os } // namespace android