Add support for NetworkTrace aggregation threshold
The aggregation threshold determines the number of packets a particular
bundle has to hit before recording only aggregate results. This allows
individual high-throughput streams to be recorded at a significantly
reduced trace buffer cost.
Bug: 246985031
Test: atest libnetworkstats_test
Change-Id: I9e3c6f013db91919be541860364764e913726cf1
diff --git a/service-t/native/libs/libnetworkstats/NetworkTraceHandler.cpp b/service-t/native/libs/libnetworkstats/NetworkTraceHandler.cpp
index 33bc9f2..a9550b5 100644
--- a/service-t/native/libs/libnetworkstats/NetworkTraceHandler.cpp
+++ b/service-t/native/libs/libnetworkstats/NetworkTraceHandler.cpp
@@ -182,15 +182,22 @@
auto* event = dst->set_network_packet_bundle();
Fill(key, event->set_ctx());
- protozero::PackedVarInt offsets;
- protozero::PackedVarInt lengths;
- for (const auto& kv : details.time_and_len) {
- offsets.Append(kv.first - details.minTs);
- lengths.Append(kv.second);
- }
+ int count = details.time_and_len.size();
+ if (!mAggregationThreshold || count < mAggregationThreshold) {
+ protozero::PackedVarInt offsets;
+ protozero::PackedVarInt lengths;
+ for (const auto& kv : details.time_and_len) {
+ offsets.Append(kv.first - details.minTs);
+ lengths.Append(kv.second);
+ }
- event->set_packet_timestamps(offsets);
- event->set_packet_lengths(lengths);
+ event->set_packet_timestamps(offsets);
+ event->set_packet_lengths(lengths);
+ } else {
+ event->set_total_duration(details.maxTs - details.minTs);
+ event->set_total_length(details.bytes);
+ event->set_total_packets(count);
+ }
}
}
diff --git a/service-t/native/libs/libnetworkstats/NetworkTraceHandlerTest.cpp b/service-t/native/libs/libnetworkstats/NetworkTraceHandlerTest.cpp
index e92c5f0..6756fb0 100644
--- a/service-t/native/libs/libnetworkstats/NetworkTraceHandlerTest.cpp
+++ b/service-t/native/libs/libnetworkstats/NetworkTraceHandlerTest.cpp
@@ -203,5 +203,39 @@
testing::ElementsAre(0, 2));
}
+TEST_F(NetworkTraceHandlerTest, AggregationThreshold) {
+ // With an aggregation threshold of 3, the set of packets with uid=123 will
+ // be aggregated (3>=3) whereas packets with uid=456 get per-packet info.
+ NetworkPacketTraceConfig config;
+ config.set_aggregation_threshold(3);
+
+ std::vector<PacketTrace> input = {
+ PacketTrace{.uid = 123, .timestampNs = 2, .length = 200},
+ PacketTrace{.uid = 123, .timestampNs = 1, .length = 100},
+ PacketTrace{.uid = 123, .timestampNs = 4, .length = 300},
+
+ PacketTrace{.uid = 456, .timestampNs = 2, .length = 400},
+ PacketTrace{.uid = 456, .timestampNs = 4, .length = 100},
+ };
+
+ std::vector<TracePacket> events;
+ ASSERT_TRUE(TraceAndSortPackets(input, &events, config));
+
+ ASSERT_EQ(events.size(), 2);
+
+ EXPECT_EQ(events[0].timestamp(), 1);
+ EXPECT_EQ(events[0].network_packet_bundle().ctx().uid(), 123);
+ EXPECT_EQ(events[0].network_packet_bundle().total_duration(), 3);
+ EXPECT_EQ(events[0].network_packet_bundle().total_packets(), 3);
+ EXPECT_EQ(events[0].network_packet_bundle().total_length(), 600);
+
+ EXPECT_EQ(events[1].timestamp(), 2);
+ EXPECT_EQ(events[1].network_packet_bundle().ctx().uid(), 456);
+ EXPECT_THAT(events[1].network_packet_bundle().packet_lengths(),
+ testing::ElementsAre(400, 100));
+ EXPECT_THAT(events[1].network_packet_bundle().packet_timestamps(),
+ testing::ElementsAre(0, 2));
+}
+
} // namespace bpf
} // namespace android