Statsd config TTL
Roughly check the config every hour to see whether the ttl expired.
If so, read the config from disk and recreate the metric manager.
Test: statsd test
BUG: b/77274363
Change-Id: I16838afe5bbe966c3a0f638869751f9b59a5a259
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index f00cdb3..de8dfe4 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -65,6 +65,7 @@
const int FIELD_ID_LAST_REPORT_WALL_CLOCK_NANOS = 5;
const int FIELD_ID_CURRENT_REPORT_WALL_CLOCK_NANOS = 6;
+#define NS_PER_HOUR 3600 * NS_PER_SEC
#define STATS_DATA_DIR "/data/misc/stats-data"
@@ -85,7 +86,7 @@
}
void StatsLogProcessor::onAnomalyAlarmFired(
- const uint64_t& timestampNs,
+ const int64_t& timestampNs,
unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) {
std::lock_guard<std::mutex> lock(mMetricsMutex);
for (const auto& itr : mMetricsManagers) {
@@ -93,7 +94,7 @@
}
}
void StatsLogProcessor::onPeriodicAlarmFired(
- const uint64_t& timestampNs,
+ const int64_t& timestampNs,
unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet) {
std::lock_guard<std::mutex> lock(mMetricsMutex);
@@ -156,10 +157,14 @@
void StatsLogProcessor::OnLogEvent(LogEvent* event) {
std::lock_guard<std::mutex> lock(mMetricsMutex);
- if (event->GetElapsedTimestampNs() < mLastLogTimestamp) {
+ const int64_t currentTimestampNs = event->GetElapsedTimestampNs();
+ if (currentTimestampNs < mLastLogTimestamp) {
return;
}
- mLastLogTimestamp = event->GetElapsedTimestampNs();
+
+ resetIfConfigTtlExpiredLocked(currentTimestampNs);
+
+ mLastLogTimestamp = currentTimestampNs;
StatsdStats::getInstance().noteAtomLogged(
event->GetTagId(), event->GetElapsedTimestampNs() / NS_PER_SEC);
@@ -173,12 +178,13 @@
return;
}
- uint64_t curTimeSec = getElapsedRealtimeSec();
+ int64_t curTimeSec = getElapsedRealtimeSec();
if (curTimeSec - mLastPullerCacheClearTimeSec > StatsdStats::kPullerCacheClearIntervalSec) {
mStatsPullerManager.ClearPullerCacheIfNecessary(curTimeSec * NS_PER_SEC);
mLastPullerCacheClearTimeSec = curTimeSec;
}
+
if (event->GetTagId() != android::util::ISOLATED_UID_CHANGED) {
// Map the isolated uid to host uid if necessary.
mapIsolatedUidToHostUidIfNecessaryLocked(event);
@@ -194,6 +200,11 @@
void StatsLogProcessor::OnConfigUpdated(const int64_t timestampNs, const ConfigKey& key,
const StatsdConfig& config) {
std::lock_guard<std::mutex> lock(mMetricsMutex);
+ OnConfigUpdatedLocked(timestampNs, key, config);
+}
+
+void StatsLogProcessor::OnConfigUpdatedLocked(
+ const int64_t timestampNs, const ConfigKey& key, const StatsdConfig& config) {
VLOG("Updated configuration for key %s", key.ToString().c_str());
sp<MetricsManager> newMetricsManager =
new MetricsManager(key, config, mTimeBaseSec, (timestampNs - 1) / NS_PER_SEC + 1, mUidMap,
@@ -206,6 +217,7 @@
// not safe to create wp or sp from this pointer inside its constructor.
mUidMap->addListener(newMetricsManager.get());
}
+ newMetricsManager->refreshTtl(timestampNs);
mMetricsManagers[key] = newMetricsManager;
VLOG("StatsdConfig valid");
} else {
@@ -235,7 +247,7 @@
/*
* onDumpReport dumps serialized ConfigMetricsReportList into outData.
*/
-void StatsLogProcessor::onDumpReport(const ConfigKey& key, const uint64_t dumpTimeStampNs,
+void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs,
vector<uint8_t>* outData) {
std::lock_guard<std::mutex> lock(mMetricsMutex);
@@ -290,7 +302,7 @@
* onConfigMetricsReportLocked dumps serialized ConfigMetricsReport into outData.
*/
void StatsLogProcessor::onConfigMetricsReportLocked(const ConfigKey& key,
- const uint64_t dumpTimeStampNs,
+ const int64_t dumpTimeStampNs,
ProtoOutputStream* proto) {
// We already checked whether key exists in mMetricsManagers in
// WriteDataToDisk.
@@ -317,7 +329,29 @@
proto->write(FIELD_TYPE_INT64 | FIELD_ID_CURRENT_REPORT_WALL_CLOCK_NANOS,
(long long)getWallClockNs());
+}
+void StatsLogProcessor::resetIfConfigTtlExpiredLocked(const int64_t timestampNs) {
+ std::vector<ConfigKey> configKeysTtlExpired;
+ for (auto it = mMetricsManagers.begin(); it != mMetricsManagers.end(); it++) {
+ if (it->second != nullptr && !it->second->isInTtl(timestampNs)) {
+ configKeysTtlExpired.push_back(it->first);
+ }
+ }
+
+ for (const auto& key : configKeysTtlExpired) {
+ StatsdConfig config;
+ if (StorageManager::readConfigFromDisk(key, &config)) {
+ OnConfigUpdatedLocked(timestampNs, key, config);
+ StatsdStats::getInstance().noteConfigReset(key);
+ } else {
+ ALOGE("Failed to read backup config from disk for : %s", key.ToString().c_str());
+ auto it = mMetricsManagers.find(key);
+ if (it != mMetricsManagers.end()) {
+ it->second->refreshTtl(timestampNs);
+ }
+ }
+ }
}
void StatsLogProcessor::OnConfigRemoved(const ConfigKey& key) {
@@ -337,7 +371,7 @@
}
void StatsLogProcessor::flushIfNecessaryLocked(
- uint64_t timestampNs, const ConfigKey& key, MetricsManager& metricsManager) {
+ int64_t timestampNs, const ConfigKey& key, MetricsManager& metricsManager) {
auto lastCheckTime = mLastByteSizeTimes.find(key);
if (lastCheckTime != mLastByteSizeTimes.end()) {
if (timestampNs - lastCheckTime->second < StatsdStats::kMinByteSizeCheckPeriodNs) {
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 1c4698f..d37429e 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -48,16 +48,16 @@
size_t GetMetricsSize(const ConfigKey& key) const;
- void onDumpReport(const ConfigKey& key, const uint64_t dumpTimeNs, vector<uint8_t>* outData);
+ void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs, vector<uint8_t>* outData);
/* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */
void onAnomalyAlarmFired(
- const uint64_t& timestampNs,
+ const int64_t& timestampNs,
unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
/* Tells MetricsManager that the alarms in alarmSet have fired. Modifies periodic alarmSet. */
void onPeriodicAlarmFired(
- const uint64_t& timestampNs,
+ const int64_t& timestampNs,
unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet);
/* Flushes data to disk. Data on memory will be gone after written to disk. */
@@ -69,6 +69,7 @@
void dumpStates(FILE* out, bool verbose);
+
private:
// For testing only.
inline sp<AlarmMonitor> getAnomalyAlarmMonitor() const {
@@ -96,12 +97,17 @@
sp<AlarmMonitor> mPeriodicAlarmMonitor;
- void onConfigMetricsReportLocked(const ConfigKey& key, const uint64_t dumpTimeStampNs,
+ void resetIfConfigTtlExpiredLocked(const int64_t timestampNs);
+
+ void OnConfigUpdatedLocked(
+ const int64_t currentTimestampNs, const ConfigKey& key, const StatsdConfig& config);
+
+ void onConfigMetricsReportLocked(const ConfigKey& key, const int64_t dumpTimeStampNs,
util::ProtoOutputStream* proto);
/* Check if we should send a broadcast if approaching memory limits and if we're over, we
* actually delete the data. */
- void flushIfNecessaryLocked(uint64_t timestampNs, const ConfigKey& key,
+ void flushIfNecessaryLocked(int64_t timestampNs, const ConfigKey& key,
MetricsManager& metricsManager);
// Maps the isolated uid in the log event to host uid if the log event contains uid fields.
@@ -152,7 +158,9 @@
FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_single_bucket);
FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_multiple_buckets);
FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
+
FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
+ FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
};
} // namespace statsd
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 7b0d5d9..adc2664 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -677,7 +677,7 @@
"Only system uid can call informAnomalyAlarmFired");
}
- uint64_t currentTimeSec = getElapsedRealtimeSec();
+ int64_t currentTimeSec = getElapsedRealtimeSec();
std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
mAnomalyAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
if (alarmSet.size() > 0) {
@@ -698,7 +698,7 @@
"Only system uid can call informAlarmForSubscriberTriggeringFired");
}
- uint64_t currentTimeSec = getElapsedRealtimeSec();
+ int64_t currentTimeSec = getElapsedRealtimeSec();
std::unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>> alarmSet =
mPeriodicAlarmMonitor->popSoonerThan(static_cast<uint32_t>(currentTimeSec));
if (alarmSet.size() > 0) {
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.cpp b/cmds/statsd/src/anomaly/AlarmTracker.cpp
index 70e6e84..c8e406f 100644
--- a/cmds/statsd/src/anomaly/AlarmTracker.cpp
+++ b/cmds/statsd/src/anomaly/AlarmTracker.cpp
@@ -30,8 +30,8 @@
namespace os {
namespace statsd {
-AlarmTracker::AlarmTracker(const uint64_t startMillis,
- const uint64_t currentMillis,
+AlarmTracker::AlarmTracker(const int64_t startMillis,
+ const int64_t currentMillis,
const Alarm& alarm, const ConfigKey& configKey,
const sp<AlarmMonitor>& alarmMonitor)
: mAlarmConfig(alarm),
@@ -70,7 +70,7 @@
}
void AlarmTracker::informAlarmsFired(
- const uint64_t& timestampNs,
+ const int64_t& timestampNs,
unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) {
if (firedAlarms.empty() || mInternalAlarm == nullptr ||
firedAlarms.find(mInternalAlarm) == firedAlarms.end()) {
diff --git a/cmds/statsd/src/anomaly/AlarmTracker.h b/cmds/statsd/src/anomaly/AlarmTracker.h
index 962a014..2fb3e3b 100644
--- a/cmds/statsd/src/anomaly/AlarmTracker.h
+++ b/cmds/statsd/src/anomaly/AlarmTracker.h
@@ -34,8 +34,8 @@
class AlarmTracker : public virtual RefBase {
public:
- AlarmTracker(const uint64_t startMillis,
- const uint64_t currentMillis,
+ AlarmTracker(const int64_t startMillis,
+ const int64_t currentMillis,
const Alarm& alarm, const ConfigKey& configKey,
const sp<AlarmMonitor>& subscriberAlarmMonitor);
@@ -45,12 +45,12 @@
void addSubscription(const Subscription& subscription);
- void informAlarmsFired(const uint64_t& timestampNs,
+ void informAlarmsFired(const int64_t& timestampNs,
unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms);
protected:
// For test only. Returns the alarm timestamp in seconds. Otherwise returns 0.
- inline uint32_t getAlarmTimestampSec() const {
+ inline int32_t getAlarmTimestampSec() const {
return mInternalAlarm == nullptr ? 0 : mInternalAlarm->timestampSec;
}
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
index f0960e3..f32efee 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
@@ -207,7 +207,7 @@
getSumOverPastBuckets(key) + currentBucketValue > mAlert.trigger_if_sum_gt();
}
-void AnomalyTracker::declareAnomaly(const uint64_t& timestampNs, const MetricDimensionKey& key) {
+void AnomalyTracker::declareAnomaly(const int64_t& timestampNs, const MetricDimensionKey& key) {
// TODO: Why receive timestamp? RefractoryPeriod should always be based on real time right now.
if (isInRefractoryPeriod(timestampNs, key)) {
VLOG("Skipping anomaly declaration since within refractory period");
@@ -235,7 +235,7 @@
mConfigKey.GetId(), mAlert.id());
}
-void AnomalyTracker::detectAndDeclareAnomaly(const uint64_t& timestampNs,
+void AnomalyTracker::detectAndDeclareAnomaly(const int64_t& timestampNs,
const int64_t& currBucketNum,
const MetricDimensionKey& key,
const int64_t& currentBucketValue) {
@@ -244,11 +244,11 @@
}
}
-bool AnomalyTracker::isInRefractoryPeriod(const uint64_t& timestampNs,
+bool AnomalyTracker::isInRefractoryPeriod(const int64_t& timestampNs,
const MetricDimensionKey& key) const {
const auto& it = mRefractoryPeriodEndsSec.find(key);
if (it != mRefractoryPeriodEndsSec.end()) {
- return timestampNs < it->second * NS_PER_SEC;
+ return timestampNs < (it->second * (int64_t)NS_PER_SEC);
}
return false;
}
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.h b/cmds/statsd/src/anomaly/AnomalyTracker.h
index 15671a6..927e2df 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.h
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.h
@@ -67,13 +67,13 @@
const int64_t& currentBucketValue);
// Informs incidentd about the detected alert.
- void declareAnomaly(const uint64_t& timestampNs, const MetricDimensionKey& key);
+ void declareAnomaly(const int64_t& timestampNs, const MetricDimensionKey& key);
// Detects if, based on past buckets plus the new currentBucketValue (which generally
// represents the partially-filled current bucket), an anomaly has happened, and if so,
// declares an anomaly and informs relevant subscribers.
// Also advances to currBucketNum-1.
- void detectAndDeclareAnomaly(const uint64_t& timestampNs, const int64_t& currBucketNum,
+ void detectAndDeclareAnomaly(const int64_t& timestampNs, const int64_t& currBucketNum,
const MetricDimensionKey& key, const int64_t& currentBucketValue);
// Init the AlarmMonitor which is shared across anomaly trackers.
@@ -107,7 +107,7 @@
// Declares an anomaly for each alarm in firedAlarms that belongs to this AnomalyTracker,
// and removes it from firedAlarms. Does NOT remove the alarm from the AlarmMonitor.
- virtual void informAlarmsFired(const uint64_t& timestampNs,
+ virtual void informAlarmsFired(const int64_t& timestampNs,
unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) {
return; // The base AnomalyTracker class doesn't have alarms.
}
@@ -166,7 +166,7 @@
void subtractValueFromSum(const MetricDimensionKey& key, const int64_t& bucketValue);
// Returns true if in the refractory period, else false.
- bool isInRefractoryPeriod(const uint64_t& timestampNs, const MetricDimensionKey& key) const;
+ bool isInRefractoryPeriod(const int64_t& timestampNs, const MetricDimensionKey& key) const;
// Calculates the corresponding bucket index within the circular array.
// Requires bucketNum >= 0.
diff --git a/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp b/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp
index cdc4251..3acfd17 100644
--- a/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp
+++ b/cmds/statsd/src/anomaly/DurationAnomalyTracker.cpp
@@ -36,7 +36,7 @@
}
void DurationAnomalyTracker::startAlarm(const MetricDimensionKey& dimensionKey,
- const uint64_t& timestampNs) {
+ const int64_t& timestampNs) {
// Alarms are stored in secs. Must round up, since if it fires early, it is ignored completely.
uint32_t timestampSec = static_cast<uint32_t>((timestampNs -1) / NS_PER_SEC) + 1; // round up
if (isInRefractoryPeriod(timestampNs, dimensionKey)) {
@@ -57,14 +57,14 @@
}
void DurationAnomalyTracker::stopAlarm(const MetricDimensionKey& dimensionKey,
- const uint64_t& timestampNs) {
+ const int64_t& timestampNs) {
const auto itr = mAlarms.find(dimensionKey);
if (itr == mAlarms.end()) {
return;
}
// If the alarm is set in the past but hasn't fired yet (due to lag), catch it now.
- if (itr->second != nullptr && timestampNs >= NS_PER_SEC * itr->second->timestampSec) {
+ if (itr->second != nullptr && timestampNs >= (int64_t)NS_PER_SEC * itr->second->timestampSec) {
declareAnomaly(timestampNs, dimensionKey);
}
if (mAlarmMonitor != nullptr) {
@@ -82,7 +82,7 @@
mAlarms.clear();
}
-void DurationAnomalyTracker::informAlarmsFired(const uint64_t& timestampNs,
+void DurationAnomalyTracker::informAlarmsFired(const int64_t& timestampNs,
unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) {
if (firedAlarms.empty() || mAlarms.empty()) return;
diff --git a/cmds/statsd/src/anomaly/DurationAnomalyTracker.h b/cmds/statsd/src/anomaly/DurationAnomalyTracker.h
index 53155d9..686d8f9 100644
--- a/cmds/statsd/src/anomaly/DurationAnomalyTracker.h
+++ b/cmds/statsd/src/anomaly/DurationAnomalyTracker.h
@@ -34,12 +34,12 @@
// Sets an alarm for the given timestamp.
// Replaces previous alarm if one already exists.
- void startAlarm(const MetricDimensionKey& dimensionKey, const uint64_t& eventTime);
+ void startAlarm(const MetricDimensionKey& dimensionKey, const int64_t& eventTime);
// Stops the alarm.
// If it should have already fired, but hasn't yet (e.g. because the AlarmManager is delayed),
// declare the anomaly now.
- void stopAlarm(const MetricDimensionKey& dimensionKey, const uint64_t& timestampNs);
+ void stopAlarm(const MetricDimensionKey& dimensionKey, const int64_t& timestampNs);
// Stop all the alarms owned by this tracker. Does not declare any anomalies.
void cancelAllAlarms();
@@ -48,7 +48,7 @@
// and removes it from firedAlarms. The AlarmMonitor is not informed.
// Note that this will generally be called from a different thread from the other functions;
// the caller is responsible for thread safety.
- void informAlarmsFired(const uint64_t& timestampNs,
+ void informAlarmsFired(const int64_t& timestampNs,
unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& firedAlarms) override;
protected:
diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp
index f9aaad4..16b7e79 100644
--- a/cmds/statsd/src/config/ConfigManager.cpp
+++ b/cmds/statsd/src/config/ConfigManager.cpp
@@ -23,6 +23,7 @@
#include "guardrail/StatsdStats.h"
#include "stats_log_util.h"
#include "stats_util.h"
+#include "stats_log_util.h"
#include <android-base/file.h>
#include <dirent.h>
@@ -112,7 +113,7 @@
const int64_t timestampNs = getElapsedRealtimeNs();
// Tell everyone
- for (sp<ConfigListener> listener:broadcastList) {
+ for (sp<ConfigListener> listener : broadcastList) {
listener->OnConfigUpdated(timestampNs, key, config);
}
}
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index 77773fe..0c076e9 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -63,6 +63,7 @@
const int FIELD_ID_CONFIG_STATS_UID = 1;
const int FIELD_ID_CONFIG_STATS_ID = 2;
const int FIELD_ID_CONFIG_STATS_CREATION = 3;
+const int FIELD_ID_CONFIG_STATS_RESET = 18;
const int FIELD_ID_CONFIG_STATS_DELETION = 4;
const int FIELD_ID_CONFIG_STATS_METRIC_COUNT = 5;
const int FIELD_ID_CONFIG_STATS_CONDITION_COUNT = 6;
@@ -165,6 +166,18 @@
noteConfigRemovedInternalLocked(key);
}
+void StatsdStats::noteConfigResetInternalLocked(const ConfigKey& key) {
+ auto it = mConfigStats.find(key);
+ if (it != mConfigStats.end()) {
+ it->second->reset_time_sec = getWallClockSec();
+ }
+}
+
+void StatsdStats::noteConfigReset(const ConfigKey& key) {
+ lock_guard<std::mutex> lock(mLock);
+ noteConfigResetInternalLocked(key);
+}
+
void StatsdStats::noteBroadcastSent(const ConfigKey& key) {
noteBroadcastSent(key, getWallClockSec());
}
@@ -378,10 +391,11 @@
fprintf(out, "%lu Config in icebox: \n", (unsigned long)mIceBox.size());
for (const auto& configStats : mIceBox) {
fprintf(out,
- "Config {%d_%lld}: creation=%d, deletion=%d, #metric=%d, #condition=%d, "
+ "Config {%d_%lld}: creation=%d, deletion=%d, reset=%d, #metric=%d, #condition=%d, "
"#matcher=%d, #alert=%d, valid=%d\n",
configStats->uid, (long long)configStats->id, configStats->creation_time_sec,
- configStats->deletion_time_sec, configStats->metric_count,
+ configStats->deletion_time_sec, configStats->reset_time_sec,
+ configStats->metric_count,
configStats->condition_count, configStats->matcher_count, configStats->alert_count,
configStats->is_valid);
@@ -485,6 +499,9 @@
proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_UID, configStats.uid);
proto->write(FIELD_TYPE_INT64 | FIELD_ID_CONFIG_STATS_ID, (long long)configStats.id);
proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_CREATION, configStats.creation_time_sec);
+ if (configStats.reset_time_sec != 0) {
+ proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_RESET, configStats.reset_time_sec);
+ }
if (configStats.deletion_time_sec != 0) {
proto->write(FIELD_TYPE_INT32 | FIELD_ID_CONFIG_STATS_DELETION,
configStats.deletion_time_sec);
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index a1b0ee2..00bef75 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -34,6 +34,7 @@
int64_t id;
int32_t creation_time_sec;
int32_t deletion_time_sec = 0;
+ int32_t reset_time_sec = 0;
int32_t metric_count;
int32_t condition_count;
int32_t matcher_count;
@@ -121,10 +122,10 @@
const static size_t kMaxBytesUsedUidMap = 50 * 1024;
/* Minimum period between two broadcasts in nanoseconds. */
- static const unsigned long long kMinBroadcastPeriodNs = 60 * NS_PER_SEC;
+ static const int64_t kMinBroadcastPeriodNs = 60 * NS_PER_SEC;
/* Min period between two checks of byte size per config key in nanoseconds. */
- static const unsigned long long kMinByteSizeCheckPeriodNs = 10 * NS_PER_SEC;
+ static const int64_t kMinByteSizeCheckPeriodNs = 10 * NS_PER_SEC;
// Maximum age (30 days) that files on disk can exist in seconds.
static const int kMaxAgeSecond = 60 * 60 * 24 * 30;
@@ -152,6 +153,10 @@
* Report a config has been removed.
*/
void noteConfigRemoved(const ConfigKey& key);
+ /**
+ * Report a config has been reset when ttl expires.
+ */
+ void noteConfigReset(const ConfigKey& key);
/**
* Report a broadcast has been sent to a config owner to collect the data.
@@ -326,6 +331,7 @@
// Stores the number of times statsd registers the periodic alarm changes
int mPeriodicAlarmRegisteredStats = 0;
+ void noteConfigResetInternalLocked(const ConfigKey& key);
void noteConfigRemovedInternalLocked(const ConfigKey& key);
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index afa5140..98963bd 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -59,7 +59,7 @@
CountMetricProducer::CountMetricProducer(const ConfigKey& key, const CountMetric& metric,
const int conditionIndex,
const sp<ConditionWizard>& wizard,
- const uint64_t startTimeNs)
+ const int64_t startTimeNs)
: MetricProducer(metric.id(), key, startTimeNs, conditionIndex, wizard) {
// TODO: evaluate initial conditions. and set mConditionMet.
if (metric.has_bucket()) {
@@ -118,11 +118,11 @@
}
void CountMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
- const uint64_t eventTime) {
+ const int64_t eventTime) {
VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
}
-void CountMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
+void CountMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
ProtoOutputStream* protoOutput) {
flushIfNeededLocked(dumpTimeNs);
if (mPastBuckets.empty()) {
@@ -173,13 +173,13 @@
mPastBuckets.clear();
}
-void CountMetricProducer::dropDataLocked(const uint64_t dropTimeNs) {
+void CountMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
flushIfNeededLocked(dropTimeNs);
mPastBuckets.clear();
}
void CountMetricProducer::onConditionChangedLocked(const bool conditionMet,
- const uint64_t eventTime) {
+ const int64_t eventTime) {
VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
mCondition = conditionMet;
}
@@ -208,7 +208,7 @@
const size_t matcherIndex, const MetricDimensionKey& eventKey,
const ConditionKey& conditionKey, bool condition,
const LogEvent& event) {
- uint64_t eventTimeNs = event.GetElapsedTimestampNs();
+ int64_t eventTimeNs = event.GetElapsedTimestampNs();
flushIfNeededLocked(eventTimeNs);
if (condition == false) {
@@ -244,23 +244,23 @@
// When a new matched event comes in, we check if event falls into the current
// bucket. If not, flush the old counter to past buckets and initialize the new bucket.
-void CountMetricProducer::flushIfNeededLocked(const uint64_t& eventTimeNs) {
- uint64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
+void CountMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
+ int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
if (eventTimeNs < currentBucketEndTimeNs) {
return;
}
flushCurrentBucketLocked(eventTimeNs);
// Setup the bucket start time and number.
- uint64_t numBucketsForward = 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
+ 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,
(long long)mCurrentBucketStartTimeNs);
}
-void CountMetricProducer::flushCurrentBucketLocked(const uint64_t& eventTimeNs) {
- uint64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
+void CountMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs) {
+ int64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
CountBucket info;
info.mBucketStartNs = mCurrentBucketStartTimeNs;
if (eventTimeNs < fullBucketEndTimeNs) {
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index fd9f0e0..5991c28 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -43,7 +43,7 @@
// TODO: Pass in the start time from MetricsManager, it should be consistent for all metrics.
CountMetricProducer(const ConfigKey& key, const CountMetric& countMetric,
const int conditionIndex, const sp<ConditionWizard>& wizard,
- const uint64_t startTimeNs);
+ const int64_t startTimeNs);
virtual ~CountMetricProducer();
@@ -54,26 +54,26 @@
const LogEvent& event) override;
private:
- void onDumpReportLocked(const uint64_t dumpTimeNs,
+ void onDumpReportLocked(const int64_t dumpTimeNs,
android::util::ProtoOutputStream* protoOutput) override;
// Internal interface to handle condition change.
- void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
+ void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
// Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(bool overallCondition, const uint64_t eventTime) override;
+ void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
void dumpStatesLocked(FILE* out, bool verbose) const override;
- void dropDataLocked(const uint64_t dropTimeNs) override;
+ void dropDataLocked(const int64_t dropTimeNs) override;
// Util function to flush the old packet.
- void flushIfNeededLocked(const uint64_t& newEventTime) override;
+ void flushIfNeededLocked(const int64_t& newEventTime) override;
- void flushCurrentBucketLocked(const uint64_t& eventTimeNs) override;
+ void flushCurrentBucketLocked(const int64_t& eventTimeNs) override;
// TODO: Add a lock to mPastBuckets.
std::unordered_map<MetricDimensionKey, std::vector<CountBucket>> mPastBuckets;
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index f02f307..19155de 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -61,7 +61,7 @@
const bool nesting,
const sp<ConditionWizard>& wizard,
const FieldMatcher& internalDimensions,
- const uint64_t startTimeNs)
+ const int64_t startTimeNs)
: MetricProducer(metric.id(), key, startTimeNs, conditionIndex, wizard),
mAggregationType(metric.aggregation_type()),
mStartIndex(startIndex),
@@ -170,7 +170,7 @@
// 2. No condition in dimension
// 3. The links covers all dimension fields in the sliced child condition predicate.
void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt1(bool condition,
- const uint64_t eventTime) {
+ const int64_t eventTime) {
if (mMetric2ConditionLinks.size() != 1 ||
!mHasLinksToAllConditionDimensionsInTracker ||
!mDimensionsInCondition.empty()) {
@@ -243,7 +243,7 @@
// 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(bool condition,
- const uint64_t eventTime) {
+ const int64_t eventTime) {
if (mMetric2ConditionLinks.size() > 1 || !mSameConditionDimensionsInTracker) {
return;
}
@@ -328,7 +328,7 @@
}
void DurationMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
- const uint64_t eventTime) {
+ const int64_t eventTime) {
VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
flushIfNeededLocked(eventTime);
@@ -420,7 +420,7 @@
}
void DurationMetricProducer::onConditionChangedLocked(const bool conditionMet,
- const uint64_t eventTime) {
+ const int64_t eventTime) {
VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
mCondition = conditionMet;
flushIfNeededLocked(eventTime);
@@ -433,12 +433,12 @@
}
}
-void DurationMetricProducer::dropDataLocked(const uint64_t dropTimeNs) {
+void DurationMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
flushIfNeededLocked(dropTimeNs);
mPastBuckets.clear();
}
-void DurationMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
+void DurationMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
ProtoOutputStream* protoOutput) {
flushIfNeededLocked(dumpTimeNs);
if (mPastBuckets.empty()) {
@@ -492,8 +492,8 @@
mPastBuckets.clear();
}
-void DurationMetricProducer::flushIfNeededLocked(const uint64_t& eventTimeNs) {
- uint64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
+void DurationMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
+ int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
if (currentBucketEndTimeNs > eventTimeNs) {
return;
@@ -522,7 +522,7 @@
mCurrentBucketNum += numBucketsForward;
}
-void DurationMetricProducer::flushCurrentBucketLocked(const uint64_t& eventTimeNs) {
+void DurationMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs) {
for (auto whatIt = mCurrentSlicedDurationTrackerMap.begin();
whatIt != mCurrentSlicedDurationTrackerMap.end();) {
for (auto it = whatIt->second.begin(); it != whatIt->second.end();) {
@@ -644,7 +644,7 @@
void DurationMetricProducer::onMatchedLogEventLocked(const size_t matcherIndex,
const LogEvent& event) {
- uint64_t eventTimeNs = event.GetElapsedTimestampNs();
+ int64_t eventTimeNs = event.GetElapsedTimestampNs();
if (eventTimeNs < mStartTimeNs) {
return;
}
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index 75f2391..80fb829 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -42,7 +42,7 @@
const int conditionIndex, const size_t startIndex,
const size_t stopIndex, const size_t stopAllIndex, const bool nesting,
const sp<ConditionWizard>& wizard,
- const FieldMatcher& internalDimensions, const uint64_t startTimeNs);
+ const FieldMatcher& internalDimensions, const int64_t startTimeNs);
virtual ~DurationMetricProducer();
@@ -61,29 +61,29 @@
void handleStartEvent(const MetricDimensionKey& eventKey, const ConditionKey& conditionKeys,
bool condition, const LogEvent& event);
- void onDumpReportLocked(const uint64_t dumpTimeNs,
+ void onDumpReportLocked(const int64_t dumpTimeNs,
android::util::ProtoOutputStream* protoOutput) override;
// Internal interface to handle condition change.
- void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
+ void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
// Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(bool overallCondition, const uint64_t eventTime) override;
+ void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
- void onSlicedConditionMayChangeLocked_opt1(bool overallCondition, const uint64_t eventTime);
- void onSlicedConditionMayChangeLocked_opt2(bool overallCondition, const uint64_t eventTime);
+ void onSlicedConditionMayChangeLocked_opt1(bool overallCondition, const int64_t eventTime);
+ void onSlicedConditionMayChangeLocked_opt2(bool overallCondition, const int64_t eventTime);
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
void dumpStatesLocked(FILE* out, bool verbose) const override;
- void dropDataLocked(const uint64_t dropTimeNs) override;
+ void dropDataLocked(const int64_t dropTimeNs) override;
// Util function to flush the old packet.
- void flushIfNeededLocked(const uint64_t& eventTime);
+ void flushIfNeededLocked(const int64_t& eventTime);
- void flushCurrentBucketLocked(const uint64_t& eventTimeNs) override;
+ void flushCurrentBucketLocked(const int64_t& eventTimeNs) override;
const DurationMetric_AggregationType mAggregationType;
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index 42a5a3a..d55cb3f 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -54,7 +54,7 @@
EventMetricProducer::EventMetricProducer(const ConfigKey& key, const EventMetric& metric,
const int conditionIndex,
const sp<ConditionWizard>& wizard,
- const uint64_t startTimeNs)
+ const int64_t startTimeNs)
: MetricProducer(metric.id(), key, startTimeNs, conditionIndex, wizard) {
if (metric.links().size() > 0) {
for (const auto& link : metric.links()) {
@@ -75,12 +75,12 @@
VLOG("~EventMetricProducer() called");
}
-void EventMetricProducer::dropDataLocked(const uint64_t dropTimeNs) {
+void EventMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
mProto->clear();
}
void EventMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
- const uint64_t eventTime) {
+ const int64_t eventTime) {
}
std::unique_ptr<std::vector<uint8_t>> serializeProtoLocked(ProtoOutputStream& protoOutput) {
@@ -100,7 +100,7 @@
return buffer;
}
-void EventMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
+void EventMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
ProtoOutputStream* protoOutput) {
if (mProto->size() <= 0) {
return;
@@ -119,7 +119,7 @@
}
void EventMetricProducer::onConditionChangedLocked(const bool conditionMet,
- const uint64_t eventTime) {
+ const int64_t eventTime) {
VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
mCondition = conditionMet;
}
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h
index 93c6c9a..fbbc7e2 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.h
+++ b/cmds/statsd/src/metrics/EventMetricProducer.h
@@ -36,7 +36,7 @@
// TODO: Pass in the start time from MetricsManager, it should be consistent for all metrics.
EventMetricProducer(const ConfigKey& key, const EventMetric& eventMetric,
const int conditionIndex, const sp<ConditionWizard>& wizard,
- const uint64_t startTimeNs);
+ const int64_t startTimeNs);
virtual ~EventMetricProducer();
@@ -46,16 +46,16 @@
const ConditionKey& conditionKey, bool condition,
const LogEvent& event) override;
- void onDumpReportLocked(const uint64_t dumpTimeNs,
+ void onDumpReportLocked(const int64_t dumpTimeNs,
android::util::ProtoOutputStream* protoOutput) override;
// Internal interface to handle condition change.
- void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
+ void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
// Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(bool overallCondition, const uint64_t eventTime) override;
+ void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
- void dropDataLocked(const uint64_t dropTimeNs) override;
+ void dropDataLocked(const int64_t dropTimeNs) override;
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index b13c3e7..2561d1d 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -61,7 +61,7 @@
GaugeMetricProducer::GaugeMetricProducer(const ConfigKey& key, const GaugeMetric& metric,
const int conditionIndex,
const sp<ConditionWizard>& wizard, const int pullTagId,
- const uint64_t startTimeNs,
+ const int64_t startTimeNs,
shared_ptr<StatsPullerManager> statsPullerManager)
: MetricProducer(metric.id(), key, startTimeNs, conditionIndex, wizard),
mStatsPullerManager(statsPullerManager),
@@ -155,7 +155,7 @@
}
}
-void GaugeMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
+void GaugeMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
ProtoOutputStream* protoOutput) {
VLOG("Gauge metric %lld report now...", (long long)mMetricId);
@@ -267,7 +267,7 @@
}
void GaugeMetricProducer::onConditionChangedLocked(const bool conditionMet,
- const uint64_t eventTime) {
+ const int64_t eventTime) {
VLOG("GaugeMetric %lld onConditionChanged", (long long)mMetricId);
flushIfNeededLocked(eventTime);
mCondition = conditionMet;
@@ -278,7 +278,7 @@
}
void GaugeMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
- const uint64_t eventTime) {
+ const int64_t eventTime) {
VLOG("GaugeMetric %lld onSlicedConditionMayChange overall condition %d", (long long)mMetricId,
overallCondition);
flushIfNeededLocked(eventTime);
@@ -336,7 +336,7 @@
if (condition == false) {
return;
}
- uint64_t eventTimeNs = event.GetElapsedTimestampNs();
+ int64_t eventTimeNs = event.GetElapsedTimestampNs();
mTagId = event.GetTagId();
if (eventTimeNs < mCurrentBucketStartTimeNs) {
VLOG("Gauge Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
@@ -391,7 +391,7 @@
}
}
-void GaugeMetricProducer::dropDataLocked(const uint64_t dropTimeNs) {
+void GaugeMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
flushIfNeededLocked(dropTimeNs);
mPastBuckets.clear();
}
@@ -401,8 +401,8 @@
// bucket.
// if data is pushed, onMatchedLogEvent will only be called through onConditionChanged() inside
// the GaugeMetricProducer while holding the lock.
-void GaugeMetricProducer::flushIfNeededLocked(const uint64_t& eventTimeNs) {
- uint64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
+void GaugeMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
+ int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
if (eventTimeNs < currentBucketEndTimeNs) {
VLOG("Gauge eventTime is %lld, less than next bucket start time %lld",
@@ -420,8 +420,8 @@
(long long)mCurrentBucketStartTimeNs);
}
-void GaugeMetricProducer::flushCurrentBucketLocked(const uint64_t& eventTimeNs) {
- uint64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
+void GaugeMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs) {
+ int64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
GaugeBucket info;
info.mBucketStartNs = mCurrentBucketStartTimeNs;
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index 9605b13..f49180f 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -65,7 +65,7 @@
void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data) override;
// GaugeMetric needs to immediately trigger another pull when we create the partial bucket.
- void notifyAppUpgrade(const uint64_t& eventTimeNs, const string& apk, const int uid,
+ void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
const int64_t version) override {
std::lock_guard<std::mutex> lock(mMutex);
@@ -87,32 +87,32 @@
const LogEvent& event) override;
private:
- void onDumpReportLocked(const uint64_t dumpTimeNs,
+ void onDumpReportLocked(const int64_t dumpTimeNs,
android::util::ProtoOutputStream* protoOutput) override;
// for testing
GaugeMetricProducer(const ConfigKey& key, const GaugeMetric& gaugeMetric,
const int conditionIndex, const sp<ConditionWizard>& wizard,
- const int pullTagId, const uint64_t startTimeNs,
+ const int pullTagId, const int64_t startTimeNs,
std::shared_ptr<StatsPullerManager> statsPullerManager);
// Internal interface to handle condition change.
- void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
+ void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
// Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(bool overallCondition, const uint64_t eventTime) override;
+ void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
void dumpStatesLocked(FILE* out, bool verbose) const override;
- void dropDataLocked(const uint64_t dropTimeNs) override;
+ void dropDataLocked(const int64_t dropTimeNs) override;
// Util function to flush the old packet.
- void flushIfNeededLocked(const uint64_t& eventTime) override;
+ void flushIfNeededLocked(const int64_t& eventTime) override;
- void flushCurrentBucketLocked(const uint64_t& eventTimeNs) override;
+ void flushCurrentBucketLocked(const int64_t& eventTimeNs) override;
void pullLocked();
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index bf529c8..bcf0e62 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -25,7 +25,7 @@
using std::map;
void MetricProducer::onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event) {
- uint64_t eventTimeNs = event.GetElapsedTimestampNs();
+ int64_t eventTimeNs = event.GetElapsedTimestampNs();
// this is old event, maybe statsd restarted?
if (eventTimeNs < mStartTimeNs) {
return;
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 0b3d677..139a407 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -64,7 +64,7 @@
* the flush again when the end timestamp is forced to be now, and then after flushing, update
* the start timestamp to be now.
*/
- void notifyAppUpgrade(const uint64_t& eventTimeNs, const string& apk, const int uid,
+ void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
const int64_t version) override {
std::lock_guard<std::mutex> lock(mMutex);
@@ -79,11 +79,11 @@
// is a partial bucket and can merge it with the previous bucket.
};
- void notifyAppRemoved(const uint64_t& eventTimeNs, const string& apk, const int uid) override{
+ void notifyAppRemoved(const int64_t& eventTimeNs, const string& apk, const int uid) override{
// TODO: Implement me.
};
- void onUidMapReceived(const uint64_t& eventTimeNs) override{
+ void onUidMapReceived(const int64_t& eventTimeNs) override{
// TODO: Implement me.
};
@@ -93,12 +93,12 @@
onMatchedLogEventLocked(matcherIndex, event);
}
- void onConditionChanged(const bool condition, const uint64_t eventTime) {
+ void onConditionChanged(const bool condition, const int64_t eventTime) {
std::lock_guard<std::mutex> lock(mMutex);
onConditionChangedLocked(condition, eventTime);
}
- void onSlicedConditionMayChange(bool overallCondition, const uint64_t eventTime) {
+ void onSlicedConditionMayChange(bool overallCondition, const int64_t eventTime) {
std::lock_guard<std::mutex> lock(mMutex);
onSlicedConditionMayChangeLocked(overallCondition, eventTime);
}
@@ -110,7 +110,7 @@
// Output the metrics data to [protoOutput]. All metrics reports end with the same timestamp.
// This method clears all the past buckets.
- void onDumpReport(const uint64_t dumpTimeNs, android::util::ProtoOutputStream* protoOutput) {
+ void onDumpReport(const int64_t dumpTimeNs, android::util::ProtoOutputStream* protoOutput) {
std::lock_guard<std::mutex> lock(mMutex);
return onDumpReportLocked(dumpTimeNs, protoOutput);
}
@@ -156,16 +156,16 @@
// We still need to keep future data valid and anomaly tracking work, which means we will
// have to flush old data, informing anomaly trackers then safely drop old data.
// We still keep current bucket data for future metrics' validity.
- void dropData(const uint64_t dropTimeNs) {
+ void dropData(const int64_t dropTimeNs) {
std::lock_guard<std::mutex> lock(mMutex);
dropDataLocked(dropTimeNs);
}
protected:
- virtual void onConditionChangedLocked(const bool condition, const uint64_t eventTime) = 0;
+ virtual void onConditionChangedLocked(const bool condition, const int64_t eventTime) = 0;
virtual void onSlicedConditionMayChangeLocked(bool overallCondition,
- const uint64_t eventTime) = 0;
- virtual void onDumpReportLocked(const uint64_t dumpTimeNs,
+ const int64_t eventTime) = 0;
+ virtual void onDumpReportLocked(const int64_t dumpTimeNs,
android::util::ProtoOutputStream* protoOutput) = 0;
virtual size_t byteSizeLocked() const = 0;
virtual void dumpStatesLocked(FILE* out, bool verbose) const = 0;
@@ -173,7 +173,7 @@
/**
* Flushes the current bucket if the eventTime is after the current bucket's end time.
*/
- virtual void flushIfNeededLocked(const uint64_t& eventTime){};
+ virtual void flushIfNeededLocked(const int64_t& eventTime){};
/**
* For metrics that aggregate (ie, every metric producer except for EventMetricProducer),
@@ -185,15 +185,15 @@
* flushIfNeededLocked or the app upgrade handler; the caller MUST update the bucket timestamp
* and bucket number as needed.
*/
- virtual void flushCurrentBucketLocked(const uint64_t& eventTimeNs){};
+ virtual void flushCurrentBucketLocked(const int64_t& eventTimeNs){};
// Convenience to compute the current bucket's end time, which is always aligned with the
// start time of the metric.
- uint64_t getCurrentBucketEndTimeNs() const {
+ int64_t getCurrentBucketEndTimeNs() const {
return mStartTimeNs + (mCurrentBucketNum + 1) * mBucketSizeNs;
}
- virtual void dropDataLocked(const uint64_t dropTimeNs) = 0;
+ virtual void dropDataLocked(const int64_t dropTimeNs) = 0;
const int64_t mMetricId;
@@ -201,15 +201,15 @@
// The time when this metric producer was first created. The end time for the current bucket
// can be computed from this based on mCurrentBucketNum.
- uint64_t mStartTimeNs;
+ int64_t mStartTimeNs;
// Start time may not be aligned with the start of statsd if there is an app upgrade in the
// middle of a bucket.
- uint64_t mCurrentBucketStartTimeNs;
+ int64_t mCurrentBucketStartTimeNs;
// Used by anomaly detector to track which bucket we are in. This is not sent with the produced
// report.
- uint64_t mCurrentBucketNum;
+ int64_t mCurrentBucketNum;
int64_t mBucketSizeNs;
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 772f017..22827b0 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -59,8 +59,13 @@
const sp<AlarmMonitor>& anomalyAlarmMonitor,
const sp<AlarmMonitor>& periodicAlarmMonitor)
: mConfigKey(key), mUidMap(uidMap),
+ mTtlNs(config.has_ttl_in_seconds() ? config.ttl_in_seconds() * NS_PER_SEC : -1),
+ mTtlEndNs(-1),
mLastReportTimeNs(timeBaseSec * NS_PER_SEC),
mLastReportWallClockNs(getWallClockNs()) {
+ // Init the ttl end timestamp.
+ refreshTtl(timeBaseSec * NS_PER_SEC);
+
mConfigValid =
initStatsdConfig(key, config, *uidMap, anomalyAlarmMonitor, periodicAlarmMonitor,
timeBaseSec, currentTimeSec, mTagIds, mAllAtomMatchers,
@@ -136,7 +141,7 @@
return mConfigValid;
}
-void MetricsManager::notifyAppUpgrade(const uint64_t& eventTimeNs, const string& apk, const int uid,
+void MetricsManager::notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
const int64_t version) {
// check if we care this package
if (std::find(mAllowedPkg.begin(), mAllowedPkg.end(), apk) == mAllowedPkg.end()) {
@@ -147,7 +152,7 @@
initLogSourceWhiteList();
}
-void MetricsManager::notifyAppRemoved(const uint64_t& eventTimeNs, const string& apk,
+void MetricsManager::notifyAppRemoved(const int64_t& eventTimeNs, const string& apk,
const int uid) {
// check if we care this package
if (std::find(mAllowedPkg.begin(), mAllowedPkg.end(), apk) == mAllowedPkg.end()) {
@@ -158,7 +163,7 @@
initLogSourceWhiteList();
}
-void MetricsManager::onUidMapReceived(const uint64_t& eventTimeNs) {
+void MetricsManager::onUidMapReceived(const int64_t& eventTimeNs) {
if (mAllowedPkg.size() == 0) {
return;
}
@@ -179,13 +184,13 @@
}
}
-void MetricsManager::dropData(const uint64_t dropTimeNs) {
+void MetricsManager::dropData(const int64_t dropTimeNs) {
for (const auto& producer : mAllMetricProducers) {
producer->dropData(dropTimeNs);
}
}
-void MetricsManager::onDumpReport(const uint64_t dumpTimeStampNs, ProtoOutputStream* protoOutput) {
+void MetricsManager::onDumpReport(const int64_t dumpTimeStampNs, ProtoOutputStream* protoOutput) {
VLOG("=========================Metric Reports Start==========================");
// one StatsLogReport per MetricProduer
for (const auto& producer : mAllMetricProducers) {
@@ -288,7 +293,7 @@
}
int tagId = event.GetTagId();
- uint64_t eventTime = event.GetElapsedTimestampNs();
+ int64_t eventTime = event.GetElapsedTimestampNs();
if (mTagIds.find(tagId) == mTagIds.end()) {
// not interesting...
return;
@@ -367,7 +372,7 @@
}
void MetricsManager::onAnomalyAlarmFired(
- const uint64_t& timestampNs,
+ const int64_t& timestampNs,
unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet) {
for (const auto& itr : mAllAnomalyTrackers) {
itr->informAlarmsFired(timestampNs, alarmSet);
@@ -375,7 +380,7 @@
}
void MetricsManager::onPeriodicAlarmFired(
- const uint64_t& timestampNs,
+ const int64_t& timestampNs,
unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet) {
for (const auto& itr : mAllPeriodicAlarmTrackers) {
itr->informAlarmsFired(timestampNs, alarmSet);
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index be4644c..9a9b33c 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -49,19 +49,19 @@
void onLogEvent(const LogEvent& event);
void onAnomalyAlarmFired(
- const uint64_t& timestampNs,
+ const int64_t& timestampNs,
unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet);
void onPeriodicAlarmFired(
- const uint64_t& timestampNs,
+ const int64_t& timestampNs,
unordered_set<sp<const InternalAlarm>, SpHash<InternalAlarm>>& alarmSet);
- void notifyAppUpgrade(const uint64_t& eventTimeNs, const string& apk, const int uid,
+ void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
const int64_t version) override;
- void notifyAppRemoved(const uint64_t& eventTimeNs, const string& apk, const int uid) override;
+ void notifyAppRemoved(const int64_t& eventTimeNs, const string& apk, const int uid) override;
- void onUidMapReceived(const uint64_t& eventTimeNs) override;
+ void onUidMapReceived(const int64_t& eventTimeNs) override;
bool shouldAddUidMapListener() const {
return !mAllowedPkg.empty();
@@ -69,6 +69,16 @@
void dumpStates(FILE* out, bool verbose);
+ inline bool isInTtl(const int64_t timestampNs) const {
+ return mTtlNs <= 0 || timestampNs < mTtlEndNs;
+ };
+
+ void refreshTtl(const int64_t currentTimestampNs) {
+ if (mTtlNs > 0) {
+ mTtlEndNs = currentTimestampNs + mTtlNs;
+ }
+ };
+
// Returns the elapsed realtime when this metric manager last reported metrics.
inline int64_t getLastReportTimeNs() const {
return mLastReportTimeNs;
@@ -78,22 +88,29 @@
return mLastReportWallClockNs;
};
- virtual void dropData(const uint64_t dropTimeNs);
+ virtual void dropData(const int64_t dropTimeNs);
// Config source owner can call onDumpReport() to get all the metrics collected.
- virtual void onDumpReport(const uint64_t dumpTimeNs,
+ virtual void onDumpReport(const int64_t dumpTimeNs,
android::util::ProtoOutputStream* protoOutput);
// Computes the total byte size of all metrics managed by a single config source.
// Does not change the state.
virtual size_t byteSize();
+
private:
+ // For test only.
+ inline int64_t getTtlEndNs() const { return mTtlEndNs; }
+
const ConfigKey mConfigKey;
sp<UidMap> mUidMap;
bool mConfigValid = false;
+ const int64_t mTtlNs;
+ int64_t mTtlEndNs;
+
int64_t mLastReportTimeNs;
int64_t mLastReportWallClockNs;
@@ -189,6 +206,7 @@
FRIEND_TEST(AnomalyDetectionE2eTest, TestDurationMetric_SUM_long_refractory_period);
FRIEND_TEST(AlarmE2eTest, TestMultipleAlarms);
+ FRIEND_TEST(ConfigTtlE2eTest, TestCountMetric);
};
} // namespace statsd
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index d0f510d..fd623ca 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -63,7 +63,7 @@
ValueMetricProducer::ValueMetricProducer(const ConfigKey& key, const ValueMetric& metric,
const int conditionIndex,
const sp<ConditionWizard>& wizard, const int pullTagId,
- const uint64_t startTimeNs,
+ const int64_t startTimeNs,
shared_ptr<StatsPullerManager> statsPullerManager)
: MetricProducer(metric.id(), key, startTimeNs, conditionIndex, wizard),
mValueField(metric.value_field()),
@@ -124,7 +124,7 @@
ValueMetricProducer::ValueMetricProducer(const ConfigKey& key, const ValueMetric& metric,
const int conditionIndex,
const sp<ConditionWizard>& wizard, const int pullTagId,
- const uint64_t startTimeNs)
+ const int64_t startTimeNs)
: ValueMetricProducer(key, metric, conditionIndex, wizard, pullTagId, startTimeNs,
make_shared<StatsPullerManager>()) {
}
@@ -137,16 +137,16 @@
}
void ValueMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
- const uint64_t eventTime) {
+ const int64_t eventTime) {
VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
}
-void ValueMetricProducer::dropDataLocked(const uint64_t dropTimeNs) {
+void ValueMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
flushIfNeededLocked(dropTimeNs);
mPastBuckets.clear();
}
-void ValueMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
+void ValueMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
ProtoOutputStream* protoOutput) {
VLOG("metric %lld dump report now...", (long long)mMetricId);
flushIfNeededLocked(dumpTimeNs);
@@ -197,7 +197,7 @@
}
void ValueMetricProducer::onConditionChangedLocked(const bool condition,
- const uint64_t eventTimeNs) {
+ const int64_t eventTimeNs) {
mCondition = condition;
if (eventTimeNs < mCurrentBucketStartTimeNs) {
@@ -231,8 +231,8 @@
}
// For scheduled pulled data, the effective event time is snap to the nearest
// bucket boundary to make bucket finalize.
- uint64_t realEventTime = allData.at(0)->GetElapsedTimestampNs();
- uint64_t eventTime = mStartTimeNs +
+ int64_t realEventTime = allData.at(0)->GetElapsedTimestampNs();
+ int64_t eventTime = mStartTimeNs +
((realEventTime - mStartTimeNs) / mBucketSizeNs) * mBucketSizeNs;
mCondition = false;
@@ -290,7 +290,7 @@
const size_t matcherIndex, const MetricDimensionKey& eventKey,
const ConditionKey& conditionKey, bool condition,
const LogEvent& event) {
- uint64_t eventTimeNs = event.GetElapsedTimestampNs();
+ int64_t eventTimeNs = event.GetElapsedTimestampNs();
if (eventTimeNs < mCurrentBucketStartTimeNs) {
VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
(long long)mCurrentBucketStartTimeNs);
@@ -349,8 +349,8 @@
}
}
-void ValueMetricProducer::flushIfNeededLocked(const uint64_t& eventTimeNs) {
- uint64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
+void ValueMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
+ int64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
if (currentBucketEndTimeNs > eventTimeNs) {
VLOG("eventTime is %lld, less than next bucket start time %lld", (long long)eventTimeNs,
@@ -371,10 +371,10 @@
(long long)mCurrentBucketStartTimeNs);
}
-void ValueMetricProducer::flushCurrentBucketLocked(const uint64_t& eventTimeNs) {
+void ValueMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs) {
VLOG("finalizing bucket for %ld, dumping %d slices", (long)mCurrentBucketStartTimeNs,
(int)mCurrentSlicedBucket.size());
- uint64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
+ int64_t fullBucketEndTimeNs = getCurrentBucketEndTimeNs();
ValueBucket info;
info.mBucketStartNs = mCurrentBucketStartTimeNs;
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index 45d9531..c8f7062 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -40,14 +40,14 @@
public:
ValueMetricProducer(const ConfigKey& key, const ValueMetric& valueMetric,
const int conditionIndex, const sp<ConditionWizard>& wizard,
- const int pullTagId, const uint64_t startTimeNs);
+ const int pullTagId, const int64_t startTimeNs);
virtual ~ValueMetricProducer();
void onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& data) override;
// ValueMetric needs special logic if it's a pulled atom.
- void notifyAppUpgrade(const uint64_t& eventTimeNs, const string& apk, const int uid,
+ void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
const int64_t version) override {
std::lock_guard<std::mutex> lock(mMutex);
@@ -86,14 +86,14 @@
const LogEvent& event) override;
private:
- void onDumpReportLocked(const uint64_t dumpTimeNs,
+ void onDumpReportLocked(const int64_t dumpTimeNs,
android::util::ProtoOutputStream* protoOutput) override;
// Internal interface to handle condition change.
- void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
+ void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override;
// Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(bool overallCondition, const uint64_t eventTime) override;
+ void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override;
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
@@ -101,11 +101,11 @@
void dumpStatesLocked(FILE* out, bool verbose) const override;
// Util function to flush the old packet.
- void flushIfNeededLocked(const uint64_t& eventTime) override;
+ void flushIfNeededLocked(const int64_t& eventTime) override;
- void flushCurrentBucketLocked(const uint64_t& eventTimeNs) override;
+ void flushCurrentBucketLocked(const int64_t& eventTimeNs) override;
- void dropDataLocked(const uint64_t dropTimeNs) override;
+ void dropDataLocked(const int64_t dropTimeNs) override;
const FieldMatcher mValueField;
@@ -114,7 +114,7 @@
// for testing
ValueMetricProducer(const ConfigKey& key, const ValueMetric& valueMetric,
const int conditionIndex, const sp<ConditionWizard>& wizard,
- const int pullTagId, const uint64_t startTimeNs,
+ const int pullTagId, const int64_t startTimeNs,
std::shared_ptr<StatsPullerManager> statsPullerManager);
// tagId for pulled data. -1 if this is not pulled
diff --git a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
index 4132703..149b318 100644
--- a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
@@ -52,9 +52,9 @@
};
struct DurationBucket {
- uint64_t mBucketStartNs;
- uint64_t mBucketEndNs;
- uint64_t mDuration;
+ int64_t mBucketStartNs;
+ int64_t mBucketEndNs;
+ int64_t mDuration;
};
class DurationTracker {
@@ -62,8 +62,8 @@
DurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
sp<ConditionWizard> wizard, int conditionIndex,
const std::vector<Matcher>& dimensionInCondition, bool nesting,
- uint64_t currentBucketStartNs, uint64_t currentBucketNum, uint64_t startTimeNs,
- uint64_t bucketSizeNs, bool conditionSliced, bool fullLink,
+ int64_t currentBucketStartNs, int64_t currentBucketNum, int64_t startTimeNs,
+ int64_t bucketSizeNs, bool conditionSliced, bool fullLink,
const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
: mConfigKey(key),
mTrackerId(id),
@@ -84,27 +84,27 @@
virtual ~DurationTracker(){};
- virtual unique_ptr<DurationTracker> clone(const uint64_t eventTime) = 0;
+ virtual unique_ptr<DurationTracker> clone(const int64_t eventTime) = 0;
virtual void noteStart(const HashableDimensionKey& key, bool condition,
- const uint64_t eventTime, const ConditionKey& conditionKey) = 0;
- virtual void noteStop(const HashableDimensionKey& key, const uint64_t eventTime,
+ const int64_t eventTime, const ConditionKey& conditionKey) = 0;
+ virtual void noteStop(const HashableDimensionKey& key, const int64_t eventTime,
const bool stopAll) = 0;
- virtual void noteStopAll(const uint64_t eventTime) = 0;
+ virtual void noteStopAll(const int64_t eventTime) = 0;
- virtual void onSlicedConditionMayChange(bool overallCondition, const uint64_t timestamp) = 0;
- virtual void onConditionChanged(bool condition, const uint64_t timestamp) = 0;
+ virtual void onSlicedConditionMayChange(bool overallCondition, const int64_t timestamp) = 0;
+ virtual void onConditionChanged(bool condition, const int64_t timestamp) = 0;
// Flush stale buckets if needed, and return true if the tracker has no on-going duration
// events, so that the owner can safely remove the tracker.
virtual bool flushIfNeeded(
- uint64_t timestampNs,
+ int64_t timestampNs,
std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) = 0;
// Should only be called during an app upgrade or from this tracker's flushIfNeeded. If from
// an app upgrade, we assume that we're trying to form a partial bucket.
virtual bool flushCurrentBucket(
- const uint64_t& eventTimeNs,
+ const int64_t& eventTimeNs,
std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) = 0;
// Predict the anomaly timestamp given the current status.
@@ -118,15 +118,15 @@
}
protected:
- uint64_t getCurrentBucketEndTimeNs() const {
+ int64_t getCurrentBucketEndTimeNs() const {
return mStartTimeNs + (mCurrentBucketNum + 1) * mBucketSizeNs;
}
// Starts the anomaly alarm.
- void startAnomalyAlarm(const uint64_t eventTime) {
+ void startAnomalyAlarm(const int64_t eventTime) {
for (auto& anomalyTracker : mAnomalyTrackers) {
if (anomalyTracker != nullptr) {
- const uint64_t alarmTimestampNs =
+ const int64_t alarmTimestampNs =
predictAnomalyTimestampNs(*anomalyTracker, eventTime);
if (alarmTimestampNs > 0) {
anomalyTracker->startAlarm(mEventKey, alarmTimestampNs);
@@ -136,7 +136,7 @@
}
// Stops the anomaly alarm. If it should have already fired, declare the anomaly now.
- void stopAnomalyAlarm(const uint64_t timestamp) {
+ void stopAnomalyAlarm(const int64_t timestamp) {
for (auto& anomalyTracker : mAnomalyTrackers) {
if (anomalyTracker != nullptr) {
anomalyTracker->stopAlarm(mEventKey, timestamp);
@@ -152,7 +152,7 @@
}
}
- void detectAndDeclareAnomaly(const uint64_t& timestamp, const int64_t& currBucketNum,
+ void detectAndDeclareAnomaly(const int64_t& timestamp, const int64_t& currBucketNum,
const int64_t& currentBucketValue) {
for (auto& anomalyTracker : mAnomalyTrackers) {
if (anomalyTracker != nullptr) {
@@ -164,7 +164,7 @@
// Convenience to compute the current bucket's end time, which is always aligned with the
// start time of the metric.
- uint64_t getCurrentBucketEndTimeNs() {
+ int64_t getCurrentBucketEndTimeNs() {
return mStartTimeNs + (mCurrentBucketNum + 1) * mBucketSizeNs;
}
@@ -185,15 +185,15 @@
const bool mNested;
- uint64_t mCurrentBucketStartTimeNs;
+ int64_t mCurrentBucketStartTimeNs;
int64_t mDuration; // current recorded duration result (for partial bucket)
int64_t mDurationFullBucket; // Sum of past partial buckets in current full bucket.
- uint64_t mCurrentBucketNum;
+ int64_t mCurrentBucketNum;
- const uint64_t mStartTimeNs;
+ const int64_t mStartTimeNs;
const bool mConditionSliced;
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
index 5c1e9c0..6868b8c 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
@@ -28,8 +28,8 @@
const MetricDimensionKey& eventKey,
sp<ConditionWizard> wizard, int conditionIndex,
const vector<Matcher>& dimensionInCondition, bool nesting,
- uint64_t currentBucketStartNs, uint64_t currentBucketNum,
- uint64_t startTimeNs, uint64_t bucketSizeNs,
+ int64_t currentBucketStartNs, int64_t currentBucketNum,
+ int64_t startTimeNs, int64_t bucketSizeNs,
bool conditionSliced, bool fullLink,
const vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
: DurationTracker(key, id, eventKey, wizard, conditionIndex, dimensionInCondition, nesting,
@@ -41,7 +41,7 @@
}
}
-unique_ptr<DurationTracker> MaxDurationTracker::clone(const uint64_t eventTime) {
+unique_ptr<DurationTracker> MaxDurationTracker::clone(const int64_t eventTime) {
auto clonedTracker = make_unique<MaxDurationTracker>(*this);
for (auto it = clonedTracker->mInfos.begin(); it != clonedTracker->mInfos.end();) {
if (it->second.state != kStopped) {
@@ -80,7 +80,7 @@
}
void MaxDurationTracker::noteStart(const HashableDimensionKey& key, bool condition,
- const uint64_t eventTime, const ConditionKey& conditionKey) {
+ const int64_t eventTime, const ConditionKey& conditionKey) {
// this will construct a new DurationInfo if this key didn't exist.
if (hitGuardRail(key)) {
return;
@@ -114,7 +114,7 @@
}
-void MaxDurationTracker::noteStop(const HashableDimensionKey& key, const uint64_t eventTime,
+void MaxDurationTracker::noteStop(const HashableDimensionKey& key, const int64_t eventTime,
bool forceStop) {
VLOG("MaxDuration: key %s stop", key.toString().c_str());
if (mInfos.find(key) == mInfos.end()) {
@@ -175,7 +175,7 @@
return false;
}
-void MaxDurationTracker::noteStopAll(const uint64_t eventTime) {
+void MaxDurationTracker::noteStopAll(const int64_t eventTime) {
std::set<HashableDimensionKey> keys;
for (const auto& pair : mInfos) {
keys.insert(pair.first);
@@ -186,14 +186,14 @@
}
bool MaxDurationTracker::flushCurrentBucket(
- const uint64_t& eventTimeNs,
+ const int64_t& eventTimeNs,
std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) {
VLOG("MaxDurationTracker flushing.....");
// adjust the bucket start time
int numBucketsForward = 0;
- uint64_t fullBucketEnd = getCurrentBucketEndTimeNs();
- uint64_t currentBucketEndTimeNs;
+ int64_t fullBucketEnd = getCurrentBucketEndTimeNs();
+ int64_t currentBucketEndTimeNs;
if (eventTimeNs >= fullBucketEnd) {
numBucketsForward = 1 + (eventTimeNs - fullBucketEnd) / mBucketSizeNs;
currentBucketEndTimeNs = fullBucketEnd;
@@ -238,7 +238,7 @@
}
bool MaxDurationTracker::flushIfNeeded(
- uint64_t eventTimeNs, unordered_map<MetricDimensionKey, vector<DurationBucket>>* output) {
+ int64_t eventTimeNs, unordered_map<MetricDimensionKey, vector<DurationBucket>>* output) {
if (eventTimeNs < getCurrentBucketEndTimeNs()) {
return false;
}
@@ -246,7 +246,7 @@
}
void MaxDurationTracker::onSlicedConditionMayChange(bool overallCondition,
- const uint64_t timestamp) {
+ const int64_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) {
@@ -268,14 +268,14 @@
}
}
-void MaxDurationTracker::onConditionChanged(bool condition, const uint64_t timestamp) {
+void MaxDurationTracker::onConditionChanged(bool condition, const int64_t timestamp) {
for (auto& pair : mInfos) {
noteConditionChanged(pair.first, condition, timestamp);
}
}
void MaxDurationTracker::noteConditionChanged(const HashableDimensionKey& key, bool conditionMet,
- const uint64_t timestamp) {
+ const int64_t timestamp) {
auto it = mInfos.find(key);
if (it == mInfos.end()) {
return;
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
index 884e8ac..8e8f2cd 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
@@ -31,30 +31,30 @@
MaxDurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
sp<ConditionWizard> wizard, int conditionIndex,
const std::vector<Matcher>& dimensionInCondition, bool nesting,
- uint64_t currentBucketStartNs, uint64_t currentBucketNum,
- uint64_t startTimeNs, uint64_t bucketSizeNs, bool conditionSliced,
+ int64_t currentBucketStartNs, int64_t currentBucketNum,
+ int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced,
bool fullLink,
const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers);
MaxDurationTracker(const MaxDurationTracker& tracker) = default;
- unique_ptr<DurationTracker> clone(const uint64_t eventTime) override;
+ unique_ptr<DurationTracker> clone(const int64_t eventTime) override;
- void noteStart(const HashableDimensionKey& key, bool condition, const uint64_t eventTime,
+ void noteStart(const HashableDimensionKey& key, bool condition, const int64_t eventTime,
const ConditionKey& conditionKey) override;
- void noteStop(const HashableDimensionKey& key, const uint64_t eventTime,
+ void noteStop(const HashableDimensionKey& key, const int64_t eventTime,
const bool stopAll) override;
- void noteStopAll(const uint64_t eventTime) override;
+ void noteStopAll(const int64_t eventTime) override;
bool flushIfNeeded(
- uint64_t timestampNs,
+ int64_t timestampNs,
std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) override;
bool flushCurrentBucket(
- const uint64_t& eventTimeNs,
+ const int64_t& eventTimeNs,
std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>*) override;
- void onSlicedConditionMayChange(bool overallCondition, const uint64_t timestamp) override;
- void onConditionChanged(bool condition, const uint64_t timestamp) override;
+ void onSlicedConditionMayChange(bool overallCondition, const int64_t timestamp) override;
+ void onConditionChanged(bool condition, const int64_t timestamp) override;
int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
const int64_t currentTimestamp) const override;
@@ -67,7 +67,7 @@
std::unordered_map<HashableDimensionKey, DurationInfo> mInfos;
void noteConditionChanged(const HashableDimensionKey& key, bool conditionMet,
- const uint64_t timestamp);
+ const int64_t timestamp);
// return true if we should not allow newKey to be tracked because we are above the threshold
bool hitGuardRail(const HashableDimensionKey& newKey);
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
index 50db9a0..b833dfc 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
@@ -27,8 +27,8 @@
OringDurationTracker::OringDurationTracker(
const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
sp<ConditionWizard> wizard, int conditionIndex, const vector<Matcher>& dimensionInCondition,
- bool nesting, uint64_t currentBucketStartNs, uint64_t currentBucketNum,
- uint64_t startTimeNs, uint64_t bucketSizeNs, bool conditionSliced, bool fullLink,
+ bool nesting, int64_t currentBucketStartNs, int64_t currentBucketNum,
+ int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced, bool fullLink,
const vector<sp<DurationAnomalyTracker>>& anomalyTrackers)
: DurationTracker(key, id, eventKey, wizard, conditionIndex, dimensionInCondition, nesting,
currentBucketStartNs, currentBucketNum, startTimeNs, bucketSizeNs,
@@ -42,7 +42,7 @@
}
}
-unique_ptr<DurationTracker> OringDurationTracker::clone(const uint64_t eventTime) {
+unique_ptr<DurationTracker> OringDurationTracker::clone(const int64_t eventTime) {
auto clonedTracker = make_unique<OringDurationTracker>(*this);
clonedTracker->mLastStartTime = eventTime;
clonedTracker->mDuration = 0;
@@ -69,7 +69,7 @@
}
void OringDurationTracker::noteStart(const HashableDimensionKey& key, bool condition,
- const uint64_t eventTime, const ConditionKey& conditionKey) {
+ const int64_t eventTime, const ConditionKey& conditionKey) {
if (hitGuardRail(key)) {
return;
}
@@ -90,7 +90,7 @@
VLOG("Oring: %s start, condition %d", key.toString().c_str(), condition);
}
-void OringDurationTracker::noteStop(const HashableDimensionKey& key, const uint64_t timestamp,
+void OringDurationTracker::noteStop(const HashableDimensionKey& key, const int64_t timestamp,
const bool stopAll) {
VLOG("Oring: %s stop", key.toString().c_str());
auto it = mStarted.find(key);
@@ -121,7 +121,7 @@
}
}
-void OringDurationTracker::noteStopAll(const uint64_t timestamp) {
+void OringDurationTracker::noteStopAll(const int64_t timestamp) {
if (!mStarted.empty()) {
mDuration += (timestamp - mLastStartTime);
VLOG("Oring Stop all: record duration %lld %lld ", (long long)timestamp - mLastStartTime,
@@ -136,7 +136,7 @@
}
bool OringDurationTracker::flushCurrentBucket(
- const uint64_t& eventTimeNs,
+ const int64_t& eventTimeNs,
std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) {
VLOG("OringDurationTracker Flushing.............");
@@ -144,8 +144,8 @@
// MetricProducer#notifyAppUpgrade.
int numBucketsForward = 0;
- uint64_t fullBucketEnd = getCurrentBucketEndTimeNs();
- uint64_t currentBucketEndTimeNs;
+ int64_t fullBucketEnd = getCurrentBucketEndTimeNs();
+ int64_t currentBucketEndTimeNs;
if (eventTimeNs >= fullBucketEnd) {
numBucketsForward = 1 + (eventTimeNs - fullBucketEnd) / mBucketSizeNs;
@@ -207,7 +207,7 @@
}
bool OringDurationTracker::flushIfNeeded(
- uint64_t eventTimeNs, unordered_map<MetricDimensionKey, vector<DurationBucket>>* output) {
+ int64_t eventTimeNs, unordered_map<MetricDimensionKey, vector<DurationBucket>>* output) {
if (eventTimeNs < getCurrentBucketEndTimeNs()) {
return false;
}
@@ -215,7 +215,7 @@
}
void OringDurationTracker::onSlicedConditionMayChange(bool overallCondition,
- const uint64_t timestamp) {
+ const int64_t timestamp) {
vector<pair<HashableDimensionKey, int>> startedToPaused;
vector<pair<HashableDimensionKey, int>> pausedToStarted;
if (!mStarted.empty()) {
@@ -297,7 +297,7 @@
}
}
-void OringDurationTracker::onConditionChanged(bool condition, const uint64_t timestamp) {
+void OringDurationTracker::onConditionChanged(bool condition, const int64_t timestamp) {
if (condition) {
if (!mPaused.empty()) {
VLOG("Condition true, all started");
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
index 987e28e..8e73256 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
@@ -30,29 +30,29 @@
OringDurationTracker(const ConfigKey& key, const int64_t& id,
const MetricDimensionKey& eventKey, sp<ConditionWizard> wizard,
int conditionIndex, const std::vector<Matcher>& dimensionInCondition,
- bool nesting, uint64_t currentBucketStartNs, uint64_t currentBucketNum,
- uint64_t startTimeNs, uint64_t bucketSizeNs, bool conditionSliced,
+ bool nesting, int64_t currentBucketStartNs, int64_t currentBucketNum,
+ int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced,
bool fullLink,
const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers);
OringDurationTracker(const OringDurationTracker& tracker) = default;
- unique_ptr<DurationTracker> clone(const uint64_t eventTime) override;
+ unique_ptr<DurationTracker> clone(const int64_t eventTime) override;
- void noteStart(const HashableDimensionKey& key, bool condition, const uint64_t eventTime,
+ void noteStart(const HashableDimensionKey& key, bool condition, const int64_t eventTime,
const ConditionKey& conditionKey) override;
- void noteStop(const HashableDimensionKey& key, const uint64_t eventTime,
+ void noteStop(const HashableDimensionKey& key, const int64_t eventTime,
const bool stopAll) override;
- void noteStopAll(const uint64_t eventTime) override;
+ void noteStopAll(const int64_t eventTime) override;
- void onSlicedConditionMayChange(bool overallCondition, const uint64_t timestamp) override;
- void onConditionChanged(bool condition, const uint64_t timestamp) override;
+ void onSlicedConditionMayChange(bool overallCondition, const int64_t timestamp) override;
+ void onConditionChanged(bool condition, const int64_t timestamp) override;
bool flushCurrentBucket(
- const uint64_t& eventTimeNs,
+ const int64_t& eventTimeNs,
std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) override;
bool flushIfNeeded(
- uint64_t timestampNs,
+ int64_t timestampNs,
std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) override;
int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
diff --git a/cmds/statsd/src/packages/PackageInfoListener.h b/cmds/statsd/src/packages/PackageInfoListener.h
index 03cb364..fcdbe69 100644
--- a/cmds/statsd/src/packages/PackageInfoListener.h
+++ b/cmds/statsd/src/packages/PackageInfoListener.h
@@ -28,15 +28,15 @@
public:
// Uid map will notify this listener that the app with apk name and uid has been upgraded to
// the specified version.
- virtual void notifyAppUpgrade(const uint64_t& eventTimeNs, const std::string& apk,
+ virtual void notifyAppUpgrade(const int64_t& eventTimeNs, const std::string& apk,
const int uid, const int64_t version) = 0;
// Notify interested listeners that the given apk and uid combination no longer exits.
- virtual void notifyAppRemoved(const uint64_t& eventTimeNs, const std::string& apk,
+ virtual void notifyAppRemoved(const int64_t& eventTimeNs, const std::string& apk,
const int uid) = 0;
// Notify the listener that the UidMap snapshot is available.
- virtual void onUidMapReceived(const uint64_t& eventTimeNs) = 0;
+ virtual void onUidMapReceived(const int64_t& eventTimeNs) = 0;
};
} // namespace statsd
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index 9fd17b6..4aa3c973 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -234,6 +234,7 @@
optional int64 id = 2;
optional int32 creation_time_sec = 3;
optional int32 deletion_time_sec = 4;
+ optional int32 reset_time_sec = 19;
optional int32 metric_count = 5;
optional int32 condition_count = 6;
optional int32 matcher_count = 7;
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index 687f5ea..870f92e 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -354,6 +354,8 @@
}
repeated Annotation annotation = 14;
+ optional int64 ttl_in_seconds = 15;
+
// Field number 1000 is reserved for later use.
reserved 1000;
}
diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp
index 643d2bf..ea8da14 100644
--- a/cmds/statsd/src/storage/StorageManager.cpp
+++ b/cmds/statsd/src/storage/StorageManager.cpp
@@ -252,8 +252,13 @@
}
}
-bool StorageManager::hasIdenticalConfig(const ConfigKey& key,
- const vector<uint8_t>& config) {
+bool StorageManager::readConfigFromDisk(const ConfigKey& key, StatsdConfig* config) {
+ string content;
+ return config != nullptr &&
+ StorageManager::readConfigFromDisk(key, &content) && config->ParseFromString(content);
+}
+
+bool StorageManager::readConfigFromDisk(const ConfigKey& key, string* content) {
unique_ptr<DIR, decltype(&closedir)> dir(opendir(STATS_SERVICE_DIR),
closedir);
if (dir == NULL) {
@@ -262,7 +267,6 @@
}
string suffix = StringPrintf("%d_%lld", key.GetUid(), (long long)key.GetId());
-
dirent* de;
while ((de = readdir(dir.get()))) {
char* name = de->d_name;
@@ -277,13 +281,8 @@
int fd = open(StringPrintf("%s/%s", STATS_SERVICE_DIR, name).c_str(),
O_RDONLY | O_CLOEXEC);
if (fd != -1) {
- string content;
- if (android::base::ReadFdToString(fd, &content)) {
- vector<uint8_t> vec(content.begin(), content.end());
- if (vec == config) {
- close(fd);
- return true;
- }
+ if (android::base::ReadFdToString(fd, content)) {
+ return true;
}
close(fd);
}
@@ -292,6 +291,18 @@
return false;
}
+bool StorageManager::hasIdenticalConfig(const ConfigKey& key,
+ const vector<uint8_t>& config) {
+ string content;
+ if (StorageManager::readConfigFromDisk(key, &content)) {
+ vector<uint8_t> vec(content.begin(), content.end());
+ if (vec == config) {
+ return true;
+ }
+ }
+ return false;
+}
+
void StorageManager::trimToFit(const char* path) {
unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
if (dir == NULL) {
diff --git a/cmds/statsd/src/storage/StorageManager.h b/cmds/statsd/src/storage/StorageManager.h
index fb7b085..8953be9 100644
--- a/cmds/statsd/src/storage/StorageManager.h
+++ b/cmds/statsd/src/storage/StorageManager.h
@@ -74,6 +74,13 @@
static void readConfigFromDisk(std::map<ConfigKey, StatsdConfig>& configsMap);
/**
+ * Call to load the specified config from disk. Returns false if the config file does not
+ * exist or error occurs when reading the file.
+ */
+ static bool readConfigFromDisk(const ConfigKey& key, StatsdConfig* config);
+ static bool readConfigFromDisk(const ConfigKey& key, string* config);
+
+ /**
* Trims files in the provided directory to limit the total size, number of
* files, accumulation of outdated files.
*/