Add fallback in Network Tracing to old format
Perfetto has been updated to understand both the bundled and individual
packets, but the change hasn't yet hit stable. Until it does, fall back
to using the single event format.
Also fixes build warning from prior change.
Note: once the change hits Perfetto stable, the two formats behave
identically in the ui/querying/etc.
Bug: 246985031
Test: atest libnetworkstats_test
Change-Id: Ifc0e00f3c73aa1ef485f87f6ed4a9873c193ebb3
diff --git a/service-t/native/libs/libnetworkstats/NetworkTraceHandler.cpp b/service-t/native/libs/libnetworkstats/NetworkTraceHandler.cpp
index ded5eb3..33bc9f2 100644
--- a/service-t/native/libs/libnetworkstats/NetworkTraceHandler.cpp
+++ b/service-t/native/libs/libnetworkstats/NetworkTraceHandler.cpp
@@ -77,8 +77,9 @@
uint32_t bytes = 0;
};
-#define AGG_FIELDS(x) \
- x.ifindex, x.uid, x.tag, x.sport, x.dport, x.egress, x.ipProto, x.tcpFlags
+#define AGG_FIELDS(x) \
+ (x).ifindex, (x).uid, (x).tag, (x).sport, (x).dport, (x).egress, \
+ (x).ipProto, (x).tcpFlags
struct BundleHash {
std::size_t operator()(const BundleKey& a) const {
@@ -151,6 +152,17 @@
void NetworkTraceHandler::Write(const std::vector<PacketTrace>& packets,
NetworkTraceHandler::TraceContext& ctx) {
+ // TODO: remove this fallback once Perfetto stable has support for bundles.
+ if (!mInternLimit && !mAggregationThreshold) {
+ for (const PacketTrace& pkt : packets) {
+ auto dst = ctx.NewTracePacket();
+ dst->set_timestamp(pkt.timestampNs);
+ auto* event = dst->set_network_packet();
+ event->set_length(pkt.length);
+ Fill(pkt, event);
+ }
+ return;
+ }
std::unordered_map<BundleKey, BundleDetails, BundleHash, BundleEq> bundles;
for (const PacketTrace& pkt : packets) {
BundleDetails& bundle = bundles[pkt];
diff --git a/service-t/native/libs/libnetworkstats/NetworkTraceHandlerTest.cpp b/service-t/native/libs/libnetworkstats/NetworkTraceHandlerTest.cpp
index d943ae0..e92c5f0 100644
--- a/service-t/native/libs/libnetworkstats/NetworkTraceHandlerTest.cpp
+++ b/service-t/native/libs/libnetworkstats/NetworkTraceHandlerTest.cpp
@@ -20,6 +20,7 @@
#include <vector>
#include "netdbpf/NetworkTraceHandler.h"
+#include "protos/perfetto/config/android/network_trace_config.gen.h"
#include "protos/perfetto/trace/android/network_trace.pb.h"
#include "protos/perfetto/trace/trace.pb.h"
#include "protos/perfetto/trace/trace_packet.pb.h"
@@ -27,6 +28,7 @@
namespace android {
namespace bpf {
using ::perfetto::protos::NetworkPacketEvent;
+using ::perfetto::protos::NetworkPacketTraceConfig;
using ::perfetto::protos::Trace;
using ::perfetto::protos::TracePacket;
using ::perfetto::protos::TrafficDirection;
@@ -42,7 +44,8 @@
class NetworkTraceHandlerTest : public testing::Test {
protected:
// Starts a tracing session with the handler under test.
- std::unique_ptr<perfetto::TracingSession> StartTracing() {
+ std::unique_ptr<perfetto::TracingSession> StartTracing(
+ NetworkPacketTraceConfig settings) {
perfetto::TracingInitArgs args;
args.backends = perfetto::kInProcessBackend;
perfetto::Tracing::Initialize(args);
@@ -53,7 +56,9 @@
perfetto::TraceConfig cfg;
cfg.add_buffers()->set_size_kb(1024);
- cfg.add_data_sources()->mutable_config()->set_name("test.network_packets");
+ auto* config = cfg.add_data_sources()->mutable_config();
+ config->set_name("test.network_packets");
+ config->set_network_packet_trace_config_raw(settings.SerializeAsString());
auto session = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
session->Setup(cfg);
@@ -86,8 +91,9 @@
// This runs a trace with a single call to Write.
bool TraceAndSortPackets(const std::vector<PacketTrace>& input,
- std::vector<TracePacket>* output) {
- auto session = StartTracing();
+ std::vector<TracePacket>* output,
+ NetworkPacketTraceConfig config = {}) {
+ auto session = StartTracing(config);
HandlerForTest::Trace([&](HandlerForTest::TraceContext ctx) {
ctx.GetDataSourceLocked()->Write(input, ctx);
ctx.Flush();
@@ -125,12 +131,11 @@
ASSERT_EQ(events.size(), 1);
EXPECT_THAT(events[0].timestamp(), 1000);
- EXPECT_THAT(events[0].network_packet_bundle().ctx().uid(), 10);
- EXPECT_THAT(events[0].network_packet_bundle().ctx().tag(), 123);
- EXPECT_THAT(events[0].network_packet_bundle().ctx().ip_proto(), 6);
- EXPECT_THAT(events[0].network_packet_bundle().ctx().tcp_flags(), 1);
- EXPECT_THAT(events[0].network_packet_bundle().packet_lengths(),
- testing::ElementsAre(100));
+ EXPECT_THAT(events[0].network_packet().uid(), 10);
+ EXPECT_THAT(events[0].network_packet().tag(), 123);
+ EXPECT_THAT(events[0].network_packet().ip_proto(), 6);
+ EXPECT_THAT(events[0].network_packet().tcp_flags(), 1);
+ EXPECT_THAT(events[0].network_packet().length(), 100);
}
TEST_F(NetworkTraceHandlerTest, WriteDirectionAndPorts) {
@@ -153,17 +158,22 @@
ASSERT_TRUE(TraceAndSortPackets(input, &events));
ASSERT_EQ(events.size(), 2);
- EXPECT_THAT(events[0].network_packet_bundle().ctx().local_port(), 8080);
- EXPECT_THAT(events[0].network_packet_bundle().ctx().remote_port(), 443);
- EXPECT_THAT(events[0].network_packet_bundle().ctx().direction(),
+ EXPECT_THAT(events[0].network_packet().local_port(), 8080);
+ EXPECT_THAT(events[0].network_packet().remote_port(), 443);
+ EXPECT_THAT(events[0].network_packet().direction(),
TrafficDirection::DIR_EGRESS);
- EXPECT_THAT(events[1].network_packet_bundle().ctx().local_port(), 8080);
- EXPECT_THAT(events[1].network_packet_bundle().ctx().remote_port(), 443);
- EXPECT_THAT(events[1].network_packet_bundle().ctx().direction(),
+ EXPECT_THAT(events[1].network_packet().local_port(), 8080);
+ EXPECT_THAT(events[1].network_packet().remote_port(), 443);
+ EXPECT_THAT(events[1].network_packet().direction(),
TrafficDirection::DIR_INGRESS);
}
TEST_F(NetworkTraceHandlerTest, BasicBundling) {
+ // TODO: remove this once bundling becomes default. Until then, set arbitrary
+ // aggregation threshold to enable bundling.
+ NetworkPacketTraceConfig config;
+ config.set_aggregation_threshold(10);
+
std::vector<PacketTrace> input = {
PacketTrace{.uid = 123, .timestampNs = 2, .length = 200},
PacketTrace{.uid = 123, .timestampNs = 1, .length = 100},
@@ -174,7 +184,7 @@
};
std::vector<TracePacket> events;
- ASSERT_TRUE(TraceAndSortPackets(input, &events));
+ ASSERT_TRUE(TraceAndSortPackets(input, &events, config));
ASSERT_EQ(events.size(), 2);