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 94 // Does not set the used uids. getUidMapOptions()95 inline UidMapOptions getUidMapOptions() const { 96 return {.includeVersionStrings = mVersionStringsInReport, 97 .includeInstaller = mInstallerInReport, 98 .truncatedCertificateHashSize = mPackageCertificateHashSizeBytes, 99 .omitSystemUids = mOmitSystemUidsInUidMap, 100 .omitUnusedUids = mOmitUnusedUidsInUidMap, 101 .allowlistedPackages = mAllowlistedUidMapPackages}; 102 } 103 isInTtl(const int64_t timestampNs)104 inline bool isInTtl(const int64_t timestampNs) const { 105 return mTtlNs <= 0 || timestampNs < mTtlEndNs; 106 }; 107 hashStringInReport()108 inline bool hashStringInReport() const { 109 return mHashStringsInReport; 110 }; 111 refreshTtl(const int64_t currentTimestampNs)112 void refreshTtl(const int64_t currentTimestampNs) { 113 if (mTtlNs > 0) { 114 mTtlEndNs = currentTimestampNs + mTtlNs; 115 } 116 }; 117 118 // Returns the elapsed realtime when this metric manager last reported metrics. If this config 119 // has not yet dumped any reports, this is the time the metricsmanager was initialized. getLastReportTimeNs()120 inline int64_t getLastReportTimeNs() const { 121 return mLastReportTimeNs; 122 }; 123 getLastReportWallClockNs()124 inline int64_t getLastReportWallClockNs() const { 125 return mLastReportWallClockNs; 126 }; 127 getNumMetrics()128 inline size_t getNumMetrics() const { 129 return mAllMetricProducers.size(); 130 } 131 132 virtual void dropData(const int64_t dropTimeNs); 133 134 virtual void onDumpReport(const int64_t dumpTimeNs, int64_t wallClockNs, 135 const bool include_current_partial_bucket, const bool erase_data, 136 const DumpLatency dumpLatency, std::set<string>* str_set, 137 std::set<int32_t>& usedUids, 138 android::util::ProtoOutputStream* protoOutput); 139 140 // Computes the total byte size of all metrics managed by a single config source. 141 // Does not change the state. 142 virtual size_t byteSize(); 143 144 // Returns whether or not this config is active. 145 // The config is active if any metric in the config is active. isActive()146 inline bool isActive() const { 147 return mIsActive; 148 } 149 150 void loadActiveConfig(const ActiveConfig& config, int64_t currentTimeNs); 151 152 void writeActiveConfigToProtoOutputStream(int64_t currentTimeNs, const DumpReportReason reason, 153 ProtoOutputStream* proto); 154 155 // Returns true if at least one piece of metadata is written. 156 bool writeMetadataToProto(int64_t currentWallClockTimeNs, int64_t systemElapsedTimeNs, 157 metadata::StatsMetadata* statsMetadata); 158 159 void loadMetadata(const metadata::StatsMetadata& metadata, int64_t currentWallClockTimeNs, 160 int64_t systemElapsedTimeNs); 161 hasRestrictedMetricsDelegate()162 inline bool hasRestrictedMetricsDelegate() const { 163 return mRestrictedMetricsDelegatePackageName.has_value(); 164 } 165 getRestrictedMetricsDelegate()166 inline string getRestrictedMetricsDelegate() const { 167 return hasRestrictedMetricsDelegate() ? mRestrictedMetricsDelegatePackageName.value() : ""; 168 } 169 getConfigKey()170 inline ConfigKey getConfigKey() const { 171 return mConfigKey; 172 } 173 174 void enforceRestrictedDataTtls(const int64_t wallClockNs); 175 176 bool validateRestrictedMetricsDelegate(int32_t callingUid); 177 178 virtual void flushRestrictedData(); 179 180 // Slow, should not be called in a hotpath. 181 vector<int64_t> getAllMetricIds() const; 182 183 // Adds all atom ids referenced by matchers in the MetricsManager's config 184 void addAllAtomIds(LogEventFilter::AtomIdSet& allIds) const; 185 186 // Gets the memory limit for the MetricsManager's config getMaxMetricsBytes()187 inline size_t getMaxMetricsBytes() const { 188 return mMaxMetricsBytes; 189 } 190 getTriggerGetDataBytes()191 inline size_t getTriggerGetDataBytes() const { 192 return mTriggerGetDataBytes; 193 } 194 195 private: 196 // For test only. getTtlEndNs()197 inline int64_t getTtlEndNs() const { 198 return mTtlEndNs; 199 } 200 201 const ConfigKey mConfigKey; 202 203 sp<UidMap> mUidMap; 204 205 bool mHashStringsInReport = false; 206 bool mVersionStringsInReport = false; 207 bool mInstallerInReport = false; 208 uint8_t mPackageCertificateHashSizeBytes; 209 210 int64_t mTtlNs; 211 int64_t mTtlEndNs; 212 213 int64_t mLastReportTimeNs; 214 int64_t mLastReportWallClockNs; 215 216 optional<InvalidConfigReason> mInvalidConfigReason; 217 218 sp<StatsPullerManager> mPullerManager; 219 220 // The uid log sources from StatsdConfig. 221 std::vector<int32_t> mAllowedUid; 222 223 // The pkg log sources from StatsdConfig. 224 std::vector<std::string> mAllowedPkg; 225 226 // The combined uid sources (after translating pkg name to uid). 227 // Logs from uids that are not in the list will be ignored to avoid spamming. 228 std::set<int32_t> mAllowedLogSources; 229 230 // To guard access to mAllowedLogSources 231 mutable std::mutex mAllowedLogSourcesMutex; 232 233 std::set<int32_t> mWhitelistedAtomIds; 234 235 // We can pull any atom from these uids. 236 std::set<int32_t> mDefaultPullUids; 237 238 // Uids that specific atoms can pull from. 239 // This is a map<atom id, set<uids>> 240 std::map<int32_t, std::set<int32_t>> mPullAtomUids; 241 242 // Packages that specific atoms can be pulled from. 243 std::map<int32_t, std::set<std::string>> mPullAtomPackages; 244 245 // All uids to pull for this atom. NOTE: Does not include the default uids for memory. 246 std::map<int32_t, std::set<int32_t>> mCombinedPullAtomUids; 247 248 // Contains the annotations passed in with StatsdConfig. 249 std::list<std::pair<const int64_t, const int32_t>> mAnnotations; 250 251 bool mShouldPersistHistory; 252 bool mUseV2SoftMemoryCalculation; 253 254 bool mOmitSystemUidsInUidMap; 255 bool mOmitUnusedUidsInUidMap; 256 set<string> mAllowlistedUidMapPackages; 257 258 // All event tags that are interesting to config metrics matchers. 259 std::unordered_map<int, std::vector<int>> mTagIdsToMatchersMap; 260 261 // We only store the sp of AtomMatchingTracker, MetricProducer, and ConditionTracker in 262 // MetricsManager. There are relationships between them, and the relationships are denoted by 263 // index instead of pointers. The reasons for this are: (1) the relationship between them are 264 // complicated, so storing index instead of pointers reduces the risk that A holds B's sp, and B 265 // holds A's sp. (2) When we evaluate matcher results, or condition results, we can quickly get 266 // the related results from a cache using the index. 267 268 // Hold all the atom matchers from the config. 269 std::vector<sp<AtomMatchingTracker>> mAllAtomMatchingTrackers; 270 271 // Hold all the conditions from the config. 272 std::vector<sp<ConditionTracker>> mAllConditionTrackers; 273 274 // Hold all metrics from the config. 275 std::vector<sp<MetricProducer>> mAllMetricProducers; 276 277 // Hold all alert trackers. 278 std::vector<sp<AnomalyTracker>> mAllAnomalyTrackers; 279 280 // Hold all periodic alarm trackers. 281 std::vector<sp<AlarmTracker>> mAllPeriodicAlarmTrackers; 282 283 // To make updating configs faster, we map the id of a AtomMatchingTracker, MetricProducer, and 284 // ConditionTracker to its index in the corresponding vector. 285 286 // Maps the id of an atom matching tracker to its index in mAllAtomMatchingTrackers. 287 std::unordered_map<int64_t, int> mAtomMatchingTrackerMap; 288 289 // Maps the id of a condition tracker to its index in mAllConditionTrackers. 290 std::unordered_map<int64_t, int> mConditionTrackerMap; 291 292 // Maps the id of a metric producer to its index in mAllMetricProducers. 293 std::unordered_map<int64_t, int> mMetricProducerMap; 294 295 // To make the log processing more efficient, we want to do as much filtering as possible 296 // before we go into individual trackers and conditions to match. 297 298 // 1st filter: check if the event tag id is in mTagIdsToMatchersMap. 299 // 2nd filter: if it is, we parse the event because there is at least one member is interested. 300 // then pass to all AtomMatchingTrackers (itself also filter events by ids). 301 // 3nd filter: for AtomMatchingTrackers that matched this event, we pass this event to the 302 // ConditionTrackers and MetricProducers that use this matcher. 303 // 4th filter: for ConditionTrackers that changed value due to this event, we pass 304 // new conditions to metrics that use this condition. 305 306 // The following map is initialized from the statsd_config. 307 308 // Maps from the index of the AtomMatchingTracker to index of MetricProducer. 309 std::unordered_map<int, std::vector<int>> mTrackerToMetricMap; 310 311 // Maps from AtomMatchingTracker to ConditionTracker 312 std::unordered_map<int, std::vector<int>> mTrackerToConditionMap; 313 314 // Maps from ConditionTracker to MetricProducer 315 std::unordered_map<int, std::vector<int>> mConditionToMetricMap; 316 317 // Maps from life span triggering event to MetricProducers. 318 std::unordered_map<int, std::vector<int>> mActivationAtomTrackerToMetricMap; 319 320 // Maps deactivation triggering event to MetricProducers. 321 std::unordered_map<int, std::vector<int>> mDeactivationAtomTrackerToMetricMap; 322 323 // Maps AlertIds to the index of the corresponding AnomalyTracker stored in mAllAnomalyTrackers. 324 // The map is used in LoadMetadata to more efficiently lookup AnomalyTrackers from an AlertId. 325 std::unordered_map<int64_t, int> mAlertTrackerMap; 326 327 std::vector<int> mMetricIndexesWithActivation; 328 checkLogCredentials(const LogEvent & event)329 inline bool checkLogCredentials(const LogEvent& event) const { 330 return checkLogCredentials(event.GetUid(), event.GetTagId()); 331 } 332 333 bool checkLogCredentials(int32_t uid, int32_t atomId) const; 334 335 void initAllowedLogSources(); 336 337 void initPullAtomSources(); 338 339 // Only called on config creation/update to initialize log sources from the config. 340 // Calls initAllowedLogSources and initPullAtomSources. Sets up mInvalidConfigReason on 341 // error. 342 void createAllLogSourcesFromConfig(const StatsdConfig& config); 343 344 // Verifies the config meets guardrails and updates statsdStats. 345 // Sets up mInvalidConfigReason on error. Should be called on config creation/update 346 void verifyGuardrailsAndUpdateStatsdStats(); 347 348 // Initializes mIsAlwaysActive and mIsActive. 349 // Should be called on config creation/update. 350 void initializeConfigActiveStatus(); 351 352 // The metrics that don't need to be uploaded or even reported. 353 std::set<int64_t> mNoReportMetricIds; 354 355 // The config is active if any metric in the config is active. 356 bool mIsActive; 357 358 // The config is always active if any metric in the config does not have an activation signal. 359 bool mIsAlwaysActive; 360 361 // Hashes of the States used in this config, keyed by the state id, used in config updates. 362 std::map<int64_t, uint64_t> mStateProtoHashes; 363 364 // Optional package name of the delegate that processes restricted metrics 365 // If set, restricted metrics are only uploaded to the delegate. 366 optional<string> mRestrictedMetricsDelegatePackageName = nullopt; 367 368 // Only called on config creation/update. Sets the memory limit in bytes for storing metrics. 369 void setMaxMetricsBytesFromConfig(const StatsdConfig& config); 370 371 // Only called on config creation/update. Sets the soft memory limit in bytes for storing 372 // metrics. 373 void setTriggerGetDataBytesFromConfig(const StatsdConfig& config); 374 375 // Parse SocketLossInfo and propagate info to the metrics 376 void onLogEventLost(const SocketLossInfo& socketLossInfo); 377 378 /** 379 * @brief Update metrics depending on #lostAtomId that it was lost due to #reason 380 * @return number of notified metrics 381 */ 382 int notifyMetricsAboutLostAtom(int32_t lostAtomId, DataCorruptedReason reason); 383 384 /** 385 * Updates MetricProducers with DataCorruptionReason due to queue overflow atom loss 386 * Notifies metrics only when new queue overflow happens since previous request 387 * Performs QueueOverflowAtomsStatsMap tracking via managing stats local copy 388 * The assumption is that QueueOverflowAtomsStatsMap collected over time, and that none 389 * of atom id counters have disappeared (which is StatsdStats logic until it explicitly reset, 390 * which should not be happen during statsd service lifetime) 391 */ 392 void processQueueOverflowStats(); 393 394 // The memory limit in bytes for storing metrics 395 size_t mMaxMetricsBytes; 396 397 // The memory limit in bytes for triggering get data. 398 size_t mTriggerGetDataBytes; 399 400 // Dropped atoms stats due to queue overflow observed up to latest dumpReport request 401 // this map is not cleared during onDumpReport to preserve tracking information and avoid 402 // repeated metric notification about past queue overflow lost event 403 // This map represent local copy of StatsdStats::mPushedAtomDropsStats with relevant atoms ids 404 StatsdStats::QueueOverflowAtomsStatsMap mQueueOverflowAtomsStats; 405 406 friend class SocketLossInfoTest; 407 FRIEND_TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks); 408 FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid); 409 FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain); 410 411 FRIEND_TEST(GaugeMetricE2ePushedTest, TestDimensionalSampling); 412 FRIEND_TEST(GaugeMetricE2ePulledTest, TestFirstNSamplesPulledNoTrigger); 413 FRIEND_TEST(GaugeMetricE2ePulledTest, TestFirstNSamplesPulledNoTriggerWithActivation); 414 FRIEND_TEST(GaugeMetricE2ePushedTest, TestMultipleFieldsForPushedEvent); 415 FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEvents); 416 FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEvent_LateAlarm); 417 FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEventsWithActivation); 418 FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEventsNoCondition); 419 FRIEND_TEST(GaugeMetricE2ePulledTest, TestConditionChangeToTrueSamplePulledEvents); 420 421 FRIEND_TEST(AnomalyCountDetectionE2eTest, TestSlicedCountMetric_single_bucket); 422 FRIEND_TEST(AnomalyCountDetectionE2eTest, TestSlicedCountMetric_multiple_buckets); 423 FRIEND_TEST(AnomalyCountDetectionE2eTest, 424 TestCountMetric_save_refractory_to_disk_no_data_written); 425 FRIEND_TEST(AnomalyCountDetectionE2eTest, TestCountMetric_save_refractory_to_disk); 426 FRIEND_TEST(AnomalyCountDetectionE2eTest, TestCountMetric_load_refractory_from_disk); 427 FRIEND_TEST(AnomalyDurationDetectionE2eTest, TestDurationMetric_SUM_single_bucket); 428 FRIEND_TEST(AnomalyDurationDetectionE2eTest, TestDurationMetric_SUM_partial_bucket); 429 FRIEND_TEST(AnomalyDurationDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets); 430 FRIEND_TEST(AnomalyDurationDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period); 431 432 FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms); 433 FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric); 434 FRIEND_TEST(ConfigUpdateE2eAbTest, TestConfigTtl); 435 FRIEND_TEST(MetricActivationE2eTest, TestCountMetric); 436 FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithOneDeactivation); 437 FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoDeactivations); 438 FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation); 439 FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations); 440 441 FRIEND_TEST(MetricsManagerTest, TestLogSources); 442 FRIEND_TEST(MetricsManagerTest, TestCheckLogCredentialsWhitelistedAtom); 443 FRIEND_TEST(MetricsManagerTest, TestLogSourcesOnConfigUpdate); 444 FRIEND_TEST(MetricsManagerTest_SPlus, TestRestrictedMetricsConfig); 445 FRIEND_TEST(MetricsManagerTest_SPlus, TestRestrictedMetricsConfigUpdate); 446 FRIEND_TEST(MetricsManagerUtilTest, TestSampledMetrics); 447 FRIEND_TEST(MetricsManagerUtilTest, TestUidFields); 448 449 FRIEND_TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead); 450 FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBoot); 451 FRIEND_TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations); 452 FRIEND_TEST(StatsLogProcessorTest, 453 TestActivationOnBootMultipleActivationsDifferentActivationTypes); 454 FRIEND_TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart); 455 456 FRIEND_TEST(CountMetricE2eTest, TestInitialConditionChanges); 457 FRIEND_TEST(CountMetricE2eTest, TestSlicedState); 458 FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap); 459 FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates); 460 FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields); 461 462 FRIEND_TEST(DurationMetricE2eTest, TestOneBucket); 463 FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets); 464 FRIEND_TEST(DurationMetricE2eTest, TestWithActivation); 465 FRIEND_TEST(DurationMetricE2eTest, TestWithCondition); 466 FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedCondition); 467 FRIEND_TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition); 468 FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedState); 469 FRIEND_TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState); 470 FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStateMapped); 471 FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset); 472 FRIEND_TEST(DurationMetricE2eTest, TestUploadThreshold); 473 474 FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges); 475 FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents); 476 FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm); 477 FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents_WithActivation); 478 FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState); 479 FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions); 480 FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions); 481 FRIEND_TEST(ValueMetricE2eTest, TestInitWithMultipleAggTypes); 482 FRIEND_TEST(ValueMetricE2eTest, TestInitWithDefaultAggType); 483 484 FRIEND_TEST(DataCorruptionQueueOverflowTest, TestNotifyOnlyInterestedMetrics); 485 FRIEND_TEST(DataCorruptionQueueOverflowTest, TestNotifyInterestedMetricsWithNewLoss); 486 FRIEND_TEST(DataCorruptionQueueOverflowTest, TestDoNotNotifyInterestedMetricsIfNoUpdate); 487 FRIEND_TEST(DataCorruptionQueueOverflowTest, TestDoNotNotifyNewInterestedMetricsIfNoUpdate); 488 }; 489 490 } // namespace statsd 491 } // namespace os 492 } // namespace android 493