Merge "Move forward the alarm timestamp when config is added to statsd." into pi-dev

This commit is contained in:
TreeHugger Robot
2018-04-03 17:57:43 +00:00
committed by Android (Google) Code Review
19 changed files with 75 additions and 49 deletions

View File

@@ -366,7 +366,7 @@ sp<StatsLogProcessor> CreateStatsLogProcessor(const long timeBaseSec, const Stat
sp<AlarmMonitor> periodicAlarmMonitor;
sp<StatsLogProcessor> processor = new StatsLogProcessor(
uidMap, anomalyAlarmMonitor, periodicAlarmMonitor, timeBaseSec, [](const ConfigKey&){});
processor->OnConfigUpdated(key, config);
processor->OnConfigUpdated(0, key, config);
return processor;
}

View File

@@ -191,11 +191,12 @@ void StatsLogProcessor::OnLogEvent(LogEvent* event) {
}
}
void StatsLogProcessor::OnConfigUpdated(const ConfigKey& key, const StatsdConfig& config) {
void StatsLogProcessor::OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
const StatsdConfig& config) {
std::lock_guard<std::mutex> lock(mMetricsMutex);
VLOG("Updated configuration for key %s", key.ToString().c_str());
sp<MetricsManager> newMetricsManager =
new MetricsManager(key, config, mTimeBaseSec, mUidMap,
new MetricsManager(key, config, mTimeBaseSec, (timestampNs - 1) / NS_PER_SEC + 1, mUidMap,
mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
if (newMetricsManager->isConfigValid()) {

View File

@@ -42,7 +42,8 @@ public:
void OnLogEvent(LogEvent* event);
void OnConfigUpdated(const ConfigKey& key, const StatsdConfig& config);
void OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
const StatsdConfig& config);
void OnConfigRemoved(const ConfigKey& key);
size_t GetMetricsSize(const ConfigKey& key) const;

View File

@@ -30,7 +30,8 @@ namespace android {
namespace os {
namespace statsd {
AlarmTracker::AlarmTracker(uint64_t startMillis,
AlarmTracker::AlarmTracker(const uint64_t startMillis,
const uint64_t currentMillis,
const Alarm& alarm, const ConfigKey& configKey,
const sp<AlarmMonitor>& alarmMonitor)
: mAlarmConfig(alarm),
@@ -38,7 +39,11 @@ AlarmTracker::AlarmTracker(uint64_t startMillis,
mAlarmMonitor(alarmMonitor) {
VLOG("AlarmTracker() called");
mAlarmSec = (startMillis + mAlarmConfig.offset_millis()) / MS_PER_SEC;
// startMillis is the time statsd is created. We need to find the 1st alarm timestamp after
// the config is added to statsd.
mAlarmSec = findNextAlarmSec(currentMillis / MS_PER_SEC); // round up
mInternalAlarm = new InternalAlarm{static_cast<uint32_t>(mAlarmSec)};
VLOG("AlarmTracker sets the periodic alarm at: %lld", (long long)mAlarmSec);
if (mAlarmMonitor != nullptr) {
mAlarmMonitor->add(mInternalAlarm);
}
@@ -55,9 +60,13 @@ void AlarmTracker::addSubscription(const Subscription& subscription) {
mSubscriptions.push_back(subscription);
}
uint64_t AlarmTracker::findNextAlarmSec(uint64_t currentTimeSec) {
int periodsForward = (currentTimeSec - mAlarmSec) * MS_PER_SEC / mAlarmConfig.period_millis();
return mAlarmSec + (periodsForward + 1) * mAlarmConfig.period_millis() / MS_PER_SEC;
int64_t AlarmTracker::findNextAlarmSec(int64_t currentTimeSec) {
if (currentTimeSec <= mAlarmSec) {
return mAlarmSec;
}
int64_t periodsForward =
((currentTimeSec - mAlarmSec) * MS_PER_SEC - 1) / mAlarmConfig.period_millis() + 1;
return mAlarmSec + periodsForward * mAlarmConfig.period_millis() / MS_PER_SEC;
}
void AlarmTracker::informAlarmsFired(
@@ -68,12 +77,14 @@ void AlarmTracker::informAlarmsFired(
return;
}
if (!mSubscriptions.empty()) {
VLOG("AlarmTracker triggers the subscribers.");
triggerSubscribers(mAlarmConfig.id(), DEFAULT_METRIC_DIMENSION_KEY, mConfigKey,
mSubscriptions);
}
firedAlarms.erase(mInternalAlarm);
mAlarmSec = findNextAlarmSec((timestampNs-1) / NS_PER_SEC + 1); // round up
mInternalAlarm = new InternalAlarm{static_cast<uint32_t>(mAlarmSec)};
VLOG("AlarmTracker sets the periodic alarm at: %lld", (long long)mAlarmSec);
if (mAlarmMonitor != nullptr) {
mAlarmMonitor->add(mInternalAlarm);
}

View File

@@ -34,7 +34,8 @@ namespace statsd {
class AlarmTracker : public virtual RefBase {
public:
AlarmTracker(uint64_t startMillis,
AlarmTracker(const uint64_t startMillis,
const uint64_t currentMillis,
const Alarm& alarm, const ConfigKey& configKey,
const sp<AlarmMonitor>& subscriberAlarmMonitor);
@@ -53,13 +54,13 @@ protected:
return mInternalAlarm == nullptr ? 0 : mInternalAlarm->timestampSec;
}
uint64_t findNextAlarmSec(uint64_t currentTimeMillis);
int64_t findNextAlarmSec(int64_t currentTimeMillis);
// statsd_config.proto Alarm message that defines this tracker.
const Alarm mAlarmConfig;
// A reference to the Alarm's config key.
const ConfigKey& mConfigKey;
const ConfigKey mConfigKey;
// The subscriptions that depend on this alarm.
std::vector<Subscription> mSubscriptions;
@@ -68,7 +69,7 @@ protected:
sp<AlarmMonitor> mAlarmMonitor;
// The current expected alarm time in seconds.
uint64_t mAlarmSec;
int64_t mAlarmSec;
// The current alarm.
sp<const InternalAlarm> mInternalAlarm;

View File

@@ -127,7 +127,7 @@ protected:
std::vector<Subscription> mSubscriptions;
// A reference to the Alert's config key.
const ConfigKey& mConfigKey;
const ConfigKey mConfigKey;
// Number of past buckets. One less than the total number of buckets needed
// for the anomaly detection (since the current bucket is not in the past).

View File

@@ -40,7 +40,8 @@ public:
/**
* A configuration was added or updated.
*/
virtual void OnConfigUpdated(const ConfigKey& key, const StatsdConfig& config) = 0;
virtual void OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
const StatsdConfig& config) = 0;
/**
* A configuration was removed.

View File

@@ -21,6 +21,7 @@
#include "storage/StorageManager.h"
#include "guardrail/StatsdStats.h"
#include "stats_log_util.h"
#include "stats_util.h"
#include <android-base/file.h>
@@ -109,9 +110,10 @@ void ConfigManager::UpdateConfig(const ConfigKey& key, const StatsdConfig& confi
}
}
const int64_t timestampNs = getElapsedRealtimeNs();
// Tell everyone
for (sp<ConfigListener> listener:broadcastList) {
listener->OnConfigUpdated(key, config);
listener->OnConfigUpdated(timestampNs, key, config);
}
}

View File

@@ -49,7 +49,7 @@ namespace statsd {
const int FIELD_ID_METRICS = 1;
MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config,
const long timeBaseSec,
const long timeBaseSec, const long currentTimeSec,
const sp<UidMap> &uidMap,
const sp<AlarmMonitor>& anomalyAlarmMonitor,
const sp<AlarmMonitor>& periodicAlarmMonitor)
@@ -58,7 +58,7 @@ MetricsManager::MetricsManager(const ConfigKey& key, const StatsdConfig& config,
mLastReportWallClockNs(getWallClockNs()) {
mConfigValid =
initStatsdConfig(key, config, *uidMap, anomalyAlarmMonitor, periodicAlarmMonitor,
timeBaseSec, mTagIds, mAllAtomMatchers,
timeBaseSec, currentTimeSec, mTagIds, mAllAtomMatchers,
mAllConditionTrackers, mAllMetricProducers, mAllAnomalyTrackers,
mAllPeriodicAlarmTrackers, mConditionToMetricMap, mTrackerToMetricMap,
mTrackerToConditionMap, mNoReportMetricIds);

View File

@@ -36,7 +36,8 @@ namespace statsd {
// A MetricsManager is responsible for managing metrics from one single config source.
class MetricsManager : public PackageInfoListener {
public:
MetricsManager(const ConfigKey& configKey, const StatsdConfig& config, const long timeBaseSec,
MetricsManager(const ConfigKey& configKey, const StatsdConfig& config,
const long timeBaseSec, const long currentTimeSec,
const sp<UidMap>& uidMap, const sp<AlarmMonitor>& anomalyAlarmMonitor,
const sp<AlarmMonitor>& periodicAlarmMonitor);

View File

@@ -599,10 +599,11 @@ bool initAlerts(const StatsdConfig& config,
bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
const sp<AlarmMonitor>& periodicAlarmMonitor,
const long timeBaseSec,
const long timeBaseSec, const long currentTimeSec,
vector<sp<AlarmTracker>>& allAlarmTrackers) {
unordered_map<int64_t, int> alarmTrackerMap;
uint64_t startMillis = (uint64_t)timeBaseSec * MS_PER_SEC;
uint64_t currentTimeMillis = (uint64_t)currentTimeSec * MS_PER_SEC;
for (int i = 0; i < config.alarm_size(); i++) {
const Alarm& alarm = config.alarm(i);
if (alarm.offset_millis() <= 0) {
@@ -615,7 +616,8 @@ bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
}
alarmTrackerMap.insert(std::make_pair(alarm.id(), allAlarmTrackers.size()));
allAlarmTrackers.push_back(
new AlarmTracker(startMillis, alarm, key, periodicAlarmMonitor));
new AlarmTracker(startMillis, currentTimeMillis,
alarm, key, periodicAlarmMonitor));
}
for (int i = 0; i < config.subscription_size(); ++i) {
const Subscription& subscription = config.subscription(i);
@@ -644,7 +646,7 @@ bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config,
const UidMap& uidMap,
const sp<AlarmMonitor>& anomalyAlarmMonitor,
const sp<AlarmMonitor>& periodicAlarmMonitor,
const long timeBaseSec,
const long timeBaseSec, const long currentTimeSec,
set<int>& allTagIds,
vector<sp<LogMatchingTracker>>& allAtomMatchers,
vector<sp<ConditionTracker>>& allConditionTrackers,
@@ -682,7 +684,8 @@ bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config,
ALOGE("initAlerts failed");
return false;
}
if (!initAlarms(config, key, periodicAlarmMonitor, timeBaseSec, allPeriodicAlarmTrackers)) {
if (!initAlarms(config, key, periodicAlarmMonitor,
timeBaseSec, currentTimeSec, allPeriodicAlarmTrackers)) {
ALOGE("initAlarms failed");
return false;
}

View File

@@ -98,7 +98,7 @@ bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config,
const UidMap& uidMap,
const sp<AlarmMonitor>& anomalyAlarmMonitor,
const sp<AlarmMonitor>& periodicAlarmMonitor,
const long timeBaseSec,
const long timeBaseSec, const long currentTimeSec,
std::set<int>& allTagIds,
std::vector<sp<LogMatchingTracker>>& allAtomMatchers,
std::vector<sp<ConditionTracker>>& allConditionTrackers,

View File

@@ -44,7 +44,8 @@ static ostream& operator<<(ostream& os, const StatsdConfig& config) {
*/
class MockListener : public ConfigListener {
public:
MOCK_METHOD2(OnConfigUpdated, void(const ConfigKey& key, const StatsdConfig& config));
MOCK_METHOD3(OnConfigUpdated, void(const int64_t timestampNs, const ConfigKey& key,
const StatsdConfig& config));
MOCK_METHOD1(OnConfigRemoved, void(const ConfigKey& key));
};
@@ -88,25 +89,25 @@ TEST(ConfigManagerTest, TestAddUpdateRemove) {
manager->StartupForTest();
// Add another one
EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(1, StringToId("zzz")),
EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(1, StringToId("zzz")),
StatsdConfigEq(91)))
.RetiresOnSaturation();
manager->UpdateConfig(ConfigKey(1, StringToId("zzz")), config91);
// Update It
EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(1, StringToId("zzz")),
EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(1, StringToId("zzz")),
StatsdConfigEq(92)))
.RetiresOnSaturation();
manager->UpdateConfig(ConfigKey(1, StringToId("zzz")), config92);
// Add one with the same uid but a different name
EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(1, StringToId("yyy")),
EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(1, StringToId("yyy")),
StatsdConfigEq(93)))
.RetiresOnSaturation();
manager->UpdateConfig(ConfigKey(1, StringToId("yyy")), config93);
// Add one with the same name but a different uid
EXPECT_CALL(*(listener.get()), OnConfigUpdated(ConfigKeyEq(2, StringToId("zzz")),
EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, ConfigKeyEq(2, StringToId("zzz")),
StatsdConfigEq(94)))
.RetiresOnSaturation();
manager->UpdateConfig(ConfigKey(2, StringToId("zzz")), config94);
@@ -142,7 +143,7 @@ TEST(ConfigManagerTest, TestRemoveUid) {
StatsdConfig config;
EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, _)).Times(5);
EXPECT_CALL(*(listener.get()), OnConfigUpdated(_, _, _)).Times(5);
EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("xxx"))));
EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("yyy"))));
EXPECT_CALL(*(listener.get()), OnConfigRemoved(ConfigKeyEq(2, StringToId("zzz"))));

View File

@@ -287,7 +287,7 @@ TEST(MetricsManagerTest, TestGoodConfig) {
EXPECT_TRUE(initStatsdConfig(kConfigKey, config, uidMap,
anomalyAlarmMonitor, periodicAlarmMonitor,
timeBaseSec, allTagIds, allAtomMatchers,
timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
allConditionTrackers, allMetricProducers, allAnomalyTrackers,
allAlarmTrackers,
conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
@@ -315,7 +315,7 @@ TEST(MetricsManagerTest, TestDimensionMetricsWithMultiTags) {
EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
anomalyAlarmMonitor, periodicAlarmMonitor,
timeBaseSec, allTagIds, allAtomMatchers,
timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
allConditionTrackers, allMetricProducers, allAnomalyTrackers,
allAlarmTrackers,
conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
@@ -340,7 +340,7 @@ TEST(MetricsManagerTest, TestCircleLogMatcherDependency) {
EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
anomalyAlarmMonitor, periodicAlarmMonitor,
timeBaseSec, allTagIds, allAtomMatchers,
timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
allConditionTrackers, allMetricProducers, allAnomalyTrackers,
allAlarmTrackers,
conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
@@ -364,7 +364,7 @@ TEST(MetricsManagerTest, TestMissingMatchers) {
std::set<int64_t> noReportMetricIds;
EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
anomalyAlarmMonitor, periodicAlarmMonitor,
timeBaseSec, allTagIds, allAtomMatchers,
timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
allConditionTrackers, allMetricProducers, allAnomalyTrackers,
allAlarmTrackers,
conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
@@ -388,7 +388,7 @@ TEST(MetricsManagerTest, TestMissingPredicate) {
std::set<int64_t> noReportMetricIds;
EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
anomalyAlarmMonitor, periodicAlarmMonitor,
timeBaseSec, allTagIds, allAtomMatchers,
timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
allConditionTrackers, allMetricProducers, allAnomalyTrackers,
allAlarmTrackers,
conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
@@ -413,7 +413,7 @@ TEST(MetricsManagerTest, TestCirclePredicateDependency) {
EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
anomalyAlarmMonitor, periodicAlarmMonitor,
timeBaseSec, allTagIds, allAtomMatchers,
timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
allConditionTrackers, allMetricProducers, allAnomalyTrackers,
allAlarmTrackers,
conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,
@@ -438,7 +438,7 @@ TEST(MetricsManagerTest, testAlertWithUnknownMetric) {
EXPECT_FALSE(initStatsdConfig(kConfigKey, config, uidMap,
anomalyAlarmMonitor, periodicAlarmMonitor,
timeBaseSec, allTagIds, allAtomMatchers,
timeBaseSec, timeBaseSec, allTagIds, allAtomMatchers,
allConditionTrackers, allMetricProducers, allAnomalyTrackers,
allAlarmTrackers,
conditionToMetricMap, trackerToMetricMap, trackerToConditionMap,

View File

@@ -43,7 +43,7 @@ using android::util::ProtoOutputStream;
class MockMetricsManager : public MetricsManager {
public:
MockMetricsManager() : MetricsManager(
ConfigKey(1, 12345), StatsdConfig(), 1000,
ConfigKey(1, 12345), StatsdConfig(), 1000, 1000,
new UidMap(),
new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t){},
[](const sp<IStatsCompanionService>&){}),
@@ -135,7 +135,7 @@ TEST(StatsLogProcessorTest, TestUidMapHasSnapshot) {
ConfigKey key(3, 4);
StatsdConfig config;
config.add_allowed_log_source("AID_ROOT");
p.OnConfigUpdated(key, config);
p.OnConfigUpdated(0, key, config);
// Expect to get no metrics, but snapshot specified above in uidmap.
vector<uint8_t> bytes;

View File

@@ -39,25 +39,24 @@ TEST(AlarmTrackerTest, TestTriggerTimestamp) {
Alarm alarm;
alarm.set_offset_millis(15 * MS_PER_SEC);
alarm.set_period_millis(60 * 60 * MS_PER_SEC); // 1hr
uint64_t startMillis = 100000000 * MS_PER_SEC;
AlarmTracker tracker(startMillis, alarm, kConfigKey,
subscriberAlarmMonitor);
int64_t startMillis = 100000000 * MS_PER_SEC;
AlarmTracker tracker(startMillis, startMillis, alarm, kConfigKey, subscriberAlarmMonitor);
EXPECT_EQ(tracker.mAlarmSec, startMillis / MS_PER_SEC + 15);
EXPECT_EQ(tracker.mAlarmSec, (int64_t)(startMillis / MS_PER_SEC + 15));
uint64_t currentTimeSec = startMillis / MS_PER_SEC + 10;
std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> firedAlarmSet =
subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
EXPECT_TRUE(firedAlarmSet.empty());
tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
EXPECT_EQ(tracker.mAlarmSec, startMillis / MS_PER_SEC + 15);
EXPECT_EQ(tracker.mAlarmSec, (int64_t)(startMillis / MS_PER_SEC + 15));
currentTimeSec = startMillis / MS_PER_SEC + 7000;
firedAlarmSet = subscriberAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
EXPECT_EQ(firedAlarmSet.size(), 1u);
tracker.informAlarmsFired(currentTimeSec * NS_PER_SEC, firedAlarmSet);
EXPECT_TRUE(firedAlarmSet.empty());
EXPECT_EQ(tracker.mAlarmSec, startMillis / MS_PER_SEC + 15 + 2 * 60 * 60);
EXPECT_EQ(tracker.mAlarmSec, (int64_t)(startMillis / MS_PER_SEC + 15 + 2 * 60 * 60));
}
} // namespace statsd

View File

@@ -455,7 +455,7 @@ sp<StatsLogProcessor> CreateStatsLogProcessor(const long timeBaseSec, const Stat
[](const sp<IStatsCompanionService>&){});
sp<StatsLogProcessor> processor = new StatsLogProcessor(
uidMap, anomalyAlarmMonitor, periodicAlarmMonitor, timeBaseSec, [](const ConfigKey&){});
processor->OnConfigUpdated(key, config);
processor->OnConfigUpdated(timeBaseSec, key, config);
return processor;
}

View File

@@ -4248,6 +4248,11 @@
android:exported="false">
</receiver>
<receiver android:name="com.android.server.stats.StatsCompanionService$PeriodicAlarmReceiver"
android:permission="android.permission.STATSCOMPANION"
android:exported="false">
</receiver>
<receiver android:name="com.android.server.am.BatteryStatsService$UsbConnectionReceiver"
android:exported="false">
<intent-filter>

View File

@@ -379,7 +379,7 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
@Override
public void onReceive(Context context, Intent intent) {
if (DEBUG)
Slog.d(TAG, "Time to poll something.");
Slog.d(TAG, "Time to trigger periodic alarm.");
synchronized (sStatsdLock) {
if (sStatsd == null) {
Slog.w(TAG, "Could not access statsd to inform it of periodic alarm firing.");
@@ -455,13 +455,13 @@ public class StatsCompanionService extends IStatsCompanionService.Stub {
public void setAlarmForSubscriberTriggering(long timestampMs) {
enforceCallingPermission();
if (DEBUG)
Slog.d(TAG, "Setting periodic alarm at " + timestampMs);
Slog.d(TAG, "Setting periodic alarm in about " +
(timestampMs - SystemClock.elapsedRealtime()));
final long callingToken = Binder.clearCallingIdentity();
try {
// using ELAPSED_REALTIME, not ELAPSED_REALTIME_WAKEUP, so if device is asleep, will
// only fire when it awakens.
// This alarm is inexact, leaving its exactness completely up to the OS optimizations.
mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, timestampMs, mPeriodicAlarmIntent);
mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME, timestampMs, mPeriodicAlarmIntent);
} finally {
Binder.restoreCallingIdentity(callingToken);
}