File: data-collection.rst

package info (click to toggle)
ns3 3.46-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 105,864 kB
  • sloc: cpp: 624,863; python: 14,863; ansic: 6,772; makefile: 1,950; sh: 987; javascript: 167; perl: 102
file content (450 lines) | stat: -rw-r--r-- 18,612 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
.. include:: replace.txt
.. highlight:: cpp
.. role:: raw-role(raw)
   :format: html latex

Data Collection
---------------

Our final tutorial chapter introduces some components that were added
to |ns3| in version 3.18, and that are still under development.  This
tutorial section is also a work-in-progress.

Motivation
**********

One of the main points of running simulations is to generate output data,
either for research purposes or simply to learn about the system.
In the previous chapter, we introduced the tracing subsystem and
the example ``sixth.cc``. from which PCAP or ASCII trace files are
generated.  These traces are valuable for data analysis using a
variety of external tools, and for many users, such output data is
a preferred means of gathering data (for analysis by external tools).

However, there are also use cases for more than trace file generation,
including the following:

* generation of data that does not map well to PCAP or ASCII traces, such
  as non-packet data (e.g. protocol state machine transitions),
* large simulations for which the disk I/O requirements for generating
  trace files is prohibitive or cumbersome, and
* the need for *online*  data reduction or computation, during the course
  of the simulation.  A good example of this is to define a termination
  condition for the simulation, to tell it when to stop when it has
  received enough data to form a narrow-enough confidence interval around
  the estimate of some parameter.

The |ns3| data collection framework is designed to provide these
additional capabilities beyond trace-based output.  We recommend
that the reader interested in this topic consult the |ns3| Manual
for a more detailed treatment of this framework; here, we summarize
with an example program some of the developing capabilities.

Example Code
************

The tutorial example ``examples/tutorial/seventh.cc`` resembles the
``sixth.cc`` example we previously reviewed, except for a few changes.
First, it has been enabled for IPv6 support with a command-line option:

::

  CommandLine cmd;
  cmd.AddValue("useIpv6", "Use Ipv6", useV6);
  cmd.Parse(argc, argv);

If the user specifies ``useIpv6``, option, the program will be run
using IPv6 instead of IPv4.  The ``help`` option, available on all |ns3|
programs that support the CommandLine object as shown above, can
be invoked as follows (please note the use of double quotes):

::

  ./ns3 run "seventh --help"

which produces:

::

  ns3-dev-seventh-debug [Program Arguments] [General Arguments]

  Program Arguments:
      --useIpv6:  Use Ipv6 [false]

  General Arguments:
      --PrintGlobals:              Print the list of globals.
      --PrintGroups:               Print the list of groups.
      --PrintGroup=[group]:        Print all TypeIds of group.
      --PrintTypeIds:              Print all TypeIds.
      --PrintAttributes=[typeid]:  Print all attributes of typeid.
      --PrintHelp:                 Print this help message.

This default (use of IPv4, since useIpv6 is false) can be changed by
toggling the boolean value as follows:

::

  ./ns3 run "seventh --useIpv6=1"

and have a look at the pcap generated, such as with ``tcpdump``:

::

  tcpdump -r seventh.pcap -nn -tt

This has been a short digression into IPv6 support and the command line,
which was also introduced earlier in this tutorial.  For a dedicated
example of command line usage, please see
``src/core/examples/command-line-example.cc``.

Now back to data collection.  In the ``examples/tutorial/`` directory,
type the following command: ``diff -u sixth.cc seventh.cc``, and examine
some of the new lines of this diff:

.. sourcecode:: diff

  +  std::string probeType;
  +  std::string tracePath;
  +  if (useV6 == false)
  +    {
     ...
  +      probeType = "ns3::Ipv4PacketProbe";
  +      tracePath = "/NodeList/*/$ns3::Ipv4L3Protocol/Tx";
  +    }
  +  else
  +    {
     ...
  +      probeType = "ns3::Ipv6PacketProbe";
  +      tracePath = "/NodeList/*/$ns3::Ipv6L3Protocol/Tx";
  +    }
   ...
  +   // Use GnuplotHelper to plot the packet byte count over time
  +   GnuplotHelper plotHelper;
  +
  +   // Configure the plot.  The first argument is the file name prefix
  +   // for the output files generated.  The second, third, and fourth
  +   // arguments are, respectively, the plot title, x-axis, and y-axis labels
  +   plotHelper.ConfigurePlot("seventh-packet-byte-count",
  +                            "Packet Byte Count vs. Time",
  +                            "Time(Seconds)",
  +                            "Packet Byte Count");
  +
  +   // Specify the probe type, trace source path (in configuration namespace), and
  +   // probe output trace source ("OutputBytes") to plot.  The fourth argument
  +   // specifies the name of the data series label on the plot.  The last
  +   // argument formats the plot by specifying where the key should be placed.
  +   plotHelper.PlotProbe(probeType,
  +                        tracePath,
  +                        "OutputBytes",
  +                        "Packet Byte Count",
  +                        GnuplotAggregator::KEY_BELOW);
  +
  +   // Use FileHelper to write out the packet byte count over time
  +   FileHelper fileHelper;
  +
  +   // Configure the file to be written, and the formatting of output data.
  +   fileHelper.ConfigureFile("seventh-packet-byte-count",
  +                            FileAggregator::FORMATTED);
  +
  +   // Set the labels for this formatted output file.
  +   fileHelper.Set2dFormat("Time (Seconds) = %.3e\tPacket Byte Count = %.0f");
  +
  +   // Specify the probe type, probe path (in configuration namespace), and
  +   // probe output trace source ("OutputBytes") to write.
  +   fileHelper.WriteProbe(probeType,
  +                         tracePath,
  +                         "OutputBytes");
  +
      Simulator::Stop(Seconds(20));
      Simulator::Run();
      Simulator::Destroy();


The careful reader will have noticed, when testing the IPv6 command
line attribute above, that ``seventh.cc`` had created a number of new output files:

::

  seventh-packet-byte-count-0.txt
  seventh-packet-byte-count-1.txt
  seventh-packet-byte-count.dat
  seventh-packet-byte-count.plt
  seventh-packet-byte-count.png
  seventh-packet-byte-count.sh

These were created by the additional statements introduced above; in
particular, by a GnuplotHelper and a FileHelper.  This data was produced
by hooking the data collection components to |ns3| trace sources, and
marshaling the data into a formatted ``gnuplot`` and into a formatted
text file.  In the next sections, we'll review each of these.

.. _GnuPlotHelper:

GnuplotHelper
*************

The GnuplotHelper is an |ns3| helper object aimed at the production of
``gnuplot`` plots with as few statements as possible, for common cases.
It hooks |ns3| trace sources with data types supported by the
data collection system.  Not all |ns3| trace sources data types are
supported, but many of the common trace types are, including TracedValues
with plain old data (POD) types.

Let's look at the output produced by this helper:

::

  seventh-packet-byte-count.dat
  seventh-packet-byte-count.plt
  seventh-packet-byte-count.sh

The first is a gnuplot data file with a series of space-delimited
timestamps and packet byte counts.  We'll cover how this particular
data output was configured below, but let's continue with the output
files.  The file ``seventh-packet-byte-count.plt`` is a gnuplot plot file,
that can be opened from within gnuplot.  Readers who understand gnuplot
syntax can see that this will produce a formatted output PNG file named
``seventh-packet-byte-count.png``.   Finally, a small shell script
``seventh-packet-byte-count.sh`` runs this plot file through gnuplot
to produce the desired PNG (which can be viewed in an image editor); that
is, the command:

::

  sh seventh-packet-byte-count.sh

will yield ``seventh-packet-byte-count.png``.  Why wasn't this PNG
produced in the first place?  The answer is that by providing the
plt file, the user can hand-configure the result if desired, before
producing the PNG.

The PNG image title states that this plot is a plot of
"Packet Byte Count vs. Time", and that it is plotting the probed data
corresponding to the trace source path:

.. sourcecode:: text

  /NodeList/*/$ns3::Ipv6L3Protocol/Tx

Note the wild-card in the trace path.  In summary, what this plot is
capturing is the plot of packet bytes observed at the transmit trace
source of the Ipv6L3Protocol object; largely 596-byte TCP segments
in one direction, and 60-byte TCP acks in the other (two node
trace sources were matched by this trace source).

How was this configured?  A few statements need to be provided.  First,
the GnuplotHelper object must be declared and configured:

::

  +  // Use GnuplotHelper to plot the packet byte count over time
  +  GnuplotHelper plotHelper;
  +
  +  // Configure the plot.  The first argument is the file name prefix
  +  // for the output files generated.  The second, third, and fourth
  +  // arguments are, respectively, the plot title, x-axis, and y-axis labels
  +  plotHelper.ConfigurePlot("seventh-packet-byte-count",
  +                           "Packet Byte Count vs. Time",
  +                           "Time (Seconds)",
  +                           "Packet Byte Count");


To this point, an empty plot has been configured.  The filename prefix
is the first argument, the plot title is the second, the x-axis label
the third, and the y-axis label the fourth argument.

The next step is to configure the data, and here is where the trace
source is hooked.  First, note above in the program we declared a few
variables for later use:

::

  +  std::string probeType;
  +  std::string tracePath;
  +  probeType = "ns3::Ipv6PacketProbe";
  +  tracePath = "/NodeList/*/$ns3::Ipv6L3Protocol/Tx";

We use them here:

::

  +  // Specify the probe type, trace source path (in configuration namespace), and
  +  // probe output trace source ("OutputBytes") to plot.  The fourth argument
  +  // specifies the name of the data series label on the plot.  The last
  +  // argument formats the plot by specifying where the key should be placed.
  +  plotHelper.PlotProbe(probeType,
  +                       tracePath,
  +                       "OutputBytes",
  +                       "Packet Byte Count",
  +                       GnuplotAggregator::KEY_BELOW);

The first two arguments are the name of the probe type and the trace source path.
These two are probably the hardest to determine when you try to use
this framework to plot other traces.  The probe trace here is the ``Tx``
trace source of class ``Ipv6L3Protocol``.  When we examine this class
implementation (``src/internet/model/ipv6-l3-protocol.cc``) we can
observe:

::

    .AddTraceSource("Tx", "Send IPv6 packet to outgoing interface.",
                    MakeTraceSourceAccessor(&Ipv6L3Protocol::m_txTrace))

This says that ``Tx`` is a name for variable ``m_txTrace``, which has
a declaration of:

::

  /**
   * \brief Callback to trace TX (transmission) packets.
   */
  TracedCallback<Ptr<const Packet>, Ptr<Ipv6>, uint32_t> m_txTrace;

It turns out that this specific trace source signature is supported
by a Probe class (what we need here) of class Ipv6PacketProbe.
See the files ``src/internet/model/ipv6-packet-probe.{h,cc}``.

So, in the PlotProbe statement above, we see that the statement is
hooking the trace source (identified by path string) with a matching
|ns3| Probe type of ``Ipv6PacketProbe``.  If we did not support
this probe type (matching trace source signature), we could have not
used this statement (although some more complicated lower-level statements
could have been used, as described in the manual).

The Ipv6PacketProbe exports, itself, some trace sources that extract
the data out of the probed Packet object:

::

  TypeId
  Ipv6PacketProbe::GetTypeId()
  {
    static TypeId tid = TypeId("ns3::Ipv6PacketProbe")
      .SetParent<Probe>()
      .SetGroupName("Stats")
      .AddConstructor<Ipv6PacketProbe>()
      .AddTraceSource("Output",
                      "The packet plus its IPv6 object and interface that serve as the output for this probe",
                      MakeTraceSourceAccessor(&Ipv6PacketProbe::m_output))
      .AddTraceSource("OutputBytes",
                      "The number of bytes in the packet",
                      MakeTraceSourceAccessor(&Ipv6PacketProbe::m_outputBytes))
    ;
    return tid;
  }


The third argument of our PlotProbe statement specifies that we are
interested in the number of bytes in this packet; specifically, the
"OutputBytes" trace source of Ipv6PacketProbe.
Finally, the last two arguments of the statement provide the plot
legend for this data series ("Packet Byte Count"), and an optional
gnuplot formatting statement (GnuplotAggregator::KEY_BELOW) that we want
the plot key to be inserted below the plot.  Other options include
NO_KEY, KEY_INSIDE, and KEY_ABOVE.


Supported Trace Types
*********************

The following traced values are supported with Probes as of this writing:

+------------------+-------------------+------------------------------------+
| TracedValue type |   Probe type      |  File                              |
+==================+=========+=========+====================================+
| double           | DoubleProbe       | stats/model/double-probe.h         |
+------------------+-------------------+------------------------------------+
| uint8_t          | Uinteger8Probe    | stats/model/uinteger-8-probe.h     |
+------------------+-------------------+------------------------------------+
| uint16_t         | Uinteger16Probe   | stats/model/uinteger-16-probe.h    |
+------------------+-------------------+------------------------------------+
| uint32_t         | Uinteger32Probe   | stats/model/uinteger-32-probe.h    |
+------------------+-------------------+------------------------------------+
| bool             | BooleanProbe      | stats/model/uinteger-16-probe.h    |
+------------------+-------------------+------------------------------------+
| ns3::Time        | TimeProbe         | stats/model/time-probe.h           |
+------------------+-------------------+------------------------------------+

The following TraceSource types are supported by Probes as of this writing:

+------------------------------------------+------------------------+---------------+----------------------------------------------------+
| TracedSource type                        |   Probe type           | Probe outputs |  File                                              |
+==========================================+========================+===============+====================================================+
| Ptr<const Packet>                        | PacketProbe            | OutputBytes   | network/utils/packet-probe.h                       |
+------------------------------------------+------------------------+---------------+----------------------------------------------------+
| Ptr<const Packet>, Ptr<Ipv4>, uint32_t   | Ipv4PacketProbe        | OutputBytes   | internet/model/ipv4-packet-probe.h                 |
+------------------------------------------+------------------------+---------------+----------------------------------------------------+
| Ptr<const Packet>, Ptr<Ipv6>, uint32_t   | Ipv6PacketProbe        | OutputBytes   | internet/model/ipv6-packet-probe.h                 |
+------------------------------------------+------------------------+---------------+----------------------------------------------------+
| Ptr<const Packet>, Ptr<Ipv6>, uint32_t   | Ipv6PacketProbe        | OutputBytes   | internet/model/ipv6-packet-probe.h                 |
+------------------------------------------+------------------------+---------------+----------------------------------------------------+
| Ptr<const Packet>, const Address&        | ApplicationPacketProbe | OutputBytes   | applications/model/application-packet-probe.h      |
+------------------------------------------+------------------------+---------------+----------------------------------------------------+

As can be seen, only a few trace sources are supported, and they are all
oriented towards outputting the Packet size (in bytes).  However,
most of the fundamental data types available as TracedValues can be
supported with these helpers.

FileHelper
**********

The FileHelper class is just a variation of the previous GnuplotHelper
example.  The example program provides formatted output of the
same timestamped data, such as follows:

::

  Time (Seconds) = 9.312e+00    Packet Byte Count = 596
  Time (Seconds) = 9.312e+00    Packet Byte Count = 564

Two files are provided, one for node "0" and one for node "1" as can
be seen in the filenames.  Let's look at the code piece-by-piece:

::

  +   // Use FileHelper to write out the packet byte count over time
  +   FileHelper fileHelper;
  +
  +   // Configure the file to be written, and the formatting of output data.
  +   fileHelper.ConfigureFile("seventh-packet-byte-count",
  +                            FileAggregator::FORMATTED);

The file helper file prefix is the first argument, and a format specifier
is next.
Some other options for formatting include SPACE_SEPARATED, COMMA_SEPARATED,
and TAB_SEPARATED.  Users are able to change the formatting (if
FORMATTED is specified) with a format string such as follows:

::

  +
  +   // Set the labels for this formatted output file.
  +   fileHelper.Set2dFormat("Time (Seconds) = %.3e\tPacket Byte Count = %.0f");

Finally, the trace source of interest must be hooked.  Again, the probeType and
tracePath variables in this example are used, and the probe's output
trace source "OutputBytes" is hooked:

::

  +
  +   // Specify the probe type, trace source path (in configuration namespace), and
  +   // probe output trace source ("OutputBytes") to write.
  +   fileHelper.WriteProbe(probeType,
  +                         tracePath,
  +                         "OutputBytes");
  +

The wildcard fields in this trace source specifier match two trace sources.
Unlike the GnuplotHelper example, in which two data series were overlaid
on the same plot, here, two separate files are written to disk.

Summary
*******

Data collection support is new as of ns-3.18, and basic support for
providing time series output has been added.  The basic pattern described
above may be replicated within the scope of support of the existing
probes and trace sources.  More capabilities including statistics
processing will be added in future releases.