allow disable partial bucket on app upgrade
Bug: 112630210
Test: unit test
Change-Id: I2de38d35f14b813d2837455a322acc2e00813e3b
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index 67a1a47..c2878f0 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -93,7 +93,8 @@
StatsdStats::kAtomDimensionKeySizeLimitMap.end()
? StatsdStats::kAtomDimensionKeySizeLimitMap.at(pullTagId).second
: StatsdStats::kDimensionKeySizeHardLimit),
- mGaugeAtomsPerDimensionLimit(metric.max_num_gauge_atoms_per_bucket()) {
+ mGaugeAtomsPerDimensionLimit(metric.max_num_gauge_atoms_per_bucket()),
+ mSplitBucketForAppUpgrade(metric.split_bucket_for_app_upgrade()) {
mCurrentSlicedBucket = std::make_shared<DimToGaugeAtomsMap>();
mCurrentSlicedBucketForAnomaly = std::make_shared<DimToValMap>();
int64_t bucketSizeMills = 0;
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index a1a5061..df08779 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -74,6 +74,9 @@
const int64_t version) override {
std::lock_guard<std::mutex> lock(mMutex);
+ if (!mSplitBucketForAppUpgrade) {
+ return;
+ }
if (eventTimeNs > getCurrentBucketEndTimeNs()) {
// Flush full buckets on the normal path up to the latest bucket boundary.
flushIfNeededLocked(eventTimeNs);
@@ -176,11 +179,14 @@
const size_t mGaugeAtomsPerDimensionLimit;
+ const bool mSplitBucketForAppUpgrade;
+
FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition);
FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsWithSlicedCondition);
FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsNoCondition);
FRIEND_TEST(GaugeMetricProducerTest, TestPushedEventsWithUpgrade);
FRIEND_TEST(GaugeMetricProducerTest, TestPulledWithUpgrade);
+ FRIEND_TEST(GaugeMetricProducerTest, TestPulledWithAppUpgradeDisabled);
FRIEND_TEST(GaugeMetricProducerTest, TestPulledEventsAnomalyDetection);
FRIEND_TEST(GaugeMetricProducerTest, TestFirstBucket);
FRIEND_TEST(GaugeMetricProducerTest, TestPullOnTrigger);
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 9a8e3bd..4122d84 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -105,7 +105,8 @@
mUseZeroDefaultBase(metric.use_zero_default_base()),
mHasGlobalBase(false),
mMaxPullDelayNs(metric.max_pull_delay_sec() > 0 ? metric.max_pull_delay_sec() * NS_PER_SEC
- : StatsdStats::kPullMaxDelayNs) {
+ : StatsdStats::kPullMaxDelayNs),
+ mSplitBucketForAppUpgrade(metric.split_bucket_for_app_upgrade()) {
int64_t bucketSizeMills = 0;
if (metric.has_bucket()) {
bucketSizeMills = TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket());
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index 4865aee..69eb0af 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -57,6 +57,9 @@
void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
const int64_t version) override {
std::lock_guard<std::mutex> lock(mMutex);
+ if (!mSplitBucketForAppUpgrade) {
+ return;
+ }
if (mIsPulled && mCondition) {
pullAndMatchEventsLocked(eventTimeNs - 1);
}
@@ -185,6 +188,8 @@
const int64_t mMaxPullDelayNs;
+ const bool mSplitBucketForAppUpgrade;
+
FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsNoCondition);
FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsWithFiltering);
FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset);
@@ -193,6 +198,7 @@
FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade);
FRIEND_TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade);
FRIEND_TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse);
+ FRIEND_TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled);
FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition);
FRIEND_TEST(ValueMetricProducerTest, TestPushedEventsWithCondition);
FRIEND_TEST(ValueMetricProducerTest, TestAnomalyDetection);
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index 381ac32..9d3a669 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -244,6 +244,8 @@
optional int64 max_num_gauge_atoms_per_bucket = 11 [default = 10];
optional int32 max_pull_delay_sec = 13 [default = 10];
+
+ optional bool split_bucket_for_app_upgrade = 14 [default = true];
}
message ValueMetric {
@@ -290,6 +292,8 @@
optional bool skip_zero_diff_output = 14 [default = true];
optional int32 max_pull_delay_sec = 16 [default = 10];
+
+ optional bool split_bucket_for_app_upgrade = 17 [default = true];
}
message Alert {
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index 2799107..0ffbb54 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -276,8 +276,9 @@
UidMap uidMap;
SimpleAtomMatcher atomMatcher;
atomMatcher.set_atom_id(tagId);
- sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
- new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
@@ -295,9 +296,8 @@
}));
GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
- logEventMatcherIndex, eventMatcherWizard,
- tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
- pullerManager);
+ logEventMatcherIndex, eventMatcherWizard, tagId, -1, tagId,
+ bucketStartTimeNs, bucketStartTimeNs, pullerManager);
vector<shared_ptr<LogEvent>> allData;
shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
@@ -337,6 +337,58 @@
->mValue.int_value);
}
+TEST(GaugeMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
+ GaugeMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.set_max_pull_delay_sec(INT_MAX);
+ metric.set_split_bucket_for_app_upgrade(false);
+ auto gaugeFieldMatcher = metric.mutable_gauge_fields_filter()->mutable_fields();
+ gaugeFieldMatcher->set_field(tagId);
+ gaugeFieldMatcher->add_child()->set_field(2);
+
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard = new EventMatcherWizard({
+ new SimpleLogMatchingTracker(atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(false));
+
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+ logEventMatcherIndex, eventMatcherWizard,
+ tagId, -1, tagId, bucketStartTimeNs, bucketStartTimeNs,
+ pullerManager);
+
+ vector<shared_ptr<LogEvent>> allData;
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
+ event->write("some value");
+ event->write(1);
+ event->init();
+ allData.push_back(event);
+ gaugeProducer.onDataPulled(allData);
+ EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
+ ->second.front()
+ .mFields->begin()
+ ->mValue.int_value);
+
+ gaugeProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
+ EXPECT_EQ(0UL, gaugeProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+ EXPECT_EQ(0L, gaugeProducer.mCurrentBucketNum);
+ EXPECT_EQ(bucketStartTimeNs, gaugeProducer.mCurrentBucketStartTimeNs);
+ EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ EXPECT_EQ(1, gaugeProducer.mCurrentSlicedBucket->begin()
+ ->second.front()
+ .mFields->begin()
+ ->mValue.int_value);
+}
+
TEST(GaugeMetricProducerTest, TestPulledEventsWithCondition) {
GaugeMetric metric;
metric.set_id(metricId);
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index 67570fc..9cfe343 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -641,7 +641,8 @@
valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
+ EXPECT_EQ(20L,
+ valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
allData.clear();
event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
@@ -652,7 +653,48 @@
valueProducer.onDataPulled(allData);
EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
+ EXPECT_EQ(20L,
+ valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].values[0].long_value);
+}
+
+TEST(ValueMetricProducerTest, TestPulledWithAppUpgradeDisabled) {
+ ValueMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_value_field()->set_field(tagId);
+ metric.mutable_value_field()->add_child()->set_field(2);
+ metric.set_max_pull_delay_sec(INT_MAX);
+ metric.set_split_bucket_for_app_upgrade(false);
+
+ UidMap uidMap;
+ SimpleAtomMatcher atomMatcher;
+ atomMatcher.set_atom_id(tagId);
+ sp<EventMatcherWizard> eventMatcherWizard =
+ new EventMatcherWizard({new SimpleLogMatchingTracker(
+ atomMatcherId, logEventMatcherIndex, atomMatcher, uidMap)});
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, _)).WillOnce(Return(true));
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, logEventMatcherIndex,
+ eventMatcherWizard, tagId, bucketStartTimeNs,
+ bucketStartTimeNs, pullerManager);
+
+ vector<shared_ptr<LogEvent>> allData;
+ allData.clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
+ event->write(tagId);
+ event->write(100);
+ event->init();
+ allData.push_back(event);
+
+ valueProducer.onDataPulled(allData);
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+
+ valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
+ EXPECT_EQ(0UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+ EXPECT_EQ(bucketStartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
}
TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {