Pass in event time when notifying listeners of a state change
Add an event time parameter to onStateChanged. Value and Duration
metrics need the event time for aggregation.
Test: bit statsd_test:*
Change-Id: I73c7a16de158de43bd9fbeb26ab8f0c32559a4a2
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index c29b32c..c1f95ee 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -121,10 +121,12 @@
VLOG("~CountMetricProducer() called");
}
-void CountMetricProducer::onStateChanged(int atomId, const HashableDimensionKey& primaryKey,
- int oldState, int newState) {
- VLOG("CountMetric %lld onStateChanged State%d, key %s, %d -> %d", (long long)mMetricId, atomId,
- primaryKey.toString().c_str(), oldState, newState);
+void CountMetricProducer::onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
+ const HashableDimensionKey& primaryKey, int oldState,
+ int newState) {
+ VLOG("CountMetric %lld onStateChanged time %lld, State%d, key %s, %d -> %d",
+ (long long)mMetricId, (long long)eventTimeNs, atomId, primaryKey.toString().c_str(),
+ oldState, newState);
}
void CountMetricProducer::dumpStatesLocked(FILE* out, bool verbose) const {
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index 8b17d88..7b6c7e0 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -52,7 +52,8 @@
virtual ~CountMetricProducer();
- void onStateChanged(int32_t atomId, const HashableDimensionKey& primaryKey, int oldState,
+ void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
+ const HashableDimensionKey& primaryKey, int oldState,
int newState) override;
protected:
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index a513db6..3512f18 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -149,8 +149,8 @@
return mConditionSliced;
};
- void onStateChanged(int atomId, const HashableDimensionKey& primaryKey, int oldState,
- int newState){};
+ void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
+ const HashableDimensionKey& primaryKey, int oldState, int newState){};
// Output the metrics data to [protoOutput]. All metrics reports end with the same timestamp.
// This method clears all the past buckets.
diff --git a/cmds/statsd/src/state/StateListener.h b/cmds/statsd/src/state/StateListener.h
index f2b9a6b..d1af196 100644
--- a/cmds/statsd/src/state/StateListener.h
+++ b/cmds/statsd/src/state/StateListener.h
@@ -38,13 +38,15 @@
* state groups and are responsible for mapping original state values to
* the correct state group.
*
+ * [eventTimeNs]: Time of the state change log event.
* [atomId]: The id of the state atom
* [primaryKey]: The primary field values of the state atom
* [oldState]: Previous state value before state change
* [newState]: Current state value after state change
*/
- virtual void onStateChanged(int32_t atomId, const HashableDimensionKey& primaryKey,
- int oldState, int newState) = 0;
+ virtual void onStateChanged(const int64_t eventTimeNs, const int32_t atomId,
+ const HashableDimensionKey& primaryKey, int oldState,
+ int newState) = 0;
};
} // namespace statsd
diff --git a/cmds/statsd/src/state/StateTracker.cpp b/cmds/statsd/src/state/StateTracker.cpp
index e6f6122..90ce1e9 100644
--- a/cmds/statsd/src/state/StateTracker.cpp
+++ b/cmds/statsd/src/state/StateTracker.cpp
@@ -38,49 +38,51 @@
}
void StateTracker::onLogEvent(const LogEvent& event) {
- // parse event for primary field values i.e. primary key
+ int64_t eventTimeNs = event.GetElapsedTimestampNs();
+
+ // Parse event for primary field values i.e. primary key.
HashableDimensionKey primaryKey;
if (mPrimaryFields.size() > 0) {
if (!filterValues(mPrimaryFields, event.getValues(), &primaryKey) ||
primaryKey.getValues().size() != mPrimaryFields.size()) {
ALOGE("StateTracker error extracting primary key from log event.");
- handleReset();
+ handleReset(eventTimeNs);
return;
}
} else {
- // atom has no primary fields
+ // Use an empty HashableDimensionKey if atom has no primary fields.
primaryKey = DEFAULT_DIMENSION_KEY;
}
- // parse event for state value
+ // Parse event for state value.
FieldValue stateValue;
int32_t state;
if (!filterValues(mStateField, event.getValues(), &stateValue) ||
stateValue.mValue.getType() != INT) {
ALOGE("StateTracker error extracting state from log event. Type: %d",
stateValue.mValue.getType());
- handlePartialReset(primaryKey);
+ handlePartialReset(eventTimeNs, primaryKey);
return;
}
state = stateValue.mValue.int_value;
if (state == mResetState) {
VLOG("StateTracker Reset state: %s", stateValue.mValue.toString().c_str());
- handleReset();
+ handleReset(eventTimeNs);
}
- // track and update state
+ // Track and update state.
int32_t oldState = 0;
int32_t newState = 0;
updateState(primaryKey, state, &oldState, &newState);
- // notify all listeners if state has changed
+ // Notify all listeners if state has changed.
if (oldState != newState) {
VLOG("StateTracker updated state");
for (auto listener : mListeners) {
auto sListener = listener.promote(); // safe access to wp<>
if (sListener != nullptr) {
- sListener->onStateChanged(mAtomId, primaryKey, oldState, newState);
+ sListener->onStateChanged(eventTimeNs, mAtomId, primaryKey, oldState, newState);
}
}
} else {
@@ -119,20 +121,22 @@
return false;
}
-void StateTracker::handleReset() {
+void StateTracker::handleReset(const int64_t eventTimeNs) {
VLOG("StateTracker handle reset");
for (const auto pair : mStateMap) {
for (auto l : mListeners) {
auto sl = l.promote();
if (sl != nullptr) {
- sl->onStateChanged(mAtomId, pair.first, pair.second.state, mDefaultState);
+ sl->onStateChanged(eventTimeNs, mAtomId, pair.first, pair.second.state,
+ mDefaultState);
}
}
}
mStateMap.clear();
}
-void StateTracker::handlePartialReset(const HashableDimensionKey& primaryKey) {
+void StateTracker::handlePartialReset(const int64_t eventTimeNs,
+ const HashableDimensionKey& primaryKey) {
VLOG("StateTracker handle partial reset");
if (mStateMap.find(primaryKey) != mStateMap.end()) {
mStateMap.erase(primaryKey);
diff --git a/cmds/statsd/src/state/StateTracker.h b/cmds/statsd/src/state/StateTracker.h
index 450412d..544857f 100644
--- a/cmds/statsd/src/state/StateTracker.h
+++ b/cmds/statsd/src/state/StateTracker.h
@@ -81,10 +81,10 @@
std::set<wp<StateListener>> mListeners;
// Reset all state values in map to default state
- void handleReset();
+ void handleReset(const int64_t eventTimeNs);
// Reset only the state value mapped to primary key to default state
- void handlePartialReset(const HashableDimensionKey& primaryKey);
+ void handlePartialReset(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey);
// Update the StateMap based on the received state value.
// Store the old and new states.