Merge "Support sliced condition change in GaugeMetric" into pi-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
d9afdee26f
@@ -149,9 +149,9 @@ void CombinationConditionTracker::evaluateCondition(
|
||||
}
|
||||
}
|
||||
|
||||
ConditionState newCondition =
|
||||
evaluateCombinationCondition(mChildren, mLogicalOperation, nonSlicedConditionCache);
|
||||
if (!mSliced) {
|
||||
ConditionState newCondition =
|
||||
evaluateCombinationCondition(mChildren, mLogicalOperation, nonSlicedConditionCache);
|
||||
|
||||
bool nonSlicedChanged = (mNonSlicedConditionState != newCondition);
|
||||
mNonSlicedConditionState = newCondition;
|
||||
@@ -172,7 +172,7 @@ void CombinationConditionTracker::evaluateCondition(
|
||||
break;
|
||||
}
|
||||
}
|
||||
nonSlicedConditionCache[mIndex] = ConditionState::kUnknown;
|
||||
nonSlicedConditionCache[mIndex] = newCondition;
|
||||
VLOG("CombinationPredicate %lld sliced may changed? %d", (long long)mConditionId,
|
||||
conditionChangedCache[mIndex] == true);
|
||||
}
|
||||
|
||||
@@ -289,9 +289,15 @@ void SimpleConditionTracker::evaluateCondition(
|
||||
// The event doesn't match this condition. So we just report existing condition values.
|
||||
conditionChangedCache[mIndex] = false;
|
||||
if (mSliced) {
|
||||
// if the condition result is sliced. metrics won't directly get value from the
|
||||
// cache, so just set any value other than kNotEvaluated.
|
||||
// if the condition result is sliced. The overall condition is true if any of the sliced
|
||||
// condition is true
|
||||
conditionCache[mIndex] = mInitialValue;
|
||||
for (const auto& slicedCondition : mSlicedConditionState) {
|
||||
if (slicedCondition.second > 0) {
|
||||
conditionCache[mIndex] = ConditionState::kTrue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
|
||||
if (itr == mSlicedConditionState.end()) {
|
||||
|
||||
@@ -141,7 +141,7 @@ void StateTracker::evaluateCondition(const LogEvent& event,
|
||||
// one keys matched.
|
||||
HashableDimensionKey primaryKey;
|
||||
HashableDimensionKey state;
|
||||
if (!filterValues(mPrimaryKeys, event.getValues(), &primaryKey) ||
|
||||
if ((mPrimaryKeys.size() > 0 && !filterValues(mPrimaryKeys, event.getValues(), &primaryKey)) ||
|
||||
!filterValues(mOutputDimensions, event.getValues(), &state)) {
|
||||
ALOGE("Failed to filter fields in the event?? panic now!");
|
||||
conditionCache[mIndex] =
|
||||
|
||||
@@ -255,331 +255,6 @@ void ConfigManager::update_saved_configs_locked(const ConfigKey& key,
|
||||
StorageManager::writeFile(file_name.c_str(), &buffer[0], numBytes);
|
||||
}
|
||||
|
||||
StatsdConfig build_fake_config() {
|
||||
// HACK: Hard code a test metric for counting screen on events...
|
||||
StatsdConfig config;
|
||||
config.set_id(12345);
|
||||
|
||||
int WAKE_LOCK_TAG_ID = 1111; // put a fake id here to make testing easier.
|
||||
int WAKE_LOCK_UID_KEY_ID = 1;
|
||||
int WAKE_LOCK_NAME_KEY = 3;
|
||||
int WAKE_LOCK_STATE_KEY = 4;
|
||||
int WAKE_LOCK_ACQUIRE_VALUE = 1;
|
||||
int WAKE_LOCK_RELEASE_VALUE = 0;
|
||||
|
||||
int APP_USAGE_TAG_ID = 12345;
|
||||
int APP_USAGE_UID_KEY_ID = 1;
|
||||
int APP_USAGE_STATE_KEY = 2;
|
||||
int APP_USAGE_FOREGROUND = 1;
|
||||
int APP_USAGE_BACKGROUND = 0;
|
||||
|
||||
int SCREEN_EVENT_TAG_ID = 29;
|
||||
int SCREEN_EVENT_STATE_KEY = 1;
|
||||
int SCREEN_EVENT_ON_VALUE = 2;
|
||||
int SCREEN_EVENT_OFF_VALUE = 1;
|
||||
|
||||
int UID_PROCESS_STATE_TAG_ID = 27;
|
||||
int UID_PROCESS_STATE_UID_KEY = 1;
|
||||
|
||||
int KERNEL_WAKELOCK_TAG_ID = 1004;
|
||||
int KERNEL_WAKELOCK_COUNT_KEY = 2;
|
||||
int KERNEL_WAKELOCK_NAME_KEY = 1;
|
||||
|
||||
int DEVICE_TEMPERATURE_TAG_ID = 33;
|
||||
int DEVICE_TEMPERATURE_KEY = 1;
|
||||
|
||||
// Count Screen ON events.
|
||||
CountMetric* metric = config.add_count_metric();
|
||||
metric->set_id(1); // METRIC_1
|
||||
metric->set_what(102); // "SCREEN_TURNED_ON"
|
||||
metric->set_bucket(ONE_MINUTE);
|
||||
|
||||
// Anomaly threshold for screen-on count.
|
||||
// TODO(b/70627390): Uncomment once the bug is fixed.
|
||||
/*Alert* alert = config.add_alert();
|
||||
alert->set_id("ALERT_1");
|
||||
alert->set_metric_name("METRIC_1");
|
||||
alert->set_number_of_buckets(6);
|
||||
alert->set_trigger_if_sum_gt(10);
|
||||
alert->set_refractory_period_secs(30);
|
||||
Alert::IncidentdDetails* details = alert->mutable_incidentd_details();
|
||||
details->add_section(12);
|
||||
details->add_section(13);*/
|
||||
|
||||
config.add_allowed_log_source("AID_ROOT");
|
||||
config.add_allowed_log_source("AID_SYSTEM");
|
||||
config.add_allowed_log_source("AID_BLUETOOTH");
|
||||
config.add_allowed_log_source("com.android.statsd.dogfood");
|
||||
config.add_allowed_log_source("com.android.systemui");
|
||||
|
||||
// Count process state changes, slice by uid.
|
||||
metric = config.add_count_metric();
|
||||
metric->set_id(2); // "METRIC_2"
|
||||
metric->set_what(104);
|
||||
metric->set_bucket(ONE_MINUTE);
|
||||
FieldMatcher* dimensions = metric->mutable_dimensions_in_what();
|
||||
dimensions->set_field(UID_PROCESS_STATE_TAG_ID);
|
||||
dimensions->add_child()->set_field(UID_PROCESS_STATE_UID_KEY);
|
||||
|
||||
// Anomaly threshold for background count.
|
||||
// TODO(b/70627390): Uncomment once the bug is fixed.
|
||||
/*
|
||||
alert = config.add_alert();
|
||||
alert->set_id("ALERT_2");
|
||||
alert->set_metric_name("METRIC_2");
|
||||
alert->set_number_of_buckets(4);
|
||||
alert->set_trigger_if_sum_gt(30);
|
||||
alert->set_refractory_period_secs(20);
|
||||
details = alert->mutable_incidentd_details();
|
||||
details->add_section(14);
|
||||
details->add_section(15);*/
|
||||
|
||||
// Count process state changes, slice by uid, while SCREEN_IS_OFF
|
||||
metric = config.add_count_metric();
|
||||
metric->set_id(3);
|
||||
metric->set_what(104);
|
||||
metric->set_bucket(ONE_MINUTE);
|
||||
|
||||
dimensions = metric->mutable_dimensions_in_what();
|
||||
dimensions->set_field(UID_PROCESS_STATE_TAG_ID);
|
||||
dimensions->add_child()->set_field(UID_PROCESS_STATE_UID_KEY);
|
||||
metric->set_condition(202);
|
||||
|
||||
// Count wake lock, slice by uid, while SCREEN_IS_ON and app in background
|
||||
metric = config.add_count_metric();
|
||||
metric->set_id(4);
|
||||
metric->set_what(107);
|
||||
metric->set_bucket(ONE_MINUTE);
|
||||
dimensions = metric->mutable_dimensions_in_what();
|
||||
dimensions->set_field(WAKE_LOCK_TAG_ID);
|
||||
dimensions->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
|
||||
|
||||
|
||||
metric->set_condition(204);
|
||||
MetricConditionLink* link = metric->add_links();
|
||||
link->set_condition(203);
|
||||
link->mutable_fields_in_what()->set_field(WAKE_LOCK_TAG_ID);
|
||||
link->mutable_fields_in_what()->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
|
||||
link->mutable_fields_in_condition()->set_field(APP_USAGE_TAG_ID);
|
||||
link->mutable_fields_in_condition()->add_child()->set_field(APP_USAGE_UID_KEY_ID);
|
||||
|
||||
// Duration of an app holding any wl, while screen on and app in background, slice by uid
|
||||
DurationMetric* durationMetric = config.add_duration_metric();
|
||||
durationMetric->set_id(5);
|
||||
durationMetric->set_bucket(ONE_MINUTE);
|
||||
durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
|
||||
dimensions = durationMetric->mutable_dimensions_in_what();
|
||||
dimensions->set_field(WAKE_LOCK_TAG_ID);
|
||||
dimensions->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
|
||||
durationMetric->set_what(205);
|
||||
durationMetric->set_condition(204);
|
||||
link = durationMetric->add_links();
|
||||
link->set_condition(203);
|
||||
link->mutable_fields_in_what()->set_field(WAKE_LOCK_TAG_ID);
|
||||
link->mutable_fields_in_what()->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
|
||||
link->mutable_fields_in_condition()->set_field(APP_USAGE_TAG_ID);
|
||||
link->mutable_fields_in_condition()->add_child()->set_field(APP_USAGE_UID_KEY_ID);
|
||||
|
||||
// max Duration of an app holding any wl, while screen on and app in background, slice by uid
|
||||
durationMetric = config.add_duration_metric();
|
||||
durationMetric->set_id(6);
|
||||
durationMetric->set_bucket(ONE_MINUTE);
|
||||
durationMetric->set_aggregation_type(DurationMetric_AggregationType_MAX_SPARSE);
|
||||
dimensions = durationMetric->mutable_dimensions_in_what();
|
||||
dimensions->set_field(WAKE_LOCK_TAG_ID);
|
||||
dimensions->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
|
||||
durationMetric->set_what(205);
|
||||
durationMetric->set_condition(204);
|
||||
link = durationMetric->add_links();
|
||||
link->set_condition(203);
|
||||
link->mutable_fields_in_what()->set_field(WAKE_LOCK_TAG_ID);
|
||||
link->mutable_fields_in_what()->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
|
||||
link->mutable_fields_in_condition()->set_field(APP_USAGE_TAG_ID);
|
||||
link->mutable_fields_in_condition()->add_child()->set_field(APP_USAGE_UID_KEY_ID);
|
||||
|
||||
// Duration of an app holding any wl, while screen on and app in background
|
||||
durationMetric = config.add_duration_metric();
|
||||
durationMetric->set_id(7);
|
||||
durationMetric->set_bucket(ONE_MINUTE);
|
||||
durationMetric->set_aggregation_type(DurationMetric_AggregationType_MAX_SPARSE);
|
||||
durationMetric->set_what(205);
|
||||
durationMetric->set_condition(204);
|
||||
link = durationMetric->add_links();
|
||||
link->set_condition(203);
|
||||
link->mutable_fields_in_what()->set_field(WAKE_LOCK_TAG_ID);
|
||||
link->mutable_fields_in_what()->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
|
||||
link->mutable_fields_in_condition()->set_field(APP_USAGE_TAG_ID);
|
||||
link->mutable_fields_in_condition()->add_child()->set_field(APP_USAGE_UID_KEY_ID);
|
||||
|
||||
|
||||
// Duration of screen on time.
|
||||
durationMetric = config.add_duration_metric();
|
||||
durationMetric->set_id(8);
|
||||
durationMetric->set_bucket(ONE_MINUTE);
|
||||
durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
|
||||
durationMetric->set_what(201);
|
||||
|
||||
// Anomaly threshold for background count.
|
||||
// TODO(b/70627390): Uncomment once the bug is fixed.
|
||||
/*
|
||||
alert = config.add_alert();
|
||||
alert->set_id(308);
|
||||
alert->set_metric_id(8);
|
||||
alert->set_number_of_buckets(4);
|
||||
alert->set_trigger_if_sum_gt(2000000000); // 2 seconds
|
||||
alert->set_refractory_period_secs(120);
|
||||
details = alert->mutable_incidentd_details();
|
||||
details->add_section(-1);*/
|
||||
|
||||
// Value metric to count KERNEL_WAKELOCK when screen turned on
|
||||
ValueMetric* valueMetric = config.add_value_metric();
|
||||
valueMetric->set_id(11);
|
||||
valueMetric->set_what(109);
|
||||
valueMetric->mutable_value_field()->set_field(KERNEL_WAKELOCK_TAG_ID);
|
||||
valueMetric->mutable_value_field()->add_child()->set_field(KERNEL_WAKELOCK_COUNT_KEY);
|
||||
valueMetric->set_condition(201);
|
||||
dimensions = valueMetric->mutable_dimensions_in_what();
|
||||
dimensions->set_field(KERNEL_WAKELOCK_TAG_ID);
|
||||
dimensions->add_child()->set_field(KERNEL_WAKELOCK_NAME_KEY);
|
||||
// This is for testing easier. We should never set bucket size this small.
|
||||
durationMetric->set_bucket(ONE_MINUTE);
|
||||
|
||||
// Add an EventMetric to log process state change events.
|
||||
EventMetric* eventMetric = config.add_event_metric();
|
||||
eventMetric->set_id(9);
|
||||
eventMetric->set_what(102); // "SCREEN_TURNED_ON"
|
||||
|
||||
// Add an GaugeMetric.
|
||||
GaugeMetric* gaugeMetric = config.add_gauge_metric();
|
||||
gaugeMetric->set_id(10);
|
||||
gaugeMetric->set_what(101);
|
||||
auto gaugeFieldMatcher = gaugeMetric->mutable_gauge_fields_filter()->mutable_fields();
|
||||
gaugeFieldMatcher->set_field(DEVICE_TEMPERATURE_TAG_ID);
|
||||
gaugeFieldMatcher->add_child()->set_field(DEVICE_TEMPERATURE_KEY);
|
||||
durationMetric->set_bucket(ONE_MINUTE);
|
||||
|
||||
// Event matchers.
|
||||
AtomMatcher* temperatureAtomMatcher = config.add_atom_matcher();
|
||||
temperatureAtomMatcher->set_id(101); // "DEVICE_TEMPERATURE"
|
||||
temperatureAtomMatcher->mutable_simple_atom_matcher()->set_atom_id(
|
||||
DEVICE_TEMPERATURE_TAG_ID);
|
||||
|
||||
AtomMatcher* eventMatcher = config.add_atom_matcher();
|
||||
eventMatcher->set_id(102); // "SCREEN_TURNED_ON"
|
||||
SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
|
||||
simpleAtomMatcher->set_atom_id(SCREEN_EVENT_TAG_ID);
|
||||
FieldValueMatcher* fieldValueMatcher = simpleAtomMatcher->add_field_value_matcher();
|
||||
fieldValueMatcher->set_field(SCREEN_EVENT_STATE_KEY);
|
||||
fieldValueMatcher->set_eq_int(SCREEN_EVENT_ON_VALUE);
|
||||
|
||||
eventMatcher = config.add_atom_matcher();
|
||||
eventMatcher->set_id(103); // "SCREEN_TURNED_OFF"
|
||||
simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
|
||||
simpleAtomMatcher->set_atom_id(SCREEN_EVENT_TAG_ID);
|
||||
fieldValueMatcher = simpleAtomMatcher->add_field_value_matcher();
|
||||
fieldValueMatcher->set_field(SCREEN_EVENT_STATE_KEY);
|
||||
fieldValueMatcher->set_eq_int(SCREEN_EVENT_OFF_VALUE);
|
||||
|
||||
eventMatcher = config.add_atom_matcher();
|
||||
eventMatcher->set_id(104); // "PROCESS_STATE_CHANGE"
|
||||
simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
|
||||
simpleAtomMatcher->set_atom_id(UID_PROCESS_STATE_TAG_ID);
|
||||
|
||||
eventMatcher = config.add_atom_matcher();
|
||||
eventMatcher->set_id(105); // "APP_GOES_BACKGROUND"
|
||||
simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
|
||||
simpleAtomMatcher->set_atom_id(APP_USAGE_TAG_ID);
|
||||
fieldValueMatcher = simpleAtomMatcher->add_field_value_matcher();
|
||||
fieldValueMatcher->set_field(APP_USAGE_STATE_KEY);
|
||||
fieldValueMatcher->set_eq_int(APP_USAGE_BACKGROUND);
|
||||
|
||||
eventMatcher = config.add_atom_matcher();
|
||||
eventMatcher->set_id(106); // "APP_GOES_FOREGROUND"
|
||||
simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
|
||||
simpleAtomMatcher->set_atom_id(APP_USAGE_TAG_ID);
|
||||
fieldValueMatcher = simpleAtomMatcher->add_field_value_matcher();
|
||||
fieldValueMatcher->set_field(APP_USAGE_STATE_KEY);
|
||||
fieldValueMatcher->set_eq_int(APP_USAGE_FOREGROUND);
|
||||
|
||||
eventMatcher = config.add_atom_matcher();
|
||||
eventMatcher->set_id(107); // "APP_GET_WL"
|
||||
simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
|
||||
simpleAtomMatcher->set_atom_id(WAKE_LOCK_TAG_ID);
|
||||
fieldValueMatcher = simpleAtomMatcher->add_field_value_matcher();
|
||||
fieldValueMatcher->set_field(WAKE_LOCK_STATE_KEY);
|
||||
fieldValueMatcher->set_eq_int(WAKE_LOCK_ACQUIRE_VALUE);
|
||||
|
||||
eventMatcher = config.add_atom_matcher();
|
||||
eventMatcher->set_id(108); //"APP_RELEASE_WL"
|
||||
simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
|
||||
simpleAtomMatcher->set_atom_id(WAKE_LOCK_TAG_ID);
|
||||
fieldValueMatcher = simpleAtomMatcher->add_field_value_matcher();
|
||||
fieldValueMatcher->set_field(WAKE_LOCK_STATE_KEY);
|
||||
fieldValueMatcher->set_eq_int(WAKE_LOCK_RELEASE_VALUE);
|
||||
|
||||
// pulled events
|
||||
eventMatcher = config.add_atom_matcher();
|
||||
eventMatcher->set_id(109); // "KERNEL_WAKELOCK"
|
||||
simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
|
||||
simpleAtomMatcher->set_atom_id(KERNEL_WAKELOCK_TAG_ID);
|
||||
|
||||
// Predicates.............
|
||||
Predicate* predicate = config.add_predicate();
|
||||
predicate->set_id(201); // "SCREEN_IS_ON"
|
||||
SimplePredicate* simplePredicate = predicate->mutable_simple_predicate();
|
||||
simplePredicate->set_start(102); // "SCREEN_TURNED_ON"
|
||||
simplePredicate->set_stop(103);
|
||||
simplePredicate->set_count_nesting(false);
|
||||
|
||||
predicate = config.add_predicate();
|
||||
predicate->set_id(202); // "SCREEN_IS_OFF"
|
||||
simplePredicate = predicate->mutable_simple_predicate();
|
||||
simplePredicate->set_start(103);
|
||||
simplePredicate->set_stop(102); // "SCREEN_TURNED_ON"
|
||||
simplePredicate->set_count_nesting(false);
|
||||
|
||||
predicate = config.add_predicate();
|
||||
predicate->set_id(203); // "APP_IS_BACKGROUND"
|
||||
simplePredicate = predicate->mutable_simple_predicate();
|
||||
simplePredicate->set_start(105);
|
||||
simplePredicate->set_stop(106);
|
||||
FieldMatcher* predicate_dimension1 = simplePredicate->mutable_dimensions();
|
||||
predicate_dimension1->set_field(APP_USAGE_TAG_ID);
|
||||
predicate_dimension1->add_child()->set_field(APP_USAGE_UID_KEY_ID);
|
||||
simplePredicate->set_count_nesting(false);
|
||||
|
||||
predicate = config.add_predicate();
|
||||
predicate->set_id(204); // "APP_IS_BACKGROUND_AND_SCREEN_ON"
|
||||
Predicate_Combination* combination_predicate = predicate->mutable_combination();
|
||||
combination_predicate->set_operation(LogicalOperation::AND);
|
||||
combination_predicate->add_predicate(203);
|
||||
combination_predicate->add_predicate(201);
|
||||
|
||||
predicate = config.add_predicate();
|
||||
predicate->set_id(205); // "WL_HELD_PER_APP_PER_NAME"
|
||||
simplePredicate = predicate->mutable_simple_predicate();
|
||||
simplePredicate->set_start(107);
|
||||
simplePredicate->set_stop(108);
|
||||
FieldMatcher* predicate_dimension = simplePredicate->mutable_dimensions();
|
||||
predicate_dimension1->set_field(WAKE_LOCK_TAG_ID);
|
||||
predicate_dimension->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
|
||||
predicate_dimension->add_child()->set_field(WAKE_LOCK_NAME_KEY);
|
||||
simplePredicate->set_count_nesting(true);
|
||||
|
||||
predicate = config.add_predicate();
|
||||
predicate->set_id(206); // "WL_HELD_PER_APP"
|
||||
simplePredicate = predicate->mutable_simple_predicate();
|
||||
simplePredicate->set_start(107);
|
||||
simplePredicate->set_stop(108);
|
||||
simplePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
|
||||
predicate_dimension = simplePredicate->mutable_dimensions();
|
||||
predicate_dimension->set_field(WAKE_LOCK_TAG_ID);
|
||||
predicate_dimension->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
|
||||
simplePredicate->set_count_nesting(true);
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
} // namespace statsd
|
||||
} // namespace os
|
||||
} // namespace android
|
||||
|
||||
@@ -117,7 +117,8 @@ void CountMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
|
||||
}
|
||||
}
|
||||
|
||||
void CountMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eventTime) {
|
||||
void CountMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
|
||||
const uint64_t eventTime) {
|
||||
VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ private:
|
||||
void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
|
||||
|
||||
// Internal interface to handle sliced condition change.
|
||||
void onSlicedConditionMayChangeLocked(const uint64_t eventTime) override;
|
||||
void onSlicedConditionMayChangeLocked(bool overallCondition, const uint64_t eventTime) override;
|
||||
|
||||
// Internal function to calculate the current used bytes.
|
||||
size_t byteSizeLocked() const override;
|
||||
|
||||
@@ -169,7 +169,8 @@ unique_ptr<DurationTracker> DurationMetricProducer::createDurationTracker(
|
||||
// 1. If combination condition, logical operation is AND, only one sliced child predicate.
|
||||
// 2. No condition in dimension
|
||||
// 3. The links covers all dimension fields in the sliced child condition predicate.
|
||||
void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt1(const uint64_t eventTime) {
|
||||
void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt1(bool condition,
|
||||
const uint64_t eventTime) {
|
||||
if (mMetric2ConditionLinks.size() != 1 ||
|
||||
!mHasLinksToAllConditionDimensionsInTracker ||
|
||||
!mDimensionsInCondition.empty()) {
|
||||
@@ -241,7 +242,8 @@ void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt1(const uint64_
|
||||
// SlicedConditionChange optimization case 2:
|
||||
// 1. If combination condition, logical operation is AND, only one sliced child predicate.
|
||||
// 2. Has dimensions_in_condition and it equals to the output dimensions of the sliced predicate.
|
||||
void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt2(const uint64_t eventTime) {
|
||||
void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt2(bool condition,
|
||||
const uint64_t eventTime) {
|
||||
if (mMetric2ConditionLinks.size() > 1 || !mSameConditionDimensionsInTracker) {
|
||||
return;
|
||||
}
|
||||
@@ -322,7 +324,8 @@ void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt2(const uint64_
|
||||
}
|
||||
}
|
||||
|
||||
void DurationMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eventTime) {
|
||||
void DurationMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
|
||||
const uint64_t eventTime) {
|
||||
VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
|
||||
flushIfNeededLocked(eventTime);
|
||||
|
||||
@@ -333,20 +336,20 @@ void DurationMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eve
|
||||
bool changeDimTrackable = mWizard->IsChangedDimensionTrackable(mConditionTrackerIndex);
|
||||
if (changeDimTrackable && mHasLinksToAllConditionDimensionsInTracker &&
|
||||
mDimensionsInCondition.empty()) {
|
||||
onSlicedConditionMayChangeLocked_opt1(eventTime);
|
||||
onSlicedConditionMayChangeLocked_opt1(overallCondition, eventTime);
|
||||
return;
|
||||
}
|
||||
|
||||
if (changeDimTrackable && mSameConditionDimensionsInTracker &&
|
||||
mMetric2ConditionLinks.size() <= 1) {
|
||||
onSlicedConditionMayChangeLocked_opt2(eventTime);
|
||||
onSlicedConditionMayChangeLocked_opt2(overallCondition, eventTime);
|
||||
return;
|
||||
}
|
||||
|
||||
// Now for each of the on-going event, check if the condition has changed for them.
|
||||
for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
|
||||
for (auto& pair : whatIt.second) {
|
||||
pair.second->onSlicedConditionMayChange(eventTime);
|
||||
pair.second->onSlicedConditionMayChange(overallCondition, eventTime);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,7 +375,7 @@ void DurationMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eve
|
||||
if (newTracker != nullptr) {
|
||||
newTracker->setEventKey(MetricDimensionKey(
|
||||
whatIt.first, conditionDimension));
|
||||
newTracker->onSlicedConditionMayChange(eventTime);
|
||||
newTracker->onSlicedConditionMayChange(overallCondition, eventTime);
|
||||
whatIt.second[conditionDimension] = std::move(newTracker);
|
||||
}
|
||||
}
|
||||
@@ -398,7 +401,7 @@ void DurationMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eve
|
||||
if (newTracker != nullptr) {
|
||||
newTracker->setEventKey(
|
||||
MetricDimensionKey(whatIt.first, conditionDimension));
|
||||
newTracker->onSlicedConditionMayChange(eventTime);
|
||||
newTracker->onSlicedConditionMayChange(overallCondition, eventTime);
|
||||
whatIt.second[conditionDimension] = std::move(newTracker);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,10 +68,10 @@ private:
|
||||
void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
|
||||
|
||||
// Internal interface to handle sliced condition change.
|
||||
void onSlicedConditionMayChangeLocked(const uint64_t eventTime) override;
|
||||
void onSlicedConditionMayChangeLocked(bool overallCondition, const uint64_t eventTime) override;
|
||||
|
||||
void onSlicedConditionMayChangeLocked_opt1(const uint64_t eventTime);
|
||||
void onSlicedConditionMayChangeLocked_opt2(const uint64_t eventTime);
|
||||
void onSlicedConditionMayChangeLocked_opt1(bool overallCondition, const uint64_t eventTime);
|
||||
void onSlicedConditionMayChangeLocked_opt2(bool overallCondition, const uint64_t eventTime);
|
||||
|
||||
// Internal function to calculate the current used bytes.
|
||||
size_t byteSizeLocked() const override;
|
||||
|
||||
@@ -79,7 +79,8 @@ void EventMetricProducer::dropDataLocked(const uint64_t dropTimeNs) {
|
||||
mProto->clear();
|
||||
}
|
||||
|
||||
void EventMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eventTime) {
|
||||
void EventMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
|
||||
const uint64_t eventTime) {
|
||||
}
|
||||
|
||||
std::unique_ptr<std::vector<uint8_t>> serializeProtoLocked(ProtoOutputStream& protoOutput) {
|
||||
|
||||
@@ -53,7 +53,7 @@ private:
|
||||
void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
|
||||
|
||||
// Internal interface to handle sliced condition change.
|
||||
void onSlicedConditionMayChangeLocked(const uint64_t eventTime) override;
|
||||
void onSlicedConditionMayChangeLocked(bool overallCondition, const uint64_t eventTime) override;
|
||||
|
||||
void dropDataLocked(const uint64_t dropTimeNs) override;
|
||||
|
||||
|
||||
@@ -115,8 +115,9 @@ GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric
|
||||
mStatsPullerManager->RegisterReceiver(mPullTagId, this, bucketSizeMills);
|
||||
}
|
||||
|
||||
VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
|
||||
(long long)mBucketSizeNs, (long long)mStartTimeNs);
|
||||
VLOG("Gauge metric %lld created. bucket size %lld start_time: %lld sliced %d",
|
||||
(long long)metric.id(), (long long)mBucketSizeNs, (long long)mStartTimeNs,
|
||||
mConditionSliced);
|
||||
}
|
||||
|
||||
// for testing
|
||||
@@ -155,7 +156,7 @@ void GaugeMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
|
||||
|
||||
void GaugeMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
|
||||
ProtoOutputStream* protoOutput) {
|
||||
VLOG("gauge metric %lld report now...", (long long)mMetricId);
|
||||
VLOG("Gauge metric %lld report now...", (long long)mMetricId);
|
||||
|
||||
flushIfNeededLocked(dumpTimeNs);
|
||||
if (mPastBuckets.empty()) {
|
||||
@@ -168,7 +169,7 @@ void GaugeMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
|
||||
for (const auto& pair : mPastBuckets) {
|
||||
const MetricDimensionKey& dimensionKey = pair.first;
|
||||
|
||||
VLOG(" dimension key %s", dimensionKey.toString().c_str());
|
||||
VLOG("Gauge dimension key %s", dimensionKey.toString().c_str());
|
||||
uint64_t wrapperToken =
|
||||
protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
|
||||
|
||||
@@ -221,8 +222,9 @@ void GaugeMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
|
||||
}
|
||||
}
|
||||
protoOutput->end(bucketInfoToken);
|
||||
VLOG("\t bucket [%lld - %lld] includes %d atoms.", (long long)bucket.mBucketStartNs,
|
||||
(long long)bucket.mBucketEndNs, (int)bucket.mGaugeAtoms.size());
|
||||
VLOG("Gauge \t bucket [%lld - %lld] includes %d atoms.",
|
||||
(long long)bucket.mBucketStartNs, (long long)bucket.mBucketEndNs,
|
||||
(int)bucket.mGaugeAtoms.size());
|
||||
}
|
||||
protoOutput->end(wrapperToken);
|
||||
}
|
||||
@@ -233,27 +235,6 @@ void GaugeMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
|
||||
}
|
||||
|
||||
void GaugeMetricProducer::pullLocked() {
|
||||
vector<std::shared_ptr<LogEvent>> allData;
|
||||
if (!mStatsPullerManager->Pull(mPullTagId, &allData)) {
|
||||
ALOGE("Stats puller failed for tag: %d", mPullTagId);
|
||||
return;
|
||||
}
|
||||
for (const auto& data : allData) {
|
||||
onMatchedLogEventLocked(0, *data);
|
||||
}
|
||||
}
|
||||
|
||||
void GaugeMetricProducer::onConditionChangedLocked(const bool conditionMet,
|
||||
const uint64_t eventTime) {
|
||||
VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
|
||||
flushIfNeededLocked(eventTime);
|
||||
mCondition = conditionMet;
|
||||
|
||||
// Push mode. No need to proactively pull the gauge data.
|
||||
if (mPullTagId == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool triggerPuller = false;
|
||||
switch(mSamplingType) {
|
||||
// When the metric wants to do random sampling and there is already one gauge atom for the
|
||||
@@ -275,17 +256,37 @@ void GaugeMetricProducer::onConditionChangedLocked(const bool conditionMet,
|
||||
|
||||
vector<std::shared_ptr<LogEvent>> allData;
|
||||
if (!mStatsPullerManager->Pull(mPullTagId, &allData)) {
|
||||
ALOGE("Stats puller failed for tag: %d", mPullTagId);
|
||||
ALOGE("Gauge Stats puller failed for tag: %d", mPullTagId);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& data : allData) {
|
||||
onMatchedLogEventLocked(0, *data);
|
||||
}
|
||||
flushIfNeededLocked(eventTime);
|
||||
}
|
||||
|
||||
void GaugeMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eventTime) {
|
||||
VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
|
||||
void GaugeMetricProducer::onConditionChangedLocked(const bool conditionMet,
|
||||
const uint64_t eventTime) {
|
||||
VLOG("GaugeMetric %lld onConditionChanged", (long long)mMetricId);
|
||||
flushIfNeededLocked(eventTime);
|
||||
mCondition = conditionMet;
|
||||
|
||||
if (mPullTagId != -1) {
|
||||
pullLocked();
|
||||
} // else: Push mode. No need to proactively pull the gauge data.
|
||||
}
|
||||
|
||||
void GaugeMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
|
||||
const uint64_t eventTime) {
|
||||
VLOG("GaugeMetric %lld onSlicedConditionMayChange overall condition %d", (long long)mMetricId,
|
||||
overallCondition);
|
||||
flushIfNeededLocked(eventTime);
|
||||
// If the condition is sliced, mCondition is true if any of the dimensions is true. And we will
|
||||
// pull for every dimension.
|
||||
mCondition = overallCondition;
|
||||
if (mPullTagId != -1) {
|
||||
pullLocked();
|
||||
} // else: Push mode. No need to proactively pull the gauge data.
|
||||
}
|
||||
|
||||
std::shared_ptr<vector<FieldValue>> GaugeMetricProducer::getGaugeFields(const LogEvent& event) {
|
||||
@@ -337,7 +338,7 @@ void GaugeMetricProducer::onMatchedLogEventInternalLocked(
|
||||
uint64_t eventTimeNs = event.GetElapsedTimestampNs();
|
||||
mTagId = event.GetTagId();
|
||||
if (eventTimeNs < mCurrentBucketStartTimeNs) {
|
||||
VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
|
||||
VLOG("Gauge Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
|
||||
(long long)mCurrentBucketStartTimeNs);
|
||||
return;
|
||||
}
|
||||
@@ -403,8 +404,8 @@ void GaugeMetricProducer::flushIfNeededLocked(const uint64_t& eventTimeNs) {
|
||||
uint64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
|
||||
|
||||
if (eventTimeNs < currentBucketEndTimeNs) {
|
||||
VLOG("eventTime is %lld, less than next bucket start time %lld", (long long)eventTimeNs,
|
||||
(long long)(mCurrentBucketStartTimeNs + mBucketSizeNs));
|
||||
VLOG("Gauge eventTime is %lld, less than next bucket start time %lld",
|
||||
(long long)eventTimeNs, (long long)(mCurrentBucketStartTimeNs + mBucketSizeNs));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -414,7 +415,7 @@ void GaugeMetricProducer::flushIfNeededLocked(const uint64_t& eventTimeNs) {
|
||||
int64_t numBucketsForward = 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
|
||||
mCurrentBucketStartTimeNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
|
||||
mCurrentBucketNum += numBucketsForward;
|
||||
VLOG("metric %lld: new bucket start time: %lld", (long long)mMetricId,
|
||||
VLOG("Gauge metric %lld: new bucket start time: %lld", (long long)mMetricId,
|
||||
(long long)mCurrentBucketStartTimeNs);
|
||||
}
|
||||
|
||||
@@ -433,7 +434,7 @@ void GaugeMetricProducer::flushCurrentBucketLocked(const uint64_t& eventTimeNs)
|
||||
info.mGaugeAtoms = slice.second;
|
||||
auto& bucketList = mPastBuckets[slice.first];
|
||||
bucketList.push_back(info);
|
||||
VLOG("gauge metric %lld, dump key value: %s", (long long)mMetricId,
|
||||
VLOG("Gauge gauge metric %lld, dump key value: %s", (long long)mMetricId,
|
||||
slice.first.toString().c_str());
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ private:
|
||||
void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
|
||||
|
||||
// Internal interface to handle sliced condition change.
|
||||
void onSlicedConditionMayChangeLocked(const uint64_t eventTime) override;
|
||||
void onSlicedConditionMayChangeLocked(bool overallCondition, const uint64_t eventTime) override;
|
||||
|
||||
// Internal function to calculate the current used bytes.
|
||||
size_t byteSizeLocked() const override;
|
||||
@@ -155,6 +155,7 @@ private:
|
||||
const size_t mDimensionHardLimit;
|
||||
|
||||
FRIEND_TEST(GaugeMetricProducerTest, TestWithCondition);
|
||||
FRIEND_TEST(GaugeMetricProducerTest, TestWithSlicedCondition);
|
||||
FRIEND_TEST(GaugeMetricProducerTest, TestNoCondition);
|
||||
FRIEND_TEST(GaugeMetricProducerTest, TestPushedEventsWithUpgrade);
|
||||
FRIEND_TEST(GaugeMetricProducerTest, TestPulledWithUpgrade);
|
||||
|
||||
@@ -33,7 +33,6 @@ void MetricProducer::onMatchedLogEventLocked(const size_t matcherIndex, const Lo
|
||||
|
||||
bool condition;
|
||||
ConditionKey conditionKey;
|
||||
|
||||
std::unordered_set<HashableDimensionKey> dimensionKeysInCondition;
|
||||
if (mConditionSliced) {
|
||||
for (const auto& link : mMetric2ConditionLinks) {
|
||||
|
||||
@@ -98,9 +98,9 @@ public:
|
||||
onConditionChangedLocked(condition, eventTime);
|
||||
}
|
||||
|
||||
void onSlicedConditionMayChange(const uint64_t eventTime) {
|
||||
void onSlicedConditionMayChange(bool overallCondition, const uint64_t eventTime) {
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
onSlicedConditionMayChangeLocked(eventTime);
|
||||
onSlicedConditionMayChangeLocked(overallCondition, eventTime);
|
||||
}
|
||||
|
||||
bool isConditionSliced() const {
|
||||
@@ -163,7 +163,8 @@ public:
|
||||
|
||||
protected:
|
||||
virtual void onConditionChangedLocked(const bool condition, const uint64_t eventTime) = 0;
|
||||
virtual void onSlicedConditionMayChangeLocked(const uint64_t eventTime) = 0;
|
||||
virtual void onSlicedConditionMayChangeLocked(bool overallCondition,
|
||||
const uint64_t eventTime) = 0;
|
||||
virtual void onDumpReportLocked(const uint64_t dumpTimeNs,
|
||||
android::util::ProtoOutputStream* protoOutput) = 0;
|
||||
virtual size_t byteSizeLocked() const = 0;
|
||||
|
||||
@@ -326,7 +326,8 @@ void MetricsManager::onLogEvent(const LogEvent& event) {
|
||||
// notification, and the metric can query the sliced conditions that are
|
||||
// interesting to it.
|
||||
} else {
|
||||
mAllMetricProducers[metricIndex]->onSlicedConditionMayChange(eventTime);
|
||||
mAllMetricProducers[metricIndex]->onSlicedConditionMayChange(conditionCache[i],
|
||||
eventTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +134,8 @@ ValueMetricProducer::~ValueMetricProducer() {
|
||||
}
|
||||
}
|
||||
|
||||
void ValueMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eventTime) {
|
||||
void ValueMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
|
||||
const uint64_t eventTime) {
|
||||
VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ private:
|
||||
void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
|
||||
|
||||
// Internal interface to handle sliced condition change.
|
||||
void onSlicedConditionMayChangeLocked(const uint64_t eventTime) override;
|
||||
void onSlicedConditionMayChangeLocked(bool overallCondition, const uint64_t eventTime) override;
|
||||
|
||||
// Internal function to calculate the current used bytes.
|
||||
size_t byteSizeLocked() const override;
|
||||
|
||||
@@ -92,7 +92,7 @@ public:
|
||||
const bool stopAll) = 0;
|
||||
virtual void noteStopAll(const uint64_t eventTime) = 0;
|
||||
|
||||
virtual void onSlicedConditionMayChange(const uint64_t timestamp) = 0;
|
||||
virtual void onSlicedConditionMayChange(bool overallCondition, const uint64_t timestamp) = 0;
|
||||
virtual void onConditionChanged(bool condition, const uint64_t timestamp) = 0;
|
||||
|
||||
// Flush stale buckets if needed, and return true if the tracker has no on-going duration
|
||||
|
||||
@@ -245,7 +245,8 @@ bool MaxDurationTracker::flushIfNeeded(
|
||||
return flushCurrentBucket(eventTimeNs, output);
|
||||
}
|
||||
|
||||
void MaxDurationTracker::onSlicedConditionMayChange(const uint64_t timestamp) {
|
||||
void MaxDurationTracker::onSlicedConditionMayChange(bool overallCondition,
|
||||
const uint64_t timestamp) {
|
||||
// Now for each of the on-going event, check if the condition has changed for them.
|
||||
for (auto& pair : mInfos) {
|
||||
if (pair.second.state == kStopped) {
|
||||
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
const uint64_t& eventTimeNs,
|
||||
std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>*) override;
|
||||
|
||||
void onSlicedConditionMayChange(const uint64_t timestamp) override;
|
||||
void onSlicedConditionMayChange(bool overallCondition, const uint64_t timestamp) override;
|
||||
void onConditionChanged(bool condition, const uint64_t timestamp) override;
|
||||
|
||||
int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
|
||||
|
||||
@@ -214,7 +214,8 @@ bool OringDurationTracker::flushIfNeeded(
|
||||
return flushCurrentBucket(eventTimeNs, output);
|
||||
}
|
||||
|
||||
void OringDurationTracker::onSlicedConditionMayChange(const uint64_t timestamp) {
|
||||
void OringDurationTracker::onSlicedConditionMayChange(bool overallCondition,
|
||||
const uint64_t timestamp) {
|
||||
vector<pair<HashableDimensionKey, int>> startedToPaused;
|
||||
vector<pair<HashableDimensionKey, int>> pausedToStarted;
|
||||
if (!mStarted.empty()) {
|
||||
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
const bool stopAll) override;
|
||||
void noteStopAll(const uint64_t eventTime) override;
|
||||
|
||||
void onSlicedConditionMayChange(const uint64_t timestamp) override;
|
||||
void onSlicedConditionMayChange(bool overallCondition, const uint64_t timestamp) override;
|
||||
void onConditionChanged(bool condition, const uint64_t timestamp) override;
|
||||
|
||||
bool flushCurrentBucket(
|
||||
|
||||
@@ -64,16 +64,6 @@ MATCHER_P(StatsdConfigEq, id, 0) {
|
||||
|
||||
const int64_t testConfigId = 12345;
|
||||
|
||||
TEST(ConfigManagerTest, TestFakeConfig) {
|
||||
auto metricsManager = std::make_unique<MetricsManager>(
|
||||
ConfigKey(0, testConfigId), build_fake_config(), 1000, new UidMap(),
|
||||
new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t){},
|
||||
[](const sp<IStatsCompanionService>&){}),
|
||||
new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t){},
|
||||
[](const sp<IStatsCompanionService>&){}));
|
||||
EXPECT_TRUE(metricsManager->isConfigValid());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the addOrUpdate and remove methods
|
||||
*/
|
||||
|
||||
@@ -338,6 +338,82 @@ TEST(GaugeMetricProducerTest, TestWithCondition) {
|
||||
->mValue.int_value);
|
||||
}
|
||||
|
||||
TEST(GaugeMetricProducerTest, TestWithSlicedCondition) {
|
||||
const int conditionTag = 65;
|
||||
GaugeMetric metric;
|
||||
metric.set_id(1111111);
|
||||
metric.set_bucket(ONE_MINUTE);
|
||||
metric.mutable_gauge_fields_filter()->set_include_all(true);
|
||||
metric.set_condition(StringToId("APP_DIED"));
|
||||
auto dim = metric.mutable_dimensions_in_what();
|
||||
dim->set_field(tagId);
|
||||
dim->add_child()->set_field(1);
|
||||
|
||||
dim = metric.mutable_dimensions_in_condition();
|
||||
dim->set_field(conditionTag);
|
||||
dim->add_child()->set_field(1);
|
||||
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
EXPECT_CALL(*wizard, query(_, _, _, _, _, _))
|
||||
.WillRepeatedly(
|
||||
Invoke([](const int conditionIndex, const ConditionKey& conditionParameters,
|
||||
const vector<Matcher>& dimensionFields, const bool isSubsetDim,
|
||||
const bool isPartialLink,
|
||||
std::unordered_set<HashableDimensionKey>* dimensionKeySet) {
|
||||
dimensionKeySet->clear();
|
||||
int pos[] = {1, 0, 0};
|
||||
Field f(conditionTag, pos, 0);
|
||||
HashableDimensionKey key;
|
||||
key.mutableValues()->emplace_back(f, Value((int32_t)1000000));
|
||||
dimensionKeySet->insert(key);
|
||||
|
||||
return ConditionState::kTrue;
|
||||
}));
|
||||
|
||||
shared_ptr<MockStatsPullerManager> pullerManager =
|
||||
make_shared<StrictMock<MockStatsPullerManager>>();
|
||||
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _)).WillOnce(Return());
|
||||
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
|
||||
EXPECT_CALL(*pullerManager, Pull(tagId, _))
|
||||
.WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
|
||||
data->clear();
|
||||
shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
|
||||
event->write(1000);
|
||||
event->write(100);
|
||||
event->init();
|
||||
data->push_back(event);
|
||||
return true;
|
||||
}));
|
||||
|
||||
GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
|
||||
pullerManager);
|
||||
gaugeProducer.setBucketSize(60 * NS_PER_SEC);
|
||||
|
||||
gaugeProducer.onSlicedConditionMayChange(true, bucketStartTimeNs + 8);
|
||||
|
||||
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
|
||||
const auto& key = gaugeProducer.mCurrentSlicedBucket->begin()->first;
|
||||
EXPECT_EQ(1UL, key.getDimensionKeyInWhat().getValues().size());
|
||||
EXPECT_EQ(1000, key.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
|
||||
|
||||
EXPECT_EQ(1UL, key.getDimensionKeyInCondition().getValues().size());
|
||||
EXPECT_EQ(1000000, key.getDimensionKeyInCondition().getValues()[0].mValue.int_value);
|
||||
|
||||
EXPECT_EQ(0UL, gaugeProducer.mPastBuckets.size());
|
||||
|
||||
vector<shared_ptr<LogEvent>> allData;
|
||||
allData.clear();
|
||||
shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
|
||||
event->write(1000);
|
||||
event->write(110);
|
||||
event->init();
|
||||
allData.push_back(event);
|
||||
gaugeProducer.onDataPulled(allData);
|
||||
|
||||
EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
|
||||
EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
|
||||
}
|
||||
|
||||
TEST(GaugeMetricProducerTest, TestAnomalyDetection) {
|
||||
sp<AlarmMonitor> alarmMonitor;
|
||||
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
|
||||
|
||||
@@ -209,7 +209,7 @@ TEST(OringDurationTrackerTest, TestDurationConditionChange) {
|
||||
|
||||
tracker.noteStart(kEventKey1, true, eventStartTimeNs, key1);
|
||||
|
||||
tracker.onSlicedConditionMayChange(eventStartTimeNs + 5);
|
||||
tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 5);
|
||||
|
||||
tracker.noteStop(kEventKey1, eventStartTimeNs + durationTimeNs, false);
|
||||
|
||||
@@ -249,9 +249,9 @@ TEST(OringDurationTrackerTest, TestDurationConditionChange2) {
|
||||
|
||||
tracker.noteStart(kEventKey1, true, eventStartTimeNs, key1);
|
||||
// condition to false; record duration 5n
|
||||
tracker.onSlicedConditionMayChange(eventStartTimeNs + 5);
|
||||
tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 5);
|
||||
// condition to true.
|
||||
tracker.onSlicedConditionMayChange(eventStartTimeNs + 1000);
|
||||
tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 1000);
|
||||
// 2nd duration: 1000ns
|
||||
tracker.noteStop(kEventKey1, eventStartTimeNs + durationTimeNs, false);
|
||||
|
||||
@@ -291,7 +291,7 @@ TEST(OringDurationTrackerTest, TestDurationConditionChangeNested) {
|
||||
|
||||
tracker.noteStop(kEventKey1, eventStartTimeNs + 3, false);
|
||||
|
||||
tracker.onSlicedConditionMayChange(eventStartTimeNs + 15);
|
||||
tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 15);
|
||||
|
||||
tracker.noteStop(kEventKey1, eventStartTimeNs + 2003, false);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user