Loading cmds/statsd/src/StatsLogProcessor.cpp +37 −2 Original line number Diff line number Diff line Loading @@ -120,10 +120,9 @@ static void flushProtoToBuffer(ProtoOutputStream& proto, vector<uint8_t>* outDat } } void StatsLogProcessor::onAnomalyAlarmFired( void StatsLogProcessor::processFiredAnomalyAlarmsLocked( const int64_t& timestampNs, unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) { std::lock_guard<std::mutex> lock(mMetricsMutex); for (const auto& itr : mMetricsManagers) { itr.second->onAnomalyAlarmFired(timestampNs, alarmSet); } Loading Loading @@ -429,6 +428,20 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs) { return; } bool fireAlarm = false; { std::lock_guard<std::mutex> anomalyLock(mAnomalyAlarmMutex); if (mNextAnomalyAlarmTime != 0 && MillisToNano(mNextAnomalyAlarmTime) <= elapsedRealtimeNs) { mNextAnomalyAlarmTime = 0; VLOG("informing anomaly alarm at time %lld", (long long)elapsedRealtimeNs); fireAlarm = true; } } if (fireAlarm) { informAnomalyAlarmFiredLocked(NanoToMillis(elapsedRealtimeNs)); } int64_t curTimeSec = getElapsedRealtimeSec(); if (curTimeSec - mLastPullerCacheClearTimeSec > StatsdStats::kPullerCacheClearIntervalSec) { mPullerManager->ClearPullerCacheIfNecessary(curTimeSec * NS_PER_SEC); Loading Loading @@ -1090,6 +1103,28 @@ void StatsLogProcessor::noteOnDiskData(const ConfigKey& key) { mOnDiskDataConfigs.insert(key); } void StatsLogProcessor::setAnomalyAlarm(const int64_t elapsedTimeMillis) { std::lock_guard<std::mutex> lock(mAnomalyAlarmMutex); mNextAnomalyAlarmTime = elapsedTimeMillis; } void StatsLogProcessor::cancelAnomalyAlarm() { std::lock_guard<std::mutex> lock(mAnomalyAlarmMutex); mNextAnomalyAlarmTime = 0; } void StatsLogProcessor::informAnomalyAlarmFiredLocked(const int64_t elapsedTimeMillis) { VLOG("StatsService::informAlarmForSubscriberTriggeringFired was called"); std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet = mAnomalyAlarmMonitor->popSoonerThan(static_cast<uint32_t>(elapsedTimeMillis / 1000)); if (alarmSet.size() > 0) { VLOG("Found periodic alarm fired."); processFiredAnomalyAlarmsLocked(MillisToNano(elapsedTimeMillis), alarmSet); } else { ALOGW("Cannot find an periodic alarm that fired. Perhaps it was recently cancelled."); } } } // namespace statsd } // namespace os } // namespace android cmds/statsd/src/StatsLogProcessor.h +21 −5 Original line number Diff line number Diff line Loading @@ -66,11 +66,6 @@ public: const DumpLatency dumpLatency, ProtoOutputStream* proto); /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */ void onAnomalyAlarmFired( const int64_t& timestampNs, unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet); /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies periodic alarmSet. */ void onPeriodicAlarmFired( const int64_t& timestampNs, Loading Loading @@ -146,6 +141,10 @@ public: // Add a specific config key to the possible configs to dump ASAP. void noteOnDiskData(const ConfigKey& key); void setAnomalyAlarm(const int64_t timeMillis); void cancelAnomalyAlarm(); private: // For testing only. inline sp<AlarmMonitor> getAnomalyAlarmMonitor() const { Loading @@ -158,6 +157,11 @@ private: mutable mutex mMetricsMutex; // Guards mNextAnomalyAlarmTime. A separate mutex is needed because alarms are set/cancelled // in the onLogEvent code path, which is locked by mMetricsMutex. // DO NOT acquire mMetricsMutex while holding mAnomalyAlarmMutex. This can lead to a deadlock. mutable mutex mAnomalyAlarmMutex; std::unordered_map<ConfigKey, sp<MetricsManager>> mMetricsManagers; std::unordered_map<ConfigKey, int64_t> mLastBroadcastTimes; Loading Loading @@ -248,6 +252,15 @@ private: // Reset the specified configs. void resetConfigsLocked(const int64_t timestampNs, const std::vector<ConfigKey>& configs); // An anomaly alarm should have fired. // Check with anomaly alarm manager to find the alarms and process the result. void informAnomalyAlarmFiredLocked(const int64_t elapsedTimeMillis); /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */ void processFiredAnomalyAlarmsLocked( const int64_t& timestampNs, unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet); // Function used to send a broadcast so that receiver for the config key can call getData // to retrieve the stored data. std::function<bool(const ConfigKey& key)> mSendBroadcast; Loading @@ -274,6 +287,9 @@ private: //Last time we wrote metadata to disk. int64_t mLastMetadataWriteNs = 0; // The time for the next anomaly alarm for alerts. int64_t mNextAnomalyAlarmTime = 0; bool mPrintAllLogs = false; FRIEND_TEST(StatsLogProcessorTest, TestOutOfOrderLogs); Loading cmds/statsd/src/StatsService.cpp +7 −21 Original line number Diff line number Diff line Loading @@ -91,17 +91,13 @@ Status checkUid(uid_t expectedUid) { StatsService::StatsService(const sp<Looper>& handlerLooper, shared_ptr<LogEventQueue> queue) : mAnomalyAlarmMonitor(new AlarmMonitor( MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS, [](const shared_ptr<IStatsCompanionService>& sc, int64_t timeMillis) { if (sc != nullptr) { sc->setAnomalyAlarm(timeMillis); [this](const shared_ptr<IStatsCompanionService>& /*sc*/, int64_t timeMillis) { mProcessor->setAnomalyAlarm(timeMillis); StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged(); } }, [](const shared_ptr<IStatsCompanionService>& sc) { if (sc != nullptr) { sc->cancelAnomalyAlarm(); [this](const shared_ptr<IStatsCompanionService>& /*sc*/) { mProcessor->cancelAnomalyAlarm(); StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged(); } })), mPeriodicAlarmMonitor(new AlarmMonitor( MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS, Loading Loading @@ -979,17 +975,7 @@ Status StatsService::informOnePackageRemoved(const string& app, int32_t uid) { Status StatsService::informAnomalyAlarmFired() { ENFORCE_UID(AID_SYSTEM); VLOG("StatsService::informAnomalyAlarmFired was called"); int64_t currentTimeSec = getElapsedRealtimeSec(); std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet = mAnomalyAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec)); if (alarmSet.size() > 0) { VLOG("Found an anomaly alarm that fired."); mProcessor->onAnomalyAlarmFired(currentTimeSec * NS_PER_SEC, alarmSet); } else { VLOG("Cannot find an anomaly alarm that fired. Perhaps it was recently cancelled."); } // Anomaly alarms are handled internally now. This code should be fully deleted. return Status::ok(); } Loading cmds/statsd/src/StatsService.h +4 −0 Original line number Diff line number Diff line Loading @@ -404,6 +404,10 @@ private: FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket); FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket); FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket); FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket); FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets); FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period); }; } // namespace statsd Loading cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp +143 −121 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
cmds/statsd/src/StatsLogProcessor.cpp +37 −2 Original line number Diff line number Diff line Loading @@ -120,10 +120,9 @@ static void flushProtoToBuffer(ProtoOutputStream& proto, vector<uint8_t>* outDat } } void StatsLogProcessor::onAnomalyAlarmFired( void StatsLogProcessor::processFiredAnomalyAlarmsLocked( const int64_t& timestampNs, unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) { std::lock_guard<std::mutex> lock(mMetricsMutex); for (const auto& itr : mMetricsManagers) { itr.second->onAnomalyAlarmFired(timestampNs, alarmSet); } Loading Loading @@ -429,6 +428,20 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event, int64_t elapsedRealtimeNs) { return; } bool fireAlarm = false; { std::lock_guard<std::mutex> anomalyLock(mAnomalyAlarmMutex); if (mNextAnomalyAlarmTime != 0 && MillisToNano(mNextAnomalyAlarmTime) <= elapsedRealtimeNs) { mNextAnomalyAlarmTime = 0; VLOG("informing anomaly alarm at time %lld", (long long)elapsedRealtimeNs); fireAlarm = true; } } if (fireAlarm) { informAnomalyAlarmFiredLocked(NanoToMillis(elapsedRealtimeNs)); } int64_t curTimeSec = getElapsedRealtimeSec(); if (curTimeSec - mLastPullerCacheClearTimeSec > StatsdStats::kPullerCacheClearIntervalSec) { mPullerManager->ClearPullerCacheIfNecessary(curTimeSec * NS_PER_SEC); Loading Loading @@ -1090,6 +1103,28 @@ void StatsLogProcessor::noteOnDiskData(const ConfigKey& key) { mOnDiskDataConfigs.insert(key); } void StatsLogProcessor::setAnomalyAlarm(const int64_t elapsedTimeMillis) { std::lock_guard<std::mutex> lock(mAnomalyAlarmMutex); mNextAnomalyAlarmTime = elapsedTimeMillis; } void StatsLogProcessor::cancelAnomalyAlarm() { std::lock_guard<std::mutex> lock(mAnomalyAlarmMutex); mNextAnomalyAlarmTime = 0; } void StatsLogProcessor::informAnomalyAlarmFiredLocked(const int64_t elapsedTimeMillis) { VLOG("StatsService::informAlarmForSubscriberTriggeringFired was called"); std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet = mAnomalyAlarmMonitor->popSoonerThan(static_cast<uint32_t>(elapsedTimeMillis / 1000)); if (alarmSet.size() > 0) { VLOG("Found periodic alarm fired."); processFiredAnomalyAlarmsLocked(MillisToNano(elapsedTimeMillis), alarmSet); } else { ALOGW("Cannot find an periodic alarm that fired. Perhaps it was recently cancelled."); } } } // namespace statsd } // namespace os } // namespace android
cmds/statsd/src/StatsLogProcessor.h +21 −5 Original line number Diff line number Diff line Loading @@ -66,11 +66,6 @@ public: const DumpLatency dumpLatency, ProtoOutputStream* proto); /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */ void onAnomalyAlarmFired( const int64_t& timestampNs, unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet); /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies periodic alarmSet. */ void onPeriodicAlarmFired( const int64_t& timestampNs, Loading Loading @@ -146,6 +141,10 @@ public: // Add a specific config key to the possible configs to dump ASAP. void noteOnDiskData(const ConfigKey& key); void setAnomalyAlarm(const int64_t timeMillis); void cancelAnomalyAlarm(); private: // For testing only. inline sp<AlarmMonitor> getAnomalyAlarmMonitor() const { Loading @@ -158,6 +157,11 @@ private: mutable mutex mMetricsMutex; // Guards mNextAnomalyAlarmTime. A separate mutex is needed because alarms are set/cancelled // in the onLogEvent code path, which is locked by mMetricsMutex. // DO NOT acquire mMetricsMutex while holding mAnomalyAlarmMutex. This can lead to a deadlock. mutable mutex mAnomalyAlarmMutex; std::unordered_map<ConfigKey, sp<MetricsManager>> mMetricsManagers; std::unordered_map<ConfigKey, int64_t> mLastBroadcastTimes; Loading Loading @@ -248,6 +252,15 @@ private: // Reset the specified configs. void resetConfigsLocked(const int64_t timestampNs, const std::vector<ConfigKey>& configs); // An anomaly alarm should have fired. // Check with anomaly alarm manager to find the alarms and process the result. void informAnomalyAlarmFiredLocked(const int64_t elapsedTimeMillis); /* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */ void processFiredAnomalyAlarmsLocked( const int64_t& timestampNs, unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet); // Function used to send a broadcast so that receiver for the config key can call getData // to retrieve the stored data. std::function<bool(const ConfigKey& key)> mSendBroadcast; Loading @@ -274,6 +287,9 @@ private: //Last time we wrote metadata to disk. int64_t mLastMetadataWriteNs = 0; // The time for the next anomaly alarm for alerts. int64_t mNextAnomalyAlarmTime = 0; bool mPrintAllLogs = false; FRIEND_TEST(StatsLogProcessorTest, TestOutOfOrderLogs); Loading
cmds/statsd/src/StatsService.cpp +7 −21 Original line number Diff line number Diff line Loading @@ -91,17 +91,13 @@ Status checkUid(uid_t expectedUid) { StatsService::StatsService(const sp<Looper>& handlerLooper, shared_ptr<LogEventQueue> queue) : mAnomalyAlarmMonitor(new AlarmMonitor( MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS, [](const shared_ptr<IStatsCompanionService>& sc, int64_t timeMillis) { if (sc != nullptr) { sc->setAnomalyAlarm(timeMillis); [this](const shared_ptr<IStatsCompanionService>& /*sc*/, int64_t timeMillis) { mProcessor->setAnomalyAlarm(timeMillis); StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged(); } }, [](const shared_ptr<IStatsCompanionService>& sc) { if (sc != nullptr) { sc->cancelAnomalyAlarm(); [this](const shared_ptr<IStatsCompanionService>& /*sc*/) { mProcessor->cancelAnomalyAlarm(); StatsdStats::getInstance().noteRegisteredAnomalyAlarmChanged(); } })), mPeriodicAlarmMonitor(new AlarmMonitor( MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS, Loading Loading @@ -979,17 +975,7 @@ Status StatsService::informOnePackageRemoved(const string& app, int32_t uid) { Status StatsService::informAnomalyAlarmFired() { ENFORCE_UID(AID_SYSTEM); VLOG("StatsService::informAnomalyAlarmFired was called"); int64_t currentTimeSec = getElapsedRealtimeSec(); std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet = mAnomalyAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec)); if (alarmSet.size() > 0) { VLOG("Found an anomaly alarm that fired."); mProcessor->onAnomalyAlarmFired(currentTimeSec * NS_PER_SEC, alarmSet); } else { VLOG("Cannot find an anomaly alarm that fired. Perhaps it was recently cancelled."); } // Anomaly alarms are handled internally now. This code should be fully deleted. return Status::ok(); } Loading
cmds/statsd/src/StatsService.h +4 −0 Original line number Diff line number Diff line Loading @@ -404,6 +404,10 @@ private: FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket); FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket); FRIEND_TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket); FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket); FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets); FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period); }; } // namespace statsd Loading
cmds/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp +143 −121 File changed.Preview size limit exceeded, changes collapsed. Show changes