Add uid field annotation in atoms.proto and statd memory usage optimization.
[memory]
statsd binary size from 664k -> 600k
memory usage 1978k -> 1813k (with no configs)
+ Avoid initialize any static map in statslog.h to avoid many copies of the map in each include.
- Do it in cpp so that it is initialized only in places that use them
[Uid annotation]
+ Uid annotation is needed for extracting uid from dimension for UidCpuPuller.
+ After the change, stand-alone uids don't need to be in field 1 anymore.
+ Also added exclusive bit annotation in AppDied
+ Currently only allow one uid field in an Atom. This is to keep things simple until
we find an exception.
Test: statsd_test
Bug: 73958484
Bug: 72129300
Change-Id: I8a916d5c00d5930e24ae7e0825a57dea19c0e744
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 652ec9d..8b681edd 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -112,8 +112,8 @@
}
void StatsLogProcessor::mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const {
- if (android::util::kAtomsWithAttributionChain.find(event->GetTagId()) !=
- android::util::kAtomsWithAttributionChain.end()) {
+ if (android::util::AtomsInfo::kAtomsWithAttributionChain.find(event->GetTagId()) !=
+ android::util::AtomsInfo::kAtomsWithAttributionChain.end()) {
for (auto& value : *(event->getMutableValues())) {
if (value.mField.getPosAtDepth(0) > kAttributionField) {
break;
@@ -123,12 +123,20 @@
updateUid(&value.mValue, hostUid);
}
}
- } else if (android::util::kAtomsWithUidField.find(event->GetTagId()) !=
- android::util::kAtomsWithUidField.end() &&
- event->getValues().size() > 0 && (event->getValues())[0].mValue.getType() == INT) {
- Value& value = (*event->getMutableValues())[0].mValue;
- const int hostUid = mUidMap->getHostUidOrSelf(value.int_value);
- updateUid(&value, hostUid);
+ } else {
+ auto it = android::util::AtomsInfo::kAtomsWithUidField.find(event->GetTagId());
+ if (it != android::util::AtomsInfo::kAtomsWithUidField.end()) {
+ int uidField = it->second; // uidField is the field number in proto,
+ // starting from 1
+ if (uidField > 0 && (int)event->getValues().size() >= uidField &&
+ (event->getValues())[uidField - 1].mValue.getType() == INT) {
+ Value& value = (*event->getMutableValues())[uidField - 1].mValue;
+ const int hostUid = mUidMap->getHostUidOrSelf(value.int_value);
+ updateUid(&value, hostUid);
+ } else {
+ ALOGE("Malformed log, uid not found. %s", event->ToString().c_str());
+ }
+ }
}
}
diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto
index 19d00b7..a2a03b1 100644
--- a/cmds/statsd/src/atom_field_options.proto
+++ b/cmds/statsd/src/atom_field_options.proto
@@ -67,4 +67,7 @@
extend google.protobuf.FieldOptions {
// Flags to decorate an atom that presents a state change.
optional StateAtomFieldOption stateFieldOption = 50000;
+
+ // Flags to decorate the uid fields in an atom.
+ optional bool is_uid = 50001 [default = false];
}
\ No newline at end of file
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 298f494..2d766be 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -208,7 +208,7 @@
* frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
*/
message UidProcessStateChanged {
- optional int32 uid = 1 [(stateFieldOption).option = PRIMARY];
+ optional int32 uid = 1 [(stateFieldOption).option = PRIMARY, (is_uid) = true];
// The state, from frameworks/base/core/proto/android/app/enums.proto.
optional android.app.ProcessStateEnum state = 2 [(stateFieldOption).option = EXCLUSIVE];
@@ -222,7 +222,7 @@
*/
message ProcessLifeCycleStateChanged {
// TODO: should be a string tagged w/ uid annotation
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
// The process name (usually same as the app name).
optional string name = 2;
@@ -592,7 +592,7 @@
*/
message MobileRadioPowerStateChanged {
// TODO: Add attribution instead of uid?
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
// Power state, from frameworks/base/core/proto/android/telephony/enums.proto.
optional android.telephony.DataConnectionPowerStateEnum state = 2;
@@ -607,7 +607,7 @@
*/
message WifiRadioPowerStateChanged {
// TODO: Add attribution instead of uid?
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
// Power state, from frameworks/base/core/proto/android/telephony/enums.proto.
optional android.telephony.DataConnectionPowerStateEnum state = 2;
@@ -1079,7 +1079,8 @@
*/
message DaveyOccurred {
// The UID that logged this atom.
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
+ ;
// Amount of time it took to render the frame. Should be >=700ms.
optional int64 jank_duration_millis = 2;
@@ -1136,7 +1137,7 @@
* frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java
*/
message ActivityForegroundStateChanged {
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
optional string pkg_name = 2;
optional string class_name = 3;
@@ -1154,7 +1155,7 @@
*/
message DropboxErrorChanged {
// The uid if available. -1 means not available.
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
// Tag used when recording this error to dropbox. Contains data_ or system_ prefix.
optional string tag = 2;
@@ -1185,7 +1186,7 @@
*/
message AppBreadcrumbReported {
// The uid of the application that sent this custom atom.
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
// An arbitrary label chosen by the developer. For Android P, the label should be in [0, 16).
optional int32 label = 2;
@@ -1209,7 +1210,7 @@
*/
message AnomalyDetected {
// Uid that owns the config whose anomaly detection alert fired.
- optional int32 config_uid = 1;
+ optional int32 config_uid = 1 [(is_uid) = true];
// Id of the config whose anomaly detection alert fired.
optional int64 config_id = 2;
@@ -1220,7 +1221,7 @@
message AppStartChanged {
// The uid if available. -1 means not available.
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
// The app package name.
optional string pkg_name = 2;
@@ -1267,7 +1268,7 @@
message AppStartCancelChanged {
// The uid if available. -1 means not available.
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
// The app package name.
optional string pkg_name = 2;
@@ -1287,7 +1288,7 @@
message AppStartFullyDrawnChanged {
// The uid if available. -1 means not available.
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
// The app package name.
optional string pkg_name = 2;
@@ -1318,7 +1319,7 @@
*/
message PictureInPictureStateChanged {
// -1 if it is not available
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
optional string short_name = 2;
@@ -1337,7 +1338,7 @@
* services/core/java/com/android/server/wm/Session.java
*/
message OverlayStateChanged {
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
optional string package_name = 2;
@@ -1358,7 +1359,7 @@
* //frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
*/
message ForegroundServiceStateChanged {
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
// package_name + "/" + class_name
optional string short_name = 2;
@@ -1378,6 +1379,7 @@
* frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
*/
message IsolatedUidChanged {
+ // NOTE: DO NOT annotate uid field in this atom. This atom is specially handled in statsd.
// The host UID. Generally, we should attribute metrics from the isolated uid to the host uid.
optional int32 parent_uid = 1;
@@ -1399,7 +1401,7 @@
message PacketWakeupOccurred {
// The uid owning the socket into which the packet was delivered, or -1 if the packet was
// delivered nowhere.
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
// The interface name on which the packet was received.
optional string iface = 2;
// The ethertype value of the packet.
@@ -1427,7 +1429,7 @@
*/
message AppStartMemoryStateCaptured {
// The uid if available. -1 means not available.
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
// The process name.
optional string process_name = 2;
@@ -1473,7 +1475,7 @@
*/
message LmkKillOccurred {
// The uid if available. -1 means not available.
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
// The process name.
optional string process_name = 2;
@@ -1505,7 +1507,7 @@
*/
message AppDied {
// timestamp(elapsedRealtime) of record creation
- optional uint64 timestamp_millis = 1;
+ optional uint64 timestamp_millis = 1 [(stateFieldOption).option = EXCLUSIVE];
}
//////////////////////////////////////////////////////////////////////
@@ -1519,7 +1521,7 @@
* StatsCompanionService (using BatteryStats to get which interfaces are wifi)
*/
message WifiBytesTransfer {
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
optional int64 rx_bytes = 2;
@@ -1537,9 +1539,10 @@
* StatsCompanionService (using BatteryStats to get which interfaces are wifi)
*/
message WifiBytesTransferByFgBg {
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
- // 1 denotes foreground and 0 denotes background. This is called Set in NetworkStats.
+ // 1 denotes foreground and 0 denotes background. This is called Set in
+ // NetworkStats.
optional int32 is_foreground = 2;
optional int64 rx_bytes = 3;
@@ -1558,7 +1561,7 @@
* StatsCompanionService (using BatteryStats to get which interfaces are mobile data)
*/
message MobileBytesTransfer {
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
optional int64 rx_bytes = 2;
@@ -1576,9 +1579,10 @@
* StatsCompanionService (using BatteryStats to get which interfaces are mobile data)
*/
message MobileBytesTransferByFgBg {
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
- // 1 denotes foreground and 0 denotes background. This is called Set in NetworkStats.
+ // 1 denotes foreground and 0 denotes background. This is called Set in
+ // NetworkStats.
optional int32 is_foreground = 2;
optional int64 rx_bytes = 3;
@@ -1597,7 +1601,7 @@
* StatsCompanionService
*/
message BluetoothBytesTransfer {
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
optional int64 rx_bytes = 2;
@@ -1657,7 +1661,7 @@
* Note that isolated process uid time should be attributed to host uids.
*/
message CpuTimePerUid {
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
optional uint64 user_time_millis = 2;
optional uint64 sys_time_millis = 3;
}
@@ -1668,7 +1672,7 @@
* For each uid, we order the time by descending frequencies.
*/
message CpuTimePerUidFreq {
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
optional uint32 freq_index = 2;
optional uint64 time_millis = 3;
}
@@ -1750,7 +1754,7 @@
*/
message ProcessMemoryState {
// The uid if available. -1 means not available.
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
// The process name.
optional string process_name = 2;
@@ -1802,7 +1806,7 @@
* The file contains a monotonically increasing count of time for a single boot.
*/
message CpuActiveTime {
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
optional uint64 time_millis = 2;
}
@@ -1816,7 +1820,7 @@
* The file contains a monotonically increasing count of time for a single boot.
*/
message CpuClusterTime {
- optional int32 uid = 1;
+ optional int32 uid = 1 [(is_uid) = true];
optional int32 cluster_index = 2;
optional uint64 time_millis = 3;
}
diff --git a/cmds/statsd/src/external/puller_util.cpp b/cmds/statsd/src/external/puller_util.cpp
index 0b0c5c4..ea23623 100644
--- a/cmds/statsd/src/external/puller_util.cpp
+++ b/cmds/statsd/src/external/puller_util.cpp
@@ -112,7 +112,8 @@
VLOG("Unknown pull atom id %d", tagId);
return;
}
- if (android::util::kAtomsWithUidField.find(tagId) == android::util::kAtomsWithUidField.end()) {
+ if (android::util::AtomsInfo::kAtomsWithUidField.find(tagId) ==
+ android::util::AtomsInfo::kAtomsWithUidField.end()) {
VLOG("No uid to merge for atom %d", tagId);
return;
}
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index 778eb8e..bd8b293 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -134,8 +134,8 @@
uint64_t wrapperToken =
mProto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
const bool truncateTimestamp =
- android::util::kNotTruncatingTimestampAtomWhiteList.find(event.GetTagId()) ==
- android::util::kNotTruncatingTimestampAtomWhiteList.end();
+ android::util::AtomsInfo::kNotTruncatingTimestampAtomWhiteList.find(event.GetTagId()) ==
+ android::util::AtomsInfo::kNotTruncatingTimestampAtomWhiteList.end();
if (truncateTimestamp) {
mProto->write(FIELD_TYPE_INT64 | FIELD_ID_ELAPSED_TIMESTAMP_NANOS,
(long long)truncateTimestampNsToFiveMinutes(event.GetElapsedTimestampNs()));
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index 55a281e..49034ac 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -195,8 +195,9 @@
protoOutput->end(atomsToken);
}
const bool truncateTimestamp =
- android::util::kNotTruncatingTimestampAtomWhiteList.find(mTagId) ==
- android::util::kNotTruncatingTimestampAtomWhiteList.end();
+ android::util::AtomsInfo::kNotTruncatingTimestampAtomWhiteList.find(
+ mTagId) ==
+ android::util::AtomsInfo::kNotTruncatingTimestampAtomWhiteList.end();
const int64_t wall_clock_ns = truncateTimestamp ?
truncateTimestampNsToFiveMinutes(getWallClockNs()) : getWallClockNs();
for (const auto& atom : bucket.mGaugeAtoms) {
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index b5afef2..f6e10da 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -170,9 +170,10 @@
// 1. must not have "stop". must have "dimension"
if (!simplePredicate.has_stop() && simplePredicate.has_dimensions()) {
// TODO: need to check the start atom matcher too.
- auto it = android::util::kStateAtomsFieldOptions.find(simplePredicate.dimensions().field());
+ auto it = android::util::AtomsInfo::kStateAtomsFieldOptions.find(
+ simplePredicate.dimensions().field());
// 2. must be based on a state atom.
- if (it != android::util::kStateAtomsFieldOptions.end()) {
+ if (it != android::util::AtomsInfo::kStateAtomsFieldOptions.end()) {
// 3. dimension must be primary fields + state field IN ORDER
size_t expectedDimensionCount = it->second.primaryFields.size() + 1;
vector<Matcher> dimensions;