enforce ttls for restricted metrics
Bug: 265020033
Bug: 267356499
Ignore-AOSP-First: android U feature
Test: statsd_test
Change-Id: I566d6de2f88286acad6157786a0f96a5ad840ece
diff --git a/statsd/src/logd/LogEvent.cpp b/statsd/src/logd/LogEvent.cpp
index 9f27d43..70d74aa 100644
--- a/statsd/src/logd/LogEvent.cpp
+++ b/statsd/src/logd/LogEvent.cpp
@@ -41,9 +41,8 @@
using std::string;
using std::vector;
-// TODO(b/265020033): Update this to use getWallClockNs()
LogEvent::LogEvent(int32_t uid, int32_t pid)
- : mLogdTimestampNs(time(nullptr)), mLogUid(uid), mLogPid(pid) {
+ : mLogdTimestampNs(getWallClockNs()), mLogUid(uid), mLogPid(pid) {
}
LogEvent::LogEvent(const string& trainName, int64_t trainVersionCode, bool requiresStaging,
diff --git a/statsd/src/metrics/MetricsManager.cpp b/statsd/src/metrics/MetricsManager.cpp
index ab418d1..b725f72 100644
--- a/statsd/src/metrics/MetricsManager.cpp
+++ b/statsd/src/metrics/MetricsManager.cpp
@@ -818,6 +818,11 @@
return;
}
sqlite3* db = dbutils::getDb(mConfigKey);
+ if (db == nullptr) {
+ ALOGE("Failed to open sqlite db");
+ dbutils::closeDb(db);
+ return;
+ }
for (const auto& producer : mAllMetricProducers) {
producer->enforceRestrictedDataTtl(db, wallClockNs);
}
diff --git a/statsd/src/metrics/RestrictedEventMetricProducer.cpp b/statsd/src/metrics/RestrictedEventMetricProducer.cpp
index 54dc642..752663a 100644
--- a/statsd/src/metrics/RestrictedEventMetricProducer.cpp
+++ b/statsd/src/metrics/RestrictedEventMetricProducer.cpp
@@ -12,6 +12,8 @@
namespace os {
namespace statsd {
+#define NS_PER_DAY (24 * 3600 * NS_PER_SEC)
+
RestrictedEventMetricProducer::RestrictedEventMetricProducer(
const ConfigKey& key, const EventMetric& metric, const int conditionIndex,
const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
@@ -19,10 +21,12 @@
const unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap,
const vector<int>& slicedStateAtoms,
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap)
+ const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap,
+ int restrictedDataTtlInDays)
: EventMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard, protoHash,
startTimeNs, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
- stateGroupMap) {
+ stateGroupMap),
+ mRestrictedDataTtlInDays(restrictedDataTtlInDays) {
}
void RestrictedEventMetricProducer::onMatchedLogEventInternalLocked(
@@ -68,6 +72,12 @@
}
}
+void RestrictedEventMetricProducer::enforceRestrictedDataTtl(sqlite3* db,
+ const int64_t wallClockNs) {
+ int64_t ttlTime = wallClockNs - mRestrictedDataTtlInDays * NS_PER_DAY;
+ dbutils::flushTtl(db, mMetricId, ttlTime);
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/statsd/src/metrics/RestrictedEventMetricProducer.h b/statsd/src/metrics/RestrictedEventMetricProducer.h
index 2158974..d285cc2 100644
--- a/statsd/src/metrics/RestrictedEventMetricProducer.h
+++ b/statsd/src/metrics/RestrictedEventMetricProducer.h
@@ -19,10 +19,13 @@
const std::unordered_map<int, std::vector<std::shared_ptr<Activation>>>&
eventDeactivationMap = {},
const vector<int>& slicedStateAtoms = {},
- const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap = {});
+ const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap = {},
+ const int restrictedDataTtlInDays = 7);
void onMetricRemove() override;
+ void enforceRestrictedDataTtl(sqlite3* db, const int64_t wallClockNs);
+
private:
void onMatchedLogEventInternalLocked(
const size_t matcherIndex, const MetricDimensionKey& eventKey,
@@ -35,6 +38,8 @@
android::util::ProtoOutputStream* protoOutput) override;
bool mIsMetricTableCreated = false;
+
+ const int32_t mRestrictedDataTtlInDays;
};
} // namespace statsd
diff --git a/statsd/tests/metrics/RestrictedEventMetricProducer_test.cpp b/statsd/tests/metrics/RestrictedEventMetricProducer_test.cpp
index 3554136..83469ba 100644
--- a/statsd/tests/metrics/RestrictedEventMetricProducer_test.cpp
+++ b/statsd/tests/metrics/RestrictedEventMetricProducer_test.cpp
@@ -190,6 +190,44 @@
EXPECT_FALSE(metricTableExist(metricId1));
}
+TEST_F(RestrictedEventMetricProducerTest, TestRestrictedEventMetricTtlDeletesFirstEvent) {
+ EventMetric metric;
+ metric.set_id(metricId1);
+ RestrictedEventMetricProducer producer(configKey, metric,
+ /*conditionIndex=*/-1,
+ /*initialConditionCache=*/{}, new ConditionWizard(),
+ /*protoHash=*/0x1234567890,
+ /*startTimeNs=*/0);
+
+ int64_t currentTimeNs = getWallClockNs();
+ int64_t eightDaysAgo = currentTimeNs - 8 * 24 * 3600 * NS_PER_SEC;
+ std::unique_ptr<LogEvent> event1 = CreateRestrictedLogEvent(/*atomTag=*/123, /*timestampNs=*/1);
+ event1->setLogdWallClockTimestampNs(eightDaysAgo);
+ std::unique_ptr<LogEvent> event2 = CreateRestrictedLogEvent(/*atomTag=*/123, /*timestampNs=*/3);
+ event2->setLogdWallClockTimestampNs(currentTimeNs);
+
+ producer.onMatchedLogEvent(/*matcherIndex=*/1, *event1);
+ producer.onMatchedLogEvent(/*matcherIndex=*/1, *event2);
+ sqlite3* dbHandle = dbutils::getDb(configKey);
+ producer.enforceRestrictedDataTtl(dbHandle, currentTimeNs + 100);
+ dbutils::closeDb(dbHandle);
+
+ std::stringstream query;
+ query << "SELECT * FROM metric_" << metricId1;
+ string err;
+ std::vector<int32_t> columnTypes;
+ std::vector<string> columnNames;
+ std::vector<std::vector<std::string>> rows;
+ dbutils::query(configKey, query.str(), rows, columnTypes, columnNames, err);
+ ASSERT_EQ(rows.size(), 1);
+ EXPECT_EQ(columnTypes.size(), 3 + event1->getValues().size());
+ EXPECT_THAT(columnNames,
+ ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
+ EXPECT_THAT(rows[0], ElementsAre(to_string(event2->GetTagId()),
+ to_string(event2->GetElapsedTimestampNs()),
+ to_string(currentTimeNs), _));
+}
+
} // namespace statsd
} // namespace os
} // namespace android