@@ -121,9 +121,9 @@ void NetStreamHandler::process_sflow_cb(const SFSample &payload)
121121 _metrics->process_sflow (payload);
122122}
123123
124- void NetStreamHandler::process_dnstap_cb (const dnstap::Dnstap &payload)
124+ void NetStreamHandler::process_dnstap_cb (const dnstap::Dnstap &payload, size_t size )
125125{
126- _metrics->process_dnstap (payload);
126+ _metrics->process_dnstap (payload, size );
127127}
128128
129129void NetStreamHandler::process_udp_packet_cb (pcpp::Packet &payload, PacketDirection dir, pcpp::ProtocolType l3, [[maybe_unused]] uint32_t flowkey, timespec stamp)
@@ -139,6 +139,8 @@ void NetworkMetricsBucket::specialized_merge(const AbstractMetricsBucket &o)
139139 // rates maintain their own thread safety
140140 _rate_in.merge (other._rate_in );
141141 _rate_out.merge (other._rate_out );
142+ _throughput_in.merge (other._throughput_in );
143+ _throughput_out.merge (other._throughput_out );
142144
143145 std::shared_lock r_lock (other._mutex );
144146 std::unique_lock w_lock (_mutex);
@@ -166,13 +168,17 @@ void NetworkMetricsBucket::specialized_merge(const AbstractMetricsBucket &o)
166168 _topGeoLoc.merge (other._topGeoLoc );
167169 _topASN.merge (other._topASN );
168170 }
171+
172+ _payload_size.merge (other._payload_size );
169173}
170174
171175void NetworkMetricsBucket::to_prometheus (std::stringstream &out, Metric::LabelMap add_labels) const
172176{
173177
174178 _rate_in.to_prometheus (out, add_labels);
175179 _rate_out.to_prometheus (out, add_labels);
180+ _throughput_in.to_prometheus (out, add_labels);
181+ _throughput_out.to_prometheus (out, add_labels);
176182
177183 {
178184 auto [num_events, num_samples, event_rate, event_lock] = event_data_locked (); // thread safe
@@ -208,6 +214,8 @@ void NetworkMetricsBucket::to_prometheus(std::stringstream &out, Metric::LabelMa
208214 _topGeoLoc.to_prometheus (out, add_labels);
209215 _topASN.to_prometheus (out, add_labels);
210216 }
217+
218+ _payload_size.to_prometheus (out, add_labels);
211219}
212220
213221void NetworkMetricsBucket::to_json (json &j) const
@@ -217,6 +225,8 @@ void NetworkMetricsBucket::to_json(json &j) const
217225 bool live_rates = !read_only () && !recorded_stream ();
218226 _rate_in.to_json (j, live_rates);
219227 _rate_out.to_json (j, live_rates);
228+ _throughput_in.to_json (j, live_rates);
229+ _throughput_out.to_json (j, live_rates);
220230
221231 {
222232 auto [num_events, num_samples, event_rate, event_lock] = event_data_locked (); // thread safe
@@ -252,13 +262,15 @@ void NetworkMetricsBucket::to_json(json &j) const
252262 _topGeoLoc.to_json (j);
253263 _topASN.to_json (j);
254264 }
265+
266+ _payload_size.to_json (j);
255267}
256268
257269// the main bucket analysis
258270void NetworkMetricsBucket::process_packet (bool deep, pcpp::Packet &payload, PacketDirection dir, pcpp::ProtocolType l3, pcpp::ProtocolType l4)
259271{
260272 if (!deep) {
261- process_net_layer (dir, l3, l4);
273+ process_net_layer (dir, l3, l4, payload. getRawPacket ()-> getRawDataLen () );
262274 return ;
263275 }
264276
@@ -285,9 +297,9 @@ void NetworkMetricsBucket::process_packet(bool deep, pcpp::Packet &payload, Pack
285297 }
286298 }
287299
288- process_net_layer (dir, l3, l4, is_ipv6, ipv4_in, ipv4_out, ipv6_in, ipv6_out);
300+ process_net_layer (dir, l3, l4, payload. getRawPacket ()-> getRawDataLen (), is_ipv6, ipv4_in, ipv4_out, ipv6_in, ipv6_out);
289301}
290- void NetworkMetricsBucket::process_dnstap (bool deep, const dnstap::Dnstap &payload)
302+ void NetworkMetricsBucket::process_dnstap (bool deep, const dnstap::Dnstap &payload, size_t size )
291303{
292304 pcpp::ProtocolType l3;
293305 bool is_ipv6{false };
@@ -335,7 +347,7 @@ void NetworkMetricsBucket::process_dnstap(bool deep, const dnstap::Dnstap &paylo
335347 }
336348
337349 if (!deep) {
338- process_net_layer (dir, l3, l4);
350+ process_net_layer (dir, l3, l4, size );
339351 return ;
340352 }
341353
@@ -354,7 +366,7 @@ void NetworkMetricsBucket::process_dnstap(bool deep, const dnstap::Dnstap &paylo
354366 ipv6_out = pcpp::IPv6Address (reinterpret_cast <const uint8_t *>(payload.message ().response_address ().data ()));
355367 }
356368
357- process_net_layer (dir, l3, l4, is_ipv6, ipv4_in, ipv4_out, ipv6_in, ipv6_out);
369+ process_net_layer (dir, l3, l4, size, is_ipv6, ipv4_in, ipv4_out, ipv6_in, ipv6_out);
358370}
359371
360372void NetworkMetricsBucket::process_sflow (bool deep, const SFSample &payload)
@@ -385,7 +397,7 @@ void NetworkMetricsBucket::process_sflow(bool deep, const SFSample &payload)
385397 }
386398
387399 if (!deep) {
388- process_net_layer (dir, l3, l4);
400+ process_net_layer (dir, l3, l4, payload. rawSampleLen );
389401 return ;
390402 }
391403
@@ -410,20 +422,22 @@ void NetworkMetricsBucket::process_sflow(bool deep, const SFSample &payload)
410422 ipv6_out = pcpp::IPv6Address (sample.ipdst .address .ip_v6 .addr );
411423 }
412424
413- process_net_layer (dir, l3, l4, is_ipv6, ipv4_in, ipv4_out, ipv6_in, ipv6_out);
425+ process_net_layer (dir, l3, l4, payload. rawSampleLen , is_ipv6, ipv4_in, ipv4_out, ipv6_in, ipv6_out);
414426 }
415427}
416428
417- void NetworkMetricsBucket::process_net_layer (PacketDirection dir, pcpp::ProtocolType l3, pcpp::ProtocolType l4)
429+ void NetworkMetricsBucket::process_net_layer (PacketDirection dir, pcpp::ProtocolType l3, pcpp::ProtocolType l4, size_t payload_size )
418430{
419431 std::unique_lock lock (_mutex);
420432
421433 switch (dir) {
422434 case PacketDirection::fromHost:
423435 ++_rate_out;
436+ _throughput_out += payload_size;
424437 break ;
425438 case PacketDirection::toHost:
426439 ++_rate_in;
440+ _throughput_in += payload_size;
427441 break ;
428442 case PacketDirection::unknown:
429443 break ;
@@ -464,18 +478,22 @@ void NetworkMetricsBucket::process_net_layer(PacketDirection dir, pcpp::Protocol
464478 break ;
465479 }
466480 }
481+
482+ _payload_size.update (payload_size);
467483}
468484
469- void NetworkMetricsBucket::process_net_layer (PacketDirection dir, pcpp::ProtocolType l3, pcpp::ProtocolType l4, bool is_ipv6, pcpp::IPv4Address &ipv4_in, pcpp::IPv4Address &ipv4_out, pcpp::IPv6Address &ipv6_in, pcpp::IPv6Address &ipv6_out)
485+ void NetworkMetricsBucket::process_net_layer (PacketDirection dir, pcpp::ProtocolType l3, pcpp::ProtocolType l4, size_t payload_size, bool is_ipv6, pcpp::IPv4Address &ipv4_in, pcpp::IPv4Address &ipv4_out, pcpp::IPv6Address &ipv6_in, pcpp::IPv6Address &ipv6_out)
470486{
471487 std::unique_lock lock (_mutex);
472488
473489 switch (dir) {
474490 case PacketDirection::fromHost:
475491 ++_rate_out;
492+ _throughput_out += payload_size;
476493 break ;
477494 case PacketDirection::toHost:
478495 ++_rate_in;
496+ _throughput_in += payload_size;
479497 break ;
480498 case PacketDirection::unknown:
481499 break ;
@@ -517,6 +535,8 @@ void NetworkMetricsBucket::process_net_layer(PacketDirection dir, pcpp::Protocol
517535 }
518536 }
519537
538+ _payload_size.update (payload_size);
539+
520540 struct sockaddr_in sa4;
521541 struct sockaddr_in6 sa6;
522542
@@ -586,7 +606,7 @@ void NetworkMetricsManager::process_packet(pcpp::Packet &payload, PacketDirectio
586606 live_bucket ()->process_packet (_deep_sampling_now, payload, dir, l3, l4);
587607}
588608
589- void NetworkMetricsManager::process_dnstap (const dnstap::Dnstap &payload)
609+ void NetworkMetricsManager::process_dnstap (const dnstap::Dnstap &payload, size_t size )
590610{
591611 // dnstap message type
592612 auto mtype = payload.message ().type ();
@@ -616,7 +636,7 @@ void NetworkMetricsManager::process_dnstap(const dnstap::Dnstap &payload)
616636 // base event
617637 new_event (stamp);
618638 // process in the "live" bucket. this will parse the resources if we are deep sampling
619- live_bucket ()->process_dnstap (_deep_sampling_now, payload);
639+ live_bucket ()->process_dnstap (_deep_sampling_now, payload, size );
620640}
621641
622642void NetworkMetricsManager::process_sflow (const SFSample &payload)
0 commit comments