1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <unordered_map> 20 21 #include "anomaly/AlarmMonitor.h" 22 #include "anomaly/AlarmTracker.h" 23 #include "anomaly/AnomalyTracker.h" 24 #include "condition/ConditionTracker.h" 25 #include "config/ConfigKey.h" 26 #include "external/StatsPullerManager.h" 27 #include "guardrail/StatsdStats.h" 28 #include "logd/LogEvent.h" 29 #include "matchers/AtomMatchingTracker.h" 30 #include "metrics/MetricProducer.h" 31 #include "packages/UidMap.h" 32 #include "src/statsd_config.pb.h" 33 #include "src/statsd_metadata.pb.h" 34 35 namespace android { 36 namespace os { 37 namespace statsd { 38 39 // A MetricsManager is responsible for managing metrics from one single config source. 40 class MetricsManager : public virtual RefBase, public virtual PullUidProvider { 41 public: 42 MetricsManager(const ConfigKey& configKey, const StatsdConfig& config, const int64_t timeBaseNs, 43 const int64_t currentTimeNs, const sp<UidMap>& uidMap, 44 const sp<StatsPullerManager>& pullerManager, 45 const sp<AlarmMonitor>& anomalyAlarmMonitor, 46 const sp<AlarmMonitor>& periodicAlarmMonitor); 47 48 virtual ~MetricsManager(); 49 50 bool updateConfig(const StatsdConfig& config, const int64_t timeBaseNs, 51 const int64_t currentTimeNs, const sp<AlarmMonitor>& anomalyAlarmMonitor, 52 const sp<AlarmMonitor>& periodicAlarmMonitor); 53 54 // Return whether the configuration is valid. 55 bool isConfigValid() const; 56 57 bool checkLogCredentials(const LogEvent& event); 58 59 bool eventSanityCheck(const LogEvent& event); 60 61 virtual void onLogEvent(const LogEvent& event); 62 63 void onAnomalyAlarmFired( 64 const int64_t& timestampNs, 65 unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet); 66 67 void onPeriodicAlarmFired( 68 const int64_t& timestampNs, 69 unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet); 70 71 void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid, 72 const int64_t version); 73 74 void notifyAppRemoved(const int64_t& eventTimeNs, const string& apk, const int uid); 75 76 void onUidMapReceived(const int64_t& eventTimeNs); 77 78 void onStatsdInitCompleted(const int64_t& elapsedTimeNs); 79 80 void init(); 81 82 vector<int32_t> getPullAtomUids(int32_t atomId) override; 83 shouldWriteToDisk()84 bool shouldWriteToDisk() const { 85 return mNoReportMetricIds.size() != mAllMetricProducers.size(); 86 } 87 shouldPersistLocalHistory()88 bool shouldPersistLocalHistory() const { 89 return mShouldPersistHistory; 90 } 91 92 void dumpStates(FILE* out, bool verbose); 93 isInTtl(const int64_t timestampNs)94 inline bool isInTtl(const int64_t timestampNs) const { 95 return mTtlNs <= 0 || timestampNs < mTtlEndNs; 96 }; 97 hashStringInReport()98 inline bool hashStringInReport() const { 99 return mHashStringsInReport; 100 }; 101 versionStringsInReport()102 inline bool versionStringsInReport() const { 103 return mVersionStringsInReport; 104 }; 105 installerInReport()106 inline bool installerInReport() const { 107 return mInstallerInReport; 108 }; 109 packageCertificateHashSizeBytes()110 inline uint8_t packageCertificateHashSizeBytes() const { 111 return mPackageCertificateHashSizeBytes; 112 } 113 refreshTtl(const int64_t currentTimestampNs)114 void refreshTtl(const int64_t currentTimestampNs) { 115 if (mTtlNs > 0) { 116 mTtlEndNs = currentTimestampNs + mTtlNs; 117 } 118 }; 119 120 // Returns the elapsed realtime when this metric manager last reported metrics. If this config 121 // has not yet dumped any reports, this is the time the metricsmanager was initialized. getLastReportTimeNs()122 inline int64_t getLastReportTimeNs() const { 123 return mLastReportTimeNs; 124 }; 125 getLastReportWallClockNs()126 inline int64_t getLastReportWallClockNs() const { 127 return mLastReportWallClockNs; 128 }; 129 getNumMetrics()130 inline size_t getNumMetrics() const { 131 return mAllMetricProducers.size(); 132 } 133 134 virtual void dropData(const int64_t dropTimeNs); 135 136 virtual void onDumpReport(const int64_t dumpTimeNs, const int64_t wallClockNs, 137 const bool include_current_partial_bucket, const bool erase_data, 138 const DumpLatency dumpLatency, std::set<string>* str_set, 139 android::util::ProtoOutputStream* protoOutput); 140 141 // Computes the total byte size of all metrics managed by a single config source. 142 // Does not change the state. 143 virtual size_t byteSize(); 144 145 // Returns whether or not this config is active. 146 // The config is active if any metric in the config is active. isActive()147 inline bool isActive() const { 148 return mIsActive; 149 } 150 151 void loadActiveConfig(const ActiveConfig& config, int64_t currentTimeNs); 152 153 void writeActiveConfigToProtoOutputStream( 154 int64_t currentTimeNs, const DumpReportReason reason, ProtoOutputStream* proto); 155 156 // Returns true if at least one piece of metadata is written. 157 bool writeMetadataToProto(int64_t currentWallClockTimeNs, 158 int64_t systemElapsedTimeNs, 159 metadata::StatsMetadata* statsMetadata); 160 161 void loadMetadata(const metadata::StatsMetadata& metadata, 162 int64_t currentWallClockTimeNs, 163 int64_t systemElapsedTimeNs); 164 hasRestrictedMetricsDelegate()165 inline bool hasRestrictedMetricsDelegate() const { 166 return mRestrictedMetricsDelegatePackageName.has_value(); 167 } 168 getRestrictedMetricsDelegate()169 inline string getRestrictedMetricsDelegate() const { 170 return hasRestrictedMetricsDelegate() ? mRestrictedMetricsDelegatePackageName.value() : ""; 171 } 172 getConfigKey()173 inline ConfigKey getConfigKey() const { 174 return mConfigKey; 175 } 176 177 void enforceRestrictedDataTtls(const int64_t wallClockNs); 178 179 bool validateRestrictedMetricsDelegate(const int32_t callingUid); 180 181 virtual void flushRestrictedData(); 182 183 // Slow, should not be called in a hotpath. 184 vector<int64_t> getAllMetricIds() const; 185 186 // Adds all atom ids referenced by matchers in the MetricsManager's config 187 void addAllAtomIds(LogEventFilter::AtomIdSet& allIds) const; 188 189 private: 190 // For test only. getTtlEndNs()191 inline int64_t getTtlEndNs() const { return mTtlEndNs; } 192 193 const ConfigKey mConfigKey; 194 195 sp<UidMap> mUidMap; 196 197 bool mHashStringsInReport = false; 198 bool mVersionStringsInReport = false; 199 bool mInstallerInReport = false; 200 uint8_t mPackageCertificateHashSizeBytes; 201 202 int64_t mTtlNs; 203 int64_t mTtlEndNs; 204 205 int64_t mLastReportTimeNs; 206 int64_t mLastReportWallClockNs; 207 208 optional<InvalidConfigReason> mInvalidConfigReason; 209 210 sp<StatsPullerManager> mPullerManager; 211 212 // The uid log sources from StatsdConfig. 213 std::vector<int32_t> mAllowedUid; 214 215 // The pkg log sources from StatsdConfig. 216 std::vector<std::string> mAllowedPkg; 217 218 // The combined uid sources (after translating pkg name to uid). 219 // Logs from uids that are not in the list will be ignored to avoid spamming. 220 std::set<int32_t> mAllowedLogSources; 221 222 // To guard access to mAllowedLogSources 223 mutable std::mutex mAllowedLogSourcesMutex; 224 225 std::set<int32_t> mWhitelistedAtomIds; 226 227 // We can pull any atom from these uids. 228 std::set<int32_t> mDefaultPullUids; 229 230 // Uids that specific atoms can pull from. 231 // This is a map<atom id, set<uids>> 232 std::map<int32_t, std::set<int32_t>> mPullAtomUids; 233 234 // Packages that specific atoms can be pulled from. 235 std::map<int32_t, std::set<std::string>> mPullAtomPackages; 236 237 // All uids to pull for this atom. NOTE: Does not include the default uids for memory. 238 std::map<int32_t, std::set<int32_t>> mCombinedPullAtomUids; 239 240 // Contains the annotations passed in with StatsdConfig. 241 std::list<std::pair<const int64_t, const int32_t>> mAnnotations; 242 243 bool mShouldPersistHistory; 244 245 // All event tags that are interesting to config metrics matchers. 246 std::unordered_map<int, std::vector<int>> mTagIdsToMatchersMap; 247 248 // We only store the sp of AtomMatchingTracker, MetricProducer, and ConditionTracker in 249 // MetricsManager. There are relationships between them, and the relationships are denoted by 250 // index instead of pointers. The reasons for this are: (1) the relationship between them are 251 // complicated, so storing index instead of pointers reduces the risk that A holds B's sp, and B 252 // holds A's sp. (2) When we evaluate matcher results, or condition results, we can quickly get 253 // the related results from a cache using the index. 254 255 // Hold all the atom matchers from the config. 256 std::vector<sp<AtomMatchingTracker>> mAllAtomMatchingTrackers; 257 258 // Hold all the conditions from the config. 259 std::vector<sp<ConditionTracker>> mAllConditionTrackers; 260 261 // Hold all metrics from the config. 262 std::vector<sp<MetricProducer>> mAllMetricProducers; 263 264 // Hold all alert trackers. 265 std::vector<sp<AnomalyTracker>> mAllAnomalyTrackers; 266 267 // Hold all periodic alarm trackers. 268 std::vector<sp<AlarmTracker>> mAllPeriodicAlarmTrackers; 269 270 // To make updating configs faster, we map the id of a AtomMatchingTracker, MetricProducer, and 271 // ConditionTracker to its index in the corresponding vector. 272 273 // Maps the id of an atom matching tracker to its index in mAllAtomMatchingTrackers. 274 std::unordered_map<int64_t, int> mAtomMatchingTrackerMap; 275 276 // Maps the id of a condition tracker to its index in mAllConditionTrackers. 277 std::unordered_map<int64_t, int> mConditionTrackerMap; 278 279 // Maps the id of a metric producer to its index in mAllMetricProducers. 280 std::unordered_map<int64_t, int> mMetricProducerMap; 281 282 // To make the log processing more efficient, we want to do as much filtering as possible 283 // before we go into individual trackers and conditions to match. 284 285 // 1st filter: check if the event tag id is in mTagIdsToMatchersMap. 286 // 2nd filter: if it is, we parse the event because there is at least one member is interested. 287 // then pass to all AtomMatchingTrackers (itself also filter events by ids). 288 // 3nd filter: for AtomMatchingTrackers that matched this event, we pass this event to the 289 // ConditionTrackers and MetricProducers that use this matcher. 290 // 4th filter: for ConditionTrackers that changed value due to this event, we pass 291 // new conditions to metrics that use this condition. 292 293 // The following map is initialized from the statsd_config. 294 295 // Maps from the index of the AtomMatchingTracker to index of MetricProducer. 296 std::unordered_map<int, std::vector<int>> mTrackerToMetricMap; 297 298 // Maps from AtomMatchingTracker to ConditionTracker 299 std::unordered_map<int, std::vector<int>> mTrackerToConditionMap; 300 301 // Maps from ConditionTracker to MetricProducer 302 std::unordered_map<int, std::vector<int>> mConditionToMetricMap; 303 304 // Maps from life span triggering event to MetricProducers. 305 std::unordered_map<int, std::vector<int>> mActivationAtomTrackerToMetricMap; 306 307 // Maps deactivation triggering event to MetricProducers. 308 std::unordered_map<int, std::vector<int>> mDeactivationAtomTrackerToMetricMap; 309 310 // Maps AlertIds to the index of the corresponding AnomalyTracker stored in mAllAnomalyTrackers. 311 // The map is used in LoadMetadata to more efficiently lookup AnomalyTrackers from an AlertId. 312 std::unordered_map<int64_t, int> mAlertTrackerMap; 313 314 std::vector<int> mMetricIndexesWithActivation; 315 316 void initAllowedLogSources(); 317 318 void initPullAtomSources(); 319 320 // Only called on config creation/update to initialize log sources from the config. 321 // Calls initAllowedLogSources and initPullAtomSources. Sets up mInvalidConfigReason on 322 // error. 323 void createAllLogSourcesFromConfig(const StatsdConfig& config); 324 325 // Verifies the config meets guardrails and updates statsdStats. 326 // Sets up mInvalidConfigReason on error. Should be called on config creation/update 327 void verifyGuardrailsAndUpdateStatsdStats(); 328 329 // Initializes mIsAlwaysActive and mIsActive. 330 // Should be called on config creation/update. 331 void initializeConfigActiveStatus(); 332 333 // The metrics that don't need to be uploaded or even reported. 334 std::set<int64_t> mNoReportMetricIds; 335 336 // The config is active if any metric in the config is active. 337 bool mIsActive; 338 339 // The config is always active if any metric in the config does not have an activation signal. 340 bool mIsAlwaysActive; 341 342 // Hashes of the States used in this config, keyed by the state id, used in config updates. 343 std::map<int64_t, uint64_t> mStateProtoHashes; 344 345 // Optional package name of the delegate that processes restricted metrics 346 // If set, restricted metrics are only uploaded to the delegate. 347 optional<string> mRestrictedMetricsDelegatePackageName = nullopt; 348 349 FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensions); 350 FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks); 351 FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid); 352 FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain); 353 FRIEND_TEST(GaugeMetricE2ePulledTest, TestFirstNSamplesPulledNoTrigger); 354 FRIEND_TEST(GaugeMetricE2ePulledTest, TestFirstNSamplesPulledNoTriggerWithActivation); 355 FRIEND_TEST(GaugeMetricE2ePushedTest, TestMultipleFieldsForPushedEvent); 356 FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEvents); 357 FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEvent_LateAlarm); 358 FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEventsWithActivation); 359 FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEventsNoCondition); 360 FRIEND_TEST(GaugeMetricE2ePulledTest, TestConditionChangeToTrueSamplePulledEvents); 361 362 FRIEND_TEST(AnomalyCountDetectionE2eTest, TestSlicedCountMetric_single_bucket); 363 FRIEND_TEST(AnomalyCountDetectionE2eTest, TestSlicedCountMetric_multiple_buckets); 364 FRIEND_TEST(AnomalyCountDetectionE2eTest, 365 TestCountMetric_save_refractory_to_disk_no_data_written); 366 FRIEND_TEST(AnomalyCountDetectionE2eTest, TestCountMetric_save_refractory_to_disk); 367 FRIEND_TEST(AnomalyCountDetectionE2eTest, TestCountMetric_load_refractory_from_disk); 368 FRIEND_TEST(AnomalyDurationDetectionE2eTest, TestDurationMetric_SUM_single_bucket); 369 FRIEND_TEST(AnomalyDurationDetectionE2eTest, TestDurationMetric_SUM_partial_bucket); 370 FRIEND_TEST(AnomalyDurationDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets); 371 FRIEND_TEST(AnomalyDurationDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period); 372 373 FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms); 374 FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric); 375 FRIEND_TEST(ConfigUpdateE2eAbTest, TestConfigTtl); 376 FRIEND_TEST(MetricActivationE2eTest, TestCountMetric); 377 FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation); 378 FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations); 379 FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation); 380 FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations); 381 382 FRIEND_TEST(MetricsManagerTest, TestLogSources); 383 FRIEND_TEST(MetricsManagerTest, TestLogSourcesOnConfigUpdate); 384 FRIEND_TEST(MetricsManagerTest, TestOnMetricRemoveCalled); 385 FRIEND_TEST(MetricsManagerTest_SPlus, TestRestrictedMetricsConfig); 386 FRIEND_TEST(MetricsManagerTest_SPlus, TestRestrictedMetricsConfigUpdate); 387 FRIEND_TEST(MetricsManagerUtilTest, TestSampledMetrics); 388 389 FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead); 390 FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot); 391 FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations); 392 FRIEND_TEST(StatsLogProcessorTest, 393 TestActivationOnBootMultipleActivationsDifferentActivationTypes); 394 FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart); 395 396 FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges); 397 FRIEND_TEST(CountMetricE2eTest, TestSlicedState); 398 FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap); 399 FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates); 400 FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields); 401 402 FRIEND_TEST(DurationMetricE2eTest, TestOneBucket); 403 FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets); 404 FRIEND_TEST(DurationMetricE2eTest, TestWithActivation); 405 FRIEND_TEST(DurationMetricE2eTest, TestWithCondition); 406 FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition); 407 FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition); 408 FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedState); 409 FRIEND_TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState); 410 FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStateMapped); 411 FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSuperset); 412 FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset); 413 FRIEND_TEST(DurationMetricE2eTest, TestUploadThreshold); 414 415 FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges); 416 FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents); 417 FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm); 418 FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation); 419 FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState); 420 FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions); 421 FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions); 422 FRIEND_TEST(GaugeMetricE2ePushedTest, TestDimensionalSampling); 423 }; 424 425 } // namespace statsd 426 } // namespace os 427 } // namespace android 428