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 "config/ConfigMetadataProvider.h" 27 #include "external/StatsPullerManager.h" 28 #include "guardrail/StatsdStats.h" 29 #include "logd/LogEvent.h" 30 #include "matchers/AtomMatchingTracker.h" 31 #include "metrics/MetricProducer.h" 32 #include "packages/UidMap.h" 33 #include "src/statsd_config.pb.h" 34 #include "src/statsd_metadata.pb.h" 35 36 namespace android { 37 namespace os { 38 namespace statsd { 39 40 // A MetricsManager is responsible for managing metrics from one single config source. 41 class MetricsManager : public virtual RefBase, 42 public virtual PullUidProvider, 43 public virtual ConfigMetadataProvider { 44 public: 45 MetricsManager(const ConfigKey& configKey, const StatsdConfig& config, int64_t timeBaseNs, 46 const int64_t currentTimeNs, const sp<UidMap>& uidMap, 47 const sp<StatsPullerManager>& pullerManager, 48 const sp<AlarmMonitor>& anomalyAlarmMonitor, 49 const sp<AlarmMonitor>& periodicAlarmMonitor); 50 51 virtual ~MetricsManager(); 52 53 bool updateConfig(const StatsdConfig& config, int64_t timeBaseNs, const int64_t currentTimeNs, 54 const sp<AlarmMonitor>& anomalyAlarmMonitor, 55 const sp<AlarmMonitor>& periodicAlarmMonitor); 56 57 // Return whether the configuration is valid. 58 bool isConfigValid() const; 59 60 virtual void onLogEvent(const LogEvent& event); 61 62 void onAnomalyAlarmFired( 63 int64_t timestampNs, 64 unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet); 65 66 void onPeriodicAlarmFired( 67 int64_t timestampNs, 68 unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet); 69 70 void notifyAppUpgrade(int64_t eventTimeNs, const string& apk, int uid, int64_t version); 71 72 void notifyAppRemoved(int64_t eventTimeNs, const string& apk, int uid); 73 74 void onUidMapReceived(int64_t eventTimeNs); 75 76 void onStatsdInitCompleted(int64_t elapsedTimeNs); 77 78 void init(); 79 80 vector<int32_t> getPullAtomUids(int32_t atomId) override; 81 82 bool useV2SoftMemoryCalculation() 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(int 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, 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(int64_t currentTimeNs, const DumpReportReason reason, 154 ProtoOutputStream* proto); 155 156 // Returns true if at least one piece of metadata is written. 157 bool writeMetadataToProto(int64_t currentWallClockTimeNs, int64_t systemElapsedTimeNs, 158 metadata::StatsMetadata* statsMetadata); 159 160 void loadMetadata(const metadata::StatsMetadata& metadata, int64_t currentWallClockTimeNs, 161 int64_t systemElapsedTimeNs); 162 hasRestrictedMetricsDelegate()163 inline bool hasRestrictedMetricsDelegate() const { 164 return mRestrictedMetricsDelegatePackageName.has_value(); 165 } 166 getRestrictedMetricsDelegate()167 inline string getRestrictedMetricsDelegate() const { 168 return hasRestrictedMetricsDelegate() ? mRestrictedMetricsDelegatePackageName.value() : ""; 169 } 170 getConfigKey()171 inline ConfigKey getConfigKey() const { 172 return mConfigKey; 173 } 174 175 void enforceRestrictedDataTtls(const int64_t wallClockNs); 176 177 bool validateRestrictedMetricsDelegate(int32_t callingUid); 178 179 virtual void flushRestrictedData(); 180 181 // Slow, should not be called in a hotpath. 182 vector<int64_t> getAllMetricIds() const; 183 184 // Adds all atom ids referenced by matchers in the MetricsManager's config 185 void addAllAtomIds(LogEventFilter::AtomIdSet& allIds) const; 186 187 // Gets the memory limit for the MetricsManager's config getMaxMetricsBytes()188 inline size_t getMaxMetricsBytes() const { 189 return mMaxMetricsBytes; 190 } 191 getTriggerGetDataBytes()192 inline size_t getTriggerGetDataBytes() const { 193 return mTriggerGetDataBytes; 194 } 195 omitSystemUidsInUidMap()196 inline bool omitSystemUidsInUidMap() const { 197 return mOmitSystemUidsInUidMap; 198 } 199 200 private: 201 // For test only. getTtlEndNs()202 inline int64_t getTtlEndNs() const { 203 return mTtlEndNs; 204 } 205 206 const ConfigKey mConfigKey; 207 208 sp<UidMap> mUidMap; 209 210 bool mHashStringsInReport = false; 211 bool mVersionStringsInReport = false; 212 bool mInstallerInReport = false; 213 uint8_t mPackageCertificateHashSizeBytes; 214 215 int64_t mTtlNs; 216 int64_t mTtlEndNs; 217 218 int64_t mLastReportTimeNs; 219 int64_t mLastReportWallClockNs; 220 221 optional<InvalidConfigReason> mInvalidConfigReason; 222 223 sp<StatsPullerManager> mPullerManager; 224 225 // The uid log sources from StatsdConfig. 226 std::vector<int32_t> mAllowedUid; 227 228 // The pkg log sources from StatsdConfig. 229 std::vector<std::string> mAllowedPkg; 230 231 // The combined uid sources (after translating pkg name to uid). 232 // Logs from uids that are not in the list will be ignored to avoid spamming. 233 std::set<int32_t> mAllowedLogSources; 234 235 // To guard access to mAllowedLogSources 236 mutable std::mutex mAllowedLogSourcesMutex; 237 238 std::set<int32_t> mWhitelistedAtomIds; 239 240 // We can pull any atom from these uids. 241 std::set<int32_t> mDefaultPullUids; 242 243 // Uids that specific atoms can pull from. 244 // This is a map<atom id, set<uids>> 245 std::map<int32_t, std::set<int32_t>> mPullAtomUids; 246 247 // Packages that specific atoms can be pulled from. 248 std::map<int32_t, std::set<std::string>> mPullAtomPackages; 249 250 // All uids to pull for this atom. NOTE: Does not include the default uids for memory. 251 std::map<int32_t, std::set<int32_t>> mCombinedPullAtomUids; 252 253 // Contains the annotations passed in with StatsdConfig. 254 std::list<std::pair<const int64_t, const int32_t>> mAnnotations; 255 256 bool mShouldPersistHistory; 257 bool mUseV2SoftMemoryCalculation; 258 259 bool mOmitSystemUidsInUidMap; 260 261 // All event tags that are interesting to config metrics matchers. 262 std::unordered_map<int, std::vector<int>> mTagIdsToMatchersMap; 263 264 // We only store the sp of AtomMatchingTracker, MetricProducer, and ConditionTracker in 265 // MetricsManager. There are relationships between them, and the relationships are denoted by 266 // index instead of pointers. The reasons for this are: (1) the relationship between them are 267 // complicated, so storing index instead of pointers reduces the risk that A holds B's sp, and B 268 // holds A's sp. (2) When we evaluate matcher results, or condition results, we can quickly get 269 // the related results from a cache using the index. 270 271 // Hold all the atom matchers from the config. 272 std::vector<sp<AtomMatchingTracker>> mAllAtomMatchingTrackers; 273 274 // Hold all the conditions from the config. 275 std::vector<sp<ConditionTracker>> mAllConditionTrackers; 276 277 // Hold all metrics from the config. 278 std::vector<sp<MetricProducer>> mAllMetricProducers; 279 280 // Hold all alert trackers. 281 std::vector<sp<AnomalyTracker>> mAllAnomalyTrackers; 282 283 // Hold all periodic alarm trackers. 284 std::vector<sp<AlarmTracker>> mAllPeriodicAlarmTrackers; 285 286 // To make updating configs faster, we map the id of a AtomMatchingTracker, MetricProducer, and 287 // ConditionTracker to its index in the corresponding vector. 288 289 // Maps the id of an atom matching tracker to its index in mAllAtomMatchingTrackers. 290 std::unordered_map<int64_t, int> mAtomMatchingTrackerMap; 291 292 // Maps the id of a condition tracker to its index in mAllConditionTrackers. 293 std::unordered_map<int64_t, int> mConditionTrackerMap; 294 295 // Maps the id of a metric producer to its index in mAllMetricProducers. 296 std::unordered_map<int64_t, int> mMetricProducerMap; 297 298 // To make the log processing more efficient, we want to do as much filtering as possible 299 // before we go into individual trackers and conditions to match. 300 301 // 1st filter: check if the event tag id is in mTagIdsToMatchersMap. 302 // 2nd filter: if it is, we parse the event because there is at least one member is interested. 303 // then pass to all AtomMatchingTrackers (itself also filter events by ids). 304 // 3nd filter: for AtomMatchingTrackers that matched this event, we pass this event to the 305 // ConditionTrackers and MetricProducers that use this matcher. 306 // 4th filter: for ConditionTrackers that changed value due to this event, we pass 307 // new conditions to metrics that use this condition. 308 309 // The following map is initialized from the statsd_config. 310 311 // Maps from the index of the AtomMatchingTracker to index of MetricProducer. 312 std::unordered_map<int, std::vector<int>> mTrackerToMetricMap; 313 314 // Maps from AtomMatchingTracker to ConditionTracker 315 std::unordered_map<int, std::vector<int>> mTrackerToConditionMap; 316 317 // Maps from ConditionTracker to MetricProducer 318 std::unordered_map<int, std::vector<int>> mConditionToMetricMap; 319 320 // Maps from life span triggering event to MetricProducers. 321 std::unordered_map<int, std::vector<int>> mActivationAtomTrackerToMetricMap; 322 323 // Maps deactivation triggering event to MetricProducers. 324 std::unordered_map<int, std::vector<int>> mDeactivationAtomTrackerToMetricMap; 325 326 // Maps AlertIds to the index of the corresponding AnomalyTracker stored in mAllAnomalyTrackers. 327 // The map is used in LoadMetadata to more efficiently lookup AnomalyTrackers from an AlertId. 328 std::unordered_map<int64_t, int> mAlertTrackerMap; 329 330 std::vector<int> mMetricIndexesWithActivation; 331 checkLogCredentials(const LogEvent & event)332 inline bool checkLogCredentials(const LogEvent& event) const { 333 return checkLogCredentials(event.GetUid(), event.GetTagId()); 334 } 335 336 bool checkLogCredentials(int32_t uid, int32_t atomId) const; 337 338 void initAllowedLogSources(); 339 340 void initPullAtomSources(); 341 342 // Only called on config creation/update to initialize log sources from the config. 343 // Calls initAllowedLogSources and initPullAtomSources. Sets up mInvalidConfigReason on 344 // error. 345 void createAllLogSourcesFromConfig(const StatsdConfig& config); 346 347 // Verifies the config meets guardrails and updates statsdStats. 348 // Sets up mInvalidConfigReason on error. Should be called on config creation/update 349 void verifyGuardrailsAndUpdateStatsdStats(); 350 351 // Initializes mIsAlwaysActive and mIsActive. 352 // Should be called on config creation/update. 353 void initializeConfigActiveStatus(); 354 355 // The metrics that don't need to be uploaded or even reported. 356 std::set<int64_t> mNoReportMetricIds; 357 358 // The config is active if any metric in the config is active. 359 bool mIsActive; 360 361 // The config is always active if any metric in the config does not have an activation signal. 362 bool mIsAlwaysActive; 363 364 // Hashes of the States used in this config, keyed by the state id, used in config updates. 365 std::map<int64_t, uint64_t> mStateProtoHashes; 366 367 // Optional package name of the delegate that processes restricted metrics 368 // If set, restricted metrics are only uploaded to the delegate. 369 optional<string> mRestrictedMetricsDelegatePackageName = nullopt; 370 371 // Only called on config creation/update. Sets the memory limit in bytes for storing metrics. 372 void setMaxMetricsBytesFromConfig(const StatsdConfig& config); 373 374 // Only called on config creation/update. Sets the soft memory limit in bytes for storing 375 // metrics. 376 void setTriggerGetDataBytesFromConfig(const StatsdConfig& config); 377 378 // Parse SocketLossInfo and propagate info to the metrics 379 void onLogEventLost(const SocketLossInfo& socketLossInfo); 380 381 /** 382 * @brief Update metrics depending on #lostAtomId that it was lost due to #reason 383 * @return number of notified metrics 384 */ 385 int notifyMetricsAboutLostAtom(int32_t lostAtomId, DataCorruptedReason reason); 386 387 /** 388 * @brief Updates MetricProducers with DataCorruptionReason due to queue overflow atom loss 389 * Notifies metrics only when new queue overflow happens since previous dumpReport 390 * Perform QueueOverflowAtomsStats tracking via managing stats local copy 391 * The assumption is that QueueOverflowAtomsStats collected over time, and that none of 392 * atom id counters have disappeared (which is StatsdStats logic until it explicitly 393 * reset, which should not be happen during statsd service lifetime) 394 * @param overflowStats 395 */ 396 void processQueueOverflowStats(const StatsdStats::QueueOverflowAtomsStats& overflowStats); 397 398 // The memory limit in bytes for storing metrics 399 size_t mMaxMetricsBytes; 400 401 // The memory limit in bytes for triggering get data. 402 size_t mTriggerGetDataBytes; 403 404 // Dropped atoms stats due to queue overflow observed up to latest dumpReport request 405 // this map is not cleared during onDumpReport to preserve tracking information and avoid 406 // repeated metric notification about past queue overflow lost event 407 // This map represent local copy of StatsdStats::mPushedAtomDropsStats with relevant atoms ids 408 typedef std::unordered_map<int32_t, int32_t> QueueOverflowAtomsStatsMap; 409 QueueOverflowAtomsStatsMap mQueueOverflowAtomsStats; 410 411 FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks); 412 FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid); 413 FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain); 414 415 FRIEND_TEST(GaugeMetricE2ePushedTest, TestDimensionalSampling); 416 FRIEND_TEST(GaugeMetricE2ePulledTest, TestFirstNSamplesPulledNoTrigger); 417 FRIEND_TEST(GaugeMetricE2ePulledTest, TestFirstNSamplesPulledNoTriggerWithActivation); 418 FRIEND_TEST(GaugeMetricE2ePushedTest, TestMultipleFieldsForPushedEvent); 419 FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEvents); 420 FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEvent_LateAlarm); 421 FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEventsWithActivation); 422 FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEventsNoCondition); 423 FRIEND_TEST(GaugeMetricE2ePulledTest, TestConditionChangeToTrueSamplePulledEvents); 424 425 FRIEND_TEST(AnomalyCountDetectionE2eTest, TestSlicedCountMetric_single_bucket); 426 FRIEND_TEST(AnomalyCountDetectionE2eTest, TestSlicedCountMetric_multiple_buckets); 427 FRIEND_TEST(AnomalyCountDetectionE2eTest, 428 TestCountMetric_save_refractory_to_disk_no_data_written); 429 FRIEND_TEST(AnomalyCountDetectionE2eTest, TestCountMetric_save_refractory_to_disk); 430 FRIEND_TEST(AnomalyCountDetectionE2eTest, TestCountMetric_load_refractory_from_disk); 431 FRIEND_TEST(AnomalyDurationDetectionE2eTest, TestDurationMetric_SUM_single_bucket); 432 FRIEND_TEST(AnomalyDurationDetectionE2eTest, TestDurationMetric_SUM_partial_bucket); 433 FRIEND_TEST(AnomalyDurationDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets); 434 FRIEND_TEST(AnomalyDurationDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period); 435 436 FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms); 437 FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric); 438 FRIEND_TEST(ConfigUpdateE2eAbTest, TestConfigTtl); 439 FRIEND_TEST(MetricActivationE2eTest, TestCountMetric); 440 FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation); 441 FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations); 442 FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation); 443 FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations); 444 445 FRIEND_TEST(MetricsManagerTest, TestLogSources); 446 FRIEND_TEST(MetricsManagerTest, TestCheckLogCredentialsWhitelistedAtom); 447 FRIEND_TEST(MetricsManagerTest, TestLogSourcesOnConfigUpdate); 448 FRIEND_TEST(MetricsManagerTest_SPlus, TestRestrictedMetricsConfig); 449 FRIEND_TEST(MetricsManagerTest_SPlus, TestRestrictedMetricsConfigUpdate); 450 FRIEND_TEST(MetricsManagerUtilTest, TestSampledMetrics); 451 452 FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead); 453 FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot); 454 FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations); 455 FRIEND_TEST(StatsLogProcessorTest, 456 TestActivationOnBootMultipleActivationsDifferentActivationTypes); 457 FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart); 458 459 FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges); 460 FRIEND_TEST(CountMetricE2eTest, TestSlicedState); 461 FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap); 462 FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates); 463 FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields); 464 465 FRIEND_TEST(DurationMetricE2eTest, TestOneBucket); 466 FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets); 467 FRIEND_TEST(DurationMetricE2eTest, TestWithActivation); 468 FRIEND_TEST(DurationMetricE2eTest, TestWithCondition); 469 FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition); 470 FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition); 471 FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedState); 472 FRIEND_TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState); 473 FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStateMapped); 474 FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset); 475 FRIEND_TEST(DurationMetricE2eTest, TestUploadThreshold); 476 477 FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges); 478 FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents); 479 FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm); 480 FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation); 481 FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState); 482 FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions); 483 FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions); 484 FRIEND_TEST(ValueMetricE2eTest, TestInitWithMultipleAggTypes); 485 FRIEND_TEST(ValueMetricE2eTest, TestInitWithDefaultAggType); 486 487 FRIEND_TEST(SocketLossInfoTest, PropagationTest); 488 489 FRIEND_TEST(DataCorruptionQueueOverflowTest, TestNotifyOnlyInterestedMetrics); 490 FRIEND_TEST(DataCorruptionQueueOverflowTest, TestNotifyInterestedMetricsWithNewLoss); 491 FRIEND_TEST(DataCorruptionQueueOverflowTest, TestDoNotNotifyInterestedMetricsIfNoUpdate); 492 }; 493 494 } // namespace statsd 495 } // namespace os 496 } // namespace android 497