Skip to content

Commit 06b46ba

Browse files
author
Alexey Zharkov
committed
changes by review
1 parent 7b65c22 commit 06b46ba

11 files changed

Lines changed: 98 additions & 75 deletions

File tree

.github/workflows/load_testing.yml

Lines changed: 32 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,19 @@ on:
88

99
env:
1010
BUILD_DIR: build
11-
GENERATORS_DIR: scripts/generators
12-
FLAMEGRAPH_ARTIFACT_DIR: flamegraph
11+
EXECUTABLE_PATH: build/nons
12+
13+
GENERATORS_DIR: scripts/generators
14+
FAT_TREE_GENERATOR: scripts/generators/topology/fat_tree/fat_tree.py
15+
FAT_TREE_CONFIGS_DIR: scripts/generators/topology/fat_tree
16+
FAT_TREE_SMALL_CONFIG: scripts/generators/topology/fat_tree/small_fat_tree_config.yml
17+
FAT_TREE_LARGE_CONFIG: scripts/generators/topology/fat_tree/large_fat_tree_config.yml
18+
ALL_TO_ALL_GENERATOR: scripts/generators/ti_simulation/all-to-all/all-to-all.py
19+
1320
FLAMEGRAPH_TOPOLOGY_NAME: fat_tree_topology.yml
1421
FLAMEGRAPH_SIMULATION_NAME: fat_tree_simulation.yml
22+
FLAMEGRAPH_ARTIFACT_DIR: flamegraph
23+
FLAMEGRAPH_OUTPUT_DIR: flamegraph/flamegraph
1524

1625
jobs:
1726
load_testing:
@@ -23,29 +32,19 @@ jobs:
2332
- name: Update submodules
2433
run: git submodule update --init --recursive
2534

26-
- name: Derive env vars
27-
run: |
28-
echo "EXECUTABLE_PATH=$BUILD_DIR/nons" >> $GITHUB_ENV
29-
echo "FAT_TREE_GENERATOR=$GENERATORS_DIR/topology/fat_tree/fat_tree.py" >> $GITHUB_ENV
30-
echo "ALL_TO_ALL_GENERATOR=$GENERATORS_DIR/ti_simulation/all-to-all/all-to-all.py" >> $GITHUB_ENV
31-
echo "FAT_TREE_CONFIGS_DIR=$GENERATORS_DIR/topology/fat_tree" >> $GITHUB_ENV
32-
echo "FAT_TREE_SMALL_CONFIG=$GENERATORS_DIR/topology/fat_tree/small_fat_tree_config.yml" >> $GITHUB_ENV
33-
echo "FAT_TREE_LARGE_CONFIG=$GENERATORS_DIR/topology/fat_tree/large_fat_tree_config.yml" >> $GITHUB_ENV
34-
echo "FLAMEGRAPH_OUTPUT_DIR=$FLAMEGRAPH_ARTIFACT_DIR/flamegraph" >> $GITHUB_ENV
35-
3635
- name: Configure CMake for building project
37-
run: cmake -B $BUILD_DIR -DCMAKE_BUILD_TYPE=Release -DBUILD_PROJECT=ON -DBUILD_TESTS=OFF -DLOG_LEVEL=LOG_LEVEL_ERROR
36+
run: cmake -B ${{env.BUILD_DIR}} -DCMAKE_BUILD_TYPE=Release -DBUILD_PROJECT=ON -DBUILD_TESTS=OFF -DLOG_LEVEL=LOG_LEVEL_ERROR
3837

3938
- name: Build project
40-
run: cmake --build $BUILD_DIR -j $(nproc)
39+
run: cmake --build ${{env.BUILD_DIR}} -j $(nproc)
4140

4241
- name: Update PYTHONPATH
4342
run: echo "PYTHONPATH=${{ github.workspace }}/scripts" >> $GITHUB_ENV
4443

4544
- name: Run simulations
4645
run: |
47-
python3 scripts/generate_configs_and_run.py -e $EXECUTABLE_PATH -t $FAT_TREE_GENERATOR -tc $FAT_TREE_SMALL_CONFIG
48-
python3 scripts/generate_configs_and_run.py -e $EXECUTABLE_PATH -t $FAT_TREE_GENERATOR -tc $FAT_TREE_LARGE_CONFIG
46+
python3 scripts/generate_configs_and_run.py -e ${{env.EXECUTABLE_PATH}} -t ${{env.FAT_TREE_GENERATOR}} -tc ${{env.FAT_TREE_SMALL_CONFIG}}
47+
python3 scripts/generate_configs_and_run.py -e ${{env.EXECUTABLE_PATH}} -t ${{env.FAT_TREE_GENERATOR}} -tc ${{env.FAT_TREE_LARGE_CONFIG}}
4948
5049
5150
profiling_load_testing:
@@ -56,34 +55,24 @@ jobs:
5655
- name: Update submodules
5756
run: git submodule update --init --recursive
5857

59-
- name: Derive env vars
60-
run: |
61-
echo "EXECUTABLE_PATH=$BUILD_DIR/nons" >> $GITHUB_ENV
62-
echo "FAT_TREE_GENERATOR=$GENERATORS_DIR/topology/fat_tree/fat_tree.py" >> $GITHUB_ENV
63-
echo "ALL_TO_ALL_GENERATOR=$GENERATORS_DIR/ti_simulation/all-to-all/all-to-all.py" >> $GITHUB_ENV
64-
echo "FAT_TREE_CONFIGS_DIR=$GENERATORS_DIR/topology/fat_tree" >> $GITHUB_ENV
65-
echo "FAT_TREE_SMALL_CONFIG=$GENERATORS_DIR/topology/fat_tree/small_fat_tree_config.yml" >> $GITHUB_ENV
66-
echo "FAT_TREE_LARGE_CONFIG=$GENERATORS_DIR/topology/fat_tree/large_fat_tree_config.yml" >> $GITHUB_ENV
67-
echo "FLAMEGRAPH_OUTPUT_DIR=$FLAMEGRAPH_ARTIFACT_DIR/flamegraph" >> $GITHUB_ENV
68-
6958
- name: Configure CMake for profiling
70-
run: cmake -B $BUILD_DIR -DCMAKE_BUILD_TYPE=Release -DBUILD_PROJECT=ON -DBUILD_TESTS=OFF -DPROFILING=ON -DLOG_LEVEL=LOG_LEVEL_ERROR
59+
run: cmake -B ${{env.BUILD_DIR}} -DCMAKE_BUILD_TYPE=Release -DBUILD_PROJECT=ON -DBUILD_TESTS=OFF -DPROFILING=ON -DLOG_LEVEL=LOG_LEVEL_ERROR
7160

7261
- name: Build project with profiling
73-
run: cmake --build $BUILD_DIR -j $(nproc)
62+
run: cmake --build ${{env.BUILD_DIR}} -j $(nproc)
7463

7564
- name: Update PYTHONPATH
7665
run: echo "PYTHONPATH=${{ github.workspace }}/scripts" >> $GITHUB_ENV
7766

7867
- name: Run simulations with profiling
7968
run: |
80-
python3 scripts/generate_configs_and_run.py -e $EXECUTABLE_PATH -t $FAT_TREE_GENERATOR -tc $FAT_TREE_SMALL_CONFIG
81-
gprof $EXECUTABLE_PATH > profile.txt || true
82-
head profile.txt || true
69+
python3 scripts/generate_configs_and_run.py -e ${{env.EXECUTABLE_PATH}} -t ${{env.FAT_TREE_GENERATOR}} -tc ${{env.FAT_TREE_SMALL_CONFIG}}
70+
gprof ${{env.EXECUTABLE_PATH}} > profile.txt
71+
head profile.txt
8372
84-
python3 scripts/generate_configs_and_run.py -e $EXECUTABLE_PATH -t $FAT_TREE_GENERATOR -tc $FAT_TREE_LARGE_CONFIG
85-
gprof $EXECUTABLE_PATH > profile.txt || true
86-
head profile.txt || true
73+
python3 scripts/generate_configs_and_run.py -e ${{env.EXECUTABLE_PATH}} -t ${{env.FAT_TREE_GENERATOR}} -tc ${{env.FAT_TREE_LARGE_CONFIG}}
74+
gprof ${{env.EXECUTABLE_PATH}} > profile.txt
75+
head profile.txt
8776
8877
flamegraph:
8978
runs-on: ubuntu-latest
@@ -96,50 +85,41 @@ jobs:
9685
- name: Update submodules
9786
run: git submodule update --init --recursive
9887

99-
- name: Derive env vars
100-
run: |
101-
echo "EXECUTABLE_PATH=$BUILD_DIR/nons" >> $GITHUB_ENV
102-
echo "FAT_TREE_GENERATOR=$GENERATORS_DIR/topology/fat_tree/fat_tree.py" >> $GITHUB_ENV
103-
echo "ALL_TO_ALL_GENERATOR=$GENERATORS_DIR/ti_simulation/all-to-all/all-to-all.py" >> $GITHUB_ENV
104-
echo "FAT_TREE_CONFIGS_DIR=$GENERATORS_DIR/topology/fat_tree" >> $GITHUB_ENV
105-
echo "FAT_TREE_LARGE_CONFIG=$GENERATORS_DIR/topology/fat_tree/large_fat_tree_config.yml" >> $GITHUB_ENV
106-
echo "FLAMEGRAPH_OUTPUT_DIR=$FLAMEGRAPH_ARTIFACT_DIR/flamegraph" >> $GITHUB_ENV
107-
10888
- name: Get dependencies
10989
run: git clone https://github.com/brendangregg/FlameGraph.git
11090

11191
- name: Configure CMake for perf
112-
run: cmake -B $BUILD_DIR -DCMAKE_BUILD_TYPE=Release -DBUILD_PROJECT=ON -DBUILD_TESTS=OFF -DLOG_LEVEL=LOG_LEVEL_ERROR -DCMAKE_CXX_FLAGS="-g -fno-omit-frame-pointer"
92+
run: cmake -B ${{env.BUILD_DIR}} -DCMAKE_BUILD_TYPE=Release -DBUILD_PROJECT=ON -DBUILD_TESTS=OFF -DLOG_LEVEL=LOG_LEVEL_ERROR -DCMAKE_CXX_FLAGS="-g -fno-omit-frame-pointer"
11393

11494
- name: Build project with profiling
115-
run: cmake --build $BUILD_DIR -j $(nproc)
95+
run: cmake --build ${{env.BUILD_DIR}} -j $(nproc)
11696

11797
- name: Update PYTHONPATH
11898
run: echo "PYTHONPATH=${{ github.workspace }}/scripts" >> $GITHUB_ENV
11999

120100
- name: Generate topology config
121-
run: python3 $FAT_TREE_GENERATOR -c $FAT_TREE_LARGE_CONFIG -o $FLAMEGRAPH_TOPOLOGY_NAME
101+
run: python3 ${{env.FAT_TREE_GENERATOR}} -c ${{env.FAT_TREE_LARGE_CONFIG}} -o ${{env.FLAMEGRAPH_TOPOLOGY_NAME}}
122102

123103
- name: Generate simulation config
124-
run: python3 $ALL_TO_ALL_GENERATOR -t $FLAMEGRAPH_TOPOLOGY_NAME -o $FLAMEGRAPH_SIMULATION_NAME
104+
run: python3 ${{env.ALL_TO_ALL_GENERATOR}} -t ${{env.FLAMEGRAPH_TOPOLOGY_NAME}} -o ${{env.FLAMEGRAPH_SIMULATION_NAME}}
125105

126106
- name: Run perf
127107
run: |
128-
sudo perf record -F 99 -g -- ./$EXECUTABLE_PATH -c $FLAMEGRAPH_SIMULATION_NAME --no-logs --no-plots > perf.data
108+
sudo perf record -F 99 -g -- ./${{env.EXECUTABLE_PATH}} -c ${{env.FLAMEGRAPH_SIMULATION_NAME}} --no-logs --no-plots > perf.data
129109
perf report -i perf.data --header-only
130-
perf script -i perf.data -v > out.perf 2>&1 || true
110+
perf script -i perf.data -v > out.perf 2>&1
131111
132112
- name: Prepare FlameGraph
133113
run: |
134-
mkdir -p $FLAMEGRAPH_OUTPUT_DIR
114+
mkdir -p ${{ env.FLAMEGRAPH_OUTPUT_DIR }}
135115
136116
- name: Generate flamegraph
137117
run: |
138118
./FlameGraph/stackcollapse-perf.pl out.perf > out.folded
139-
./FlameGraph/flamegraph.pl out.folded > $FLAMEGRAPH_OUTPUT_DIR/flamegraph.svg
119+
./FlameGraph/flamegraph.pl out.folded > ${{ env.FLAMEGRAPH_OUTPUT_DIR }}/flamegraph.svg
140120
141121
- name: Create HTML
142-
run: python3 scripts/generate-html.py ./$FLAMEGRAPH_ARTIFACT_DIR
122+
run: python3 scripts/generate-html.py ./${{ env.FLAMEGRAPH_ARTIFACT_DIR }}
143123

144124
- name: Put github context to json file
145125
run: echo '${{ toJson(github) }}' > github_context.json

scripts/common.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,14 @@ def run_subprocess(subprocess_args : list[str], log_commands : bool = True, chec
3030
Runs subprocess with given args. If command fails, prints its stderr to stderr
3131
Returns result of subprocess.
3232
"""
33+
command_str = ' '.join(subprocess_args)
3334
if log_commands:
34-
print(f"Run command: `{' '.join(subprocess_args)}`")
35+
print(f"Run command: `{command_str}`")
3536

3637
result = subprocess.run(subprocess_args, capture_output=True, text=True)
3738

3839
if result.returncode != 0 and check_fails:
39-
print(f"Command `{' '.join(subprocess_args)}` failed; stderr:", file=sys.stderr)
40+
print(f"Command `{command_str}` failed; stderr:", file=sys.stderr)
4041
print(result.stderr, file=sys.stderr)
4142

4243
return result

source/connection/flow/i_flow.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class IFlow : public Identifiable {
1717
virtual void send_data(SizeByte data) = 0;
1818

1919
virtual SizeByte get_packet_size() const = 0;
20+
virtual SizeByte get_total_data_size_added_from_conn() const = 0;
2021
virtual SizeByte get_sent_data_size() const = 0;
2122
virtual SizeByte get_delivered_data_size() const = 0;
2223
virtual uint32_t retransmit_count() const = 0;
@@ -27,7 +28,7 @@ class IFlow : public Identifiable {
2728
virtual TimeNs get_fct() const = 0;
2829

2930
virtual const BaseFlagManager& get_flag_manager() const = 0;
30-
31+
3132
virtual std::shared_ptr<IHost> get_sender() const = 0;
3233
virtual std::shared_ptr<IHost> get_receiver() const = 0;
3334

source/connection/flow/tcp/tcp_flow.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ TcpFlow::TcpFlow(Id a_id, std::shared_ptr<IConnection> a_conn,
3232
m_rto_steady(false),
3333
m_retransmit_count(0),
3434
m_packets_in_flight(0),
35+
m_total_data_from_conn(0),
3536
m_delivered_data_size(0),
3637
m_sent_data_size(0),
3738
m_next_packet_num(0) {
@@ -95,6 +96,7 @@ void TcpFlow::update(Packet packet) {
9596
}
9697

9798
void TcpFlow::send_data(SizeByte data) {
99+
m_total_data_from_conn += data;
98100
TimeNs now = Scheduler::get_instance().get_current_time();
99101

100102
if (!m_sending_started) {
@@ -125,6 +127,10 @@ void TcpFlow::send_data(SizeByte data) {
125127

126128
SizeByte TcpFlow::get_packet_size() const { return m_packet_size; }
127129

130+
SizeByte TcpFlow::get_total_data_size_added_from_conn() const {
131+
return m_total_data_from_conn;
132+
}
133+
128134
SizeByte TcpFlow::get_sent_data_size() const { return m_sent_data_size; }
129135

130136
SizeByte TcpFlow::get_delivered_data_size() const {

source/connection/flow/tcp/tcp_flow.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class TcpFlow : public IFlow, public std::enable_shared_from_this<TcpFlow> {
2323
void send_data(SizeByte data) final;
2424

2525
SizeByte get_packet_size() const final;
26+
SizeByte get_total_data_size_added_from_conn() const final;
2627
SizeByte get_sent_data_size() const final;
2728
SizeByte get_delivered_data_size() const final;
2829
uint32_t retransmit_count() const final;
@@ -98,6 +99,7 @@ class TcpFlow : public IFlow, public std::enable_shared_from_this<TcpFlow> {
9899
std::uint32_t m_retransmit_count;
99100

100101
std::uint32_t m_packets_in_flight;
102+
SizeByte m_total_data_from_conn;
101103
SizeByte m_delivered_data_size;
102104
SizeByte m_sent_data_size;
103105
PacketNum m_next_packet_num;

source/scenario/action/send_data_action.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ namespace sim {
66

77
SendDataAction::SendDataAction(TimeNs a_when, SizeByte a_size,
88
std::vector<std::weak_ptr<IConnection>> a_conns,
9-
int a_repeat_count, TimeNs a_repeat_interval, TimeNs a_jitter)
9+
int a_repeat_count, TimeNs a_repeat_interval,
10+
TimeNs a_jitter)
1011
: m_when(a_when),
1112
m_size(a_size),
1213
m_conns(std::move(a_conns)),
@@ -21,9 +22,10 @@ void SendDataAction::schedule() {
2122
auto conn = weak.lock();
2223
if (!conn) throw std::runtime_error("Expired connection in action");
2324

24-
std::uint64_t seed = std::hash<std::string>{}(conn->get_id());
25+
std::uint64_t seed = std::hash<std::string>{}(conn->get_id());
2526
std::mt19937_64 rng(seed);
26-
std::uniform_int_distribution<uint64_t> dist(0, m_jitter.value_nanoseconds());
27+
std::uniform_int_distribution<uint64_t> dist(
28+
0, m_jitter.value_nanoseconds());
2729

2830
for (size_t i = 0; i < m_repeat_count; ++i) {
2931
TimeNs jitter_gap = use_jitter ? TimeNs(dist(rng)) : TimeNs(0);

source/scenario/action/send_data_action.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22
#include <random>
3+
34
#include "connection/i_connection.hpp"
45
#include "i_action.hpp"
56
#include "scheduler.hpp"
@@ -11,7 +12,8 @@ class SendDataAction : public IAction {
1112
public:
1213
SendDataAction(TimeNs a_when, SizeByte a_size,
1314
std::vector<std::weak_ptr<IConnection>> a_conns,
14-
int a_repeat_count, TimeNs a_repeat_interval, TimeNs a_jitter);
15+
int a_repeat_count, TimeNs a_repeat_interval,
16+
TimeNs a_jitter);
1517

1618
void schedule() final;
1719

source/utils/summary.cpp

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,26 @@ Summary::Summary(
1515
Id conn_id = conn->get_id();
1616
SizeByte expt_data_delivery = conn->get_total_data_added();
1717
if (expt_data_delivery == SizeByte(0)) {
18-
m_warnings.emplace_back(
19-
fmt::format("Connection {} has 0 expected data delivery", conn_id));
18+
m_warnings.emplace_back(fmt::format(
19+
"Connection {} has 0 expected data delivery", conn_id));
2020
}
2121
SizeByte real_data_delivery(0);
2222
auto flows = conn->get_flows();
2323

2424
for (const auto& flow : flows) {
25+
const SizeByte added_from_conn =
26+
flow->get_total_data_size_added_from_conn();
2527
const SizeByte delivered = flow->get_delivered_data_size();
2628
real_data_delivery += delivered;
2729

30+
if (added_from_conn > delivered) {
31+
m_errors.emplace_back(fmt::format(
32+
"For flow {} of connection {} added from connection {} "
33+
"bytes but delivered {} bytes",
34+
flow->get_id(), conn_id, added_from_conn.value(),
35+
delivered.value()));
36+
}
37+
2838
const SizeByte sent = flow->get_sent_data_size();
2939
if (sent < delivered) {
3040
m_errors.emplace_back(fmt::format(
@@ -33,7 +43,9 @@ Summary::Summary(
3343
flow->get_id(), conn_id, sent.value(), delivered.value()));
3444
}
3545

36-
double overhead = delivered != SizeByte(0) ? (sent / delivered - 1) * 100 : std::nan("");
46+
double overhead = delivered != SizeByte(0)
47+
? (sent / delivered - 1) * 100
48+
: std::nan("");
3749

3850
const TimeNs fct = flow->get_fct();
3951
SizeByte packet_size = flow->get_packet_size();
@@ -45,21 +57,31 @@ Summary::Summary(
4557
SizeByte retransmit_size = retransmit_count * packet_size;
4658

4759
m_values[conn_id][flow->get_id()] =
48-
FlowSummary{sent, delivered, packet_size,
49-
overhead, retransmit_size, retransmit_count,
50-
sending_rate, throughput, fct};
60+
FlowSummary{added_from_conn, sent,
61+
delivered, packet_size,
62+
overhead, retransmit_size,
63+
retransmit_count, sending_rate,
64+
throughput, fct};
5165
}
5266
if (expt_data_delivery > real_data_delivery) {
5367
m_errors.emplace_back(fmt::format(
5468
"For connection {} expected delivery {} but real is {}",
5569
conn_id, expt_data_delivery.value(),
5670
real_data_delivery.value()));
5771
}
58-
if (expt_data_delivery == SizeByte(0) && real_data_delivery > SizeByte(0)) {
72+
if (expt_data_delivery == SizeByte(0) &&
73+
real_data_delivery > SizeByte(0)) {
5974
m_errors.emplace_back(fmt::format(
60-
"For connection {} expected delivery 0 but real is {}",
61-
conn_id, real_data_delivery.value()));
75+
"For connection {} expected delivery 0 but real is {}", conn_id,
76+
real_data_delivery.value()));
6277
}
78+
// PS: case expt_data_delivery != real_data_delivery == 0 is is not
79+
// always an error, because in our model, if there is less data to send
80+
// than the size of the flow's packet, the flow still sends a full-sized
81+
// packet.
82+
// For example, if there is 1 byte to send and the packet size is 1500
83+
// bytes, the flow will send a full 1500-byte packet.
84+
// For this reason we do not consider this case an error.
6385
}
6486
}
6587

@@ -69,26 +91,28 @@ void Summary::write_to_csv(std::filesystem::path& output_path) const {
6991
if (!out) {
7092
throw std::runtime_error("Failed to create file for summary");
7193
}
72-
out << "Flow id, Packet size (bytes), Sent (bytes), Delivered (bytes), "
94+
out << "Flow id, Packet size (bytes), Data from conn (bytes), Sent "
95+
"(bytes), Delivered (bytes), "
7396
"Overhead (%), Retransmit size (bytes), Retransmit count, Sending "
7497
"rate (Gbps), Throughput (Gbps), FCT (ns)\n";
7598
for (const auto& [conn_id, flows] : m_values) {
7699
out << "\n";
77100
for (const auto& [flow_id, fs] : flows) {
78101
out << flow_id << ", " << fs.packet_size.value() << ", "
79-
<< fs.sent.value() << ", " << fs.delivered.value() << ", "
80-
<< fs.overhead << ", " << fs.retransmit_size.value() << ", "
81-
<< fs.retransmit_count << ", " << fs.sending_rate.value()
82-
<< ", " << fs.throughput.value() << ", " << fs.fct.value()
83-
<< "\n";
102+
<< fs.added_from_conn.value() << ", " << fs.sent.value() << ", "
103+
<< fs.delivered.value() << ", " << fs.overhead << ", "
104+
<< fs.retransmit_size.value() << ", " << fs.retransmit_count
105+
<< ", " << fs.sending_rate.value() << ", "
106+
<< fs.throughput.value() << ", " << fs.fct.value() << "\n";
84107
}
85108
}
86109
out.close();
87110
}
88111

89112
void Summary::check() const {
90113
if (!m_warnings.empty()) {
91-
LOG_WARN(fmt::format("Summary warnings: {}", fmt::join(m_warnings, "\n")));
114+
LOG_WARN(
115+
fmt::format("Summary warnings: {}", fmt::join(m_warnings, "\n")));
92116
}
93117
if (!m_errors.empty()) {
94118
throw std::runtime_error(

source/utils/summary.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ using ErrorMessage = std::string;
1212
using WarningMessage = std::string;
1313

1414
struct FlowSummary {
15+
SizeByte added_from_conn{0};
1516
SizeByte sent{0};
1617
SizeByte delivered{0};
1718
SizeByte packet_size{0};

0 commit comments

Comments
 (0)