Tracks the delay between the pull and the actual bucket boundary.
Test: atest statsd_test
Change-Id: I08880eafb54d599c9d1adb3c23b19af1f7fac886
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index c774719..c4034ff 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -458,6 +458,15 @@
getAtomMetricStats(metricId).invalidatedBucket++;
}
+void StatsdStats::noteBucketBoundaryDelayNs(int64_t metricId, int64_t timeDelayNs) {
+ lock_guard<std::mutex> lock(mLock);
+ AtomMetricStats& pullStats = getAtomMetricStats(metricId);
+ pullStats.maxBucketBoundaryDelayNs =
+ std::max(pullStats.maxBucketBoundaryDelayNs, timeDelayNs);
+ pullStats.minBucketBoundaryDelayNs =
+ std::min(pullStats.minBucketBoundaryDelayNs, timeDelayNs);
+}
+
StatsdStats::AtomMetricStats& StatsdStats::getAtomMetricStats(int metricId) {
auto atomMetricStatsIter = mAtomMetricStats.find(metricId);
if (atomMetricStatsIter != mAtomMetricStats.end()) {
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index ed42b1f..2999b64 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -375,6 +375,12 @@
void noteInvalidatedBucket(int64_t metricId);
/**
+ * For pulls at bucket boundaries, it represents the misalignment between the real timestamp and
+ * the end of the bucket.
+ */
+ void noteBucketBoundaryDelayNs(int64_t metricId, int64_t timeDelayNs);
+
+ /**
* Reset the historical stats. Including all stats in icebox, and the tracked stats about
* metrics, matchers, and atoms. The active configs will be kept and StatsdStats will continue
* to collect stats after reset() has been called.
@@ -420,6 +426,8 @@
long conditionChangeInNextBucket = 0;
long invalidatedBucket = 0;
long bucketDropped = 0;
+ int64_t minBucketBoundaryDelayNs = 0;
+ int64_t maxBucketBoundaryDelayNs = 0;
} AtomMetricStats;
private:
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 4fc9c37..ac6c27a 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -387,6 +387,8 @@
// If the sleep was very long, we skip more than one bucket before sleep. In this case,
// if the diff base will be cleared and this new data will serve as new diff base.
int64_t bucketEndTime = calcPreviousBucketEndTime(originalPullTimeNs) - 1;
+ StatsdStats::getInstance().noteBucketBoundaryDelayNs(
+ mMetricId, originalPullTimeNs - bucketEndTime);
accumulateEvents(allData, originalPullTimeNs, bucketEndTime);
// We can probably flush the bucket. Since we used bucketEndTime when calling
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index 73aab48..6a07a3f 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -419,6 +419,8 @@
optional int64 condition_change_in_next_bucket = 6;
optional int64 invalidated_bucket = 7;
optional int64 bucket_dropped = 8;
+ optional int64 min_bucket_boundary_delay_ns = 9;
+ optional int64 max_bucket_boundary_delay_ns = 10;
}
repeated AtomMetricStats atom_metric_stats = 17;
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index f76a9ad..aa8cfc5 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -80,6 +80,8 @@
const int FIELD_ID_CONDITION_CHANGE_IN_NEXT_BUCKET = 6;
const int FIELD_ID_INVALIDATED_BUCKET = 7;
const int FIELD_ID_BUCKET_DROPPED = 8;
+const int FIELD_ID_MIN_BUCKET_BOUNDARY_DELAY_NS = 9;
+const int FIELD_ID_MAX_BUCKET_BOUNDARY_DELAY_NS = 10;
namespace {
@@ -500,6 +502,10 @@
(long long)pair.second.invalidatedBucket);
protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_DROPPED,
(long long)pair.second.bucketDropped);
+ protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MIN_BUCKET_BOUNDARY_DELAY_NS,
+ (long long)pair.second.minBucketBoundaryDelayNs);
+ protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MAX_BUCKET_BOUNDARY_DELAY_NS,
+ (long long)pair.second.maxBucketBoundaryDelayNs);
protoOutput->end(token);
}