add some words about tracing to the manual
authorCraig Dowell <craigdo@ee.washington.edu>
Tue, 15 Sep 2009 00:05:36 -0700
changeset 5188 799fdd8fc54a
parent 5187 d8c22a819f59
child 5189 8fcdf87a790a
child 5197 0401d439763e
child 5211 36838195150a
add some words about tracing to the manual
doc/manual/manual.texi
doc/manual/tracing.texi
--- a/doc/manual/manual.texi	Mon Sep 14 21:49:43 2009 -0700
+++ b/doc/manual/manual.texi	Tue Sep 15 00:05:36 2009 -0700
@@ -82,8 +82,9 @@
 @menu
 * Random variables::
 * Callbacks::
+* Object model::
 * Attributes::
-* Object model::
+* Tracing::
 * RealTime::
 * Emulation::
 * Packets::
@@ -100,8 +101,9 @@
 
 @include random.texi
 @include callbacks.texi
+@include objects.texi
 @include attributes.texi
-@include objects.texi
+@include tracing.texi
 @include realtime.texi
 @include emulation.texi
 @include packets.texi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/manual/tracing.texi	Tue Sep 15 00:05:36 2009 -0700
@@ -0,0 +1,325 @@
+@node Tracing
+@chapter Tracing
+
+The tracing subsystem is one of the most important mechansisms to understand in
+@command{ns-3}.  In most cases, @command{ns-3} users will have a brilliant idea
+for some new and improved networking feature.  In order to verify that this
+idea works, the researcher will make changes to an existing system and then run
+experiments to see how the new feature behaves by gathering some form of statistic
+that captures the behavior of the feature.
+
+In other words, the whole point of running a simulation is to generate output for
+further study.  In @command{ns-3}, the subsystem that enables a researcher to do
+this is the tracing subsystem.
+
+@menu
+* Motivation::
+* Overview::
+* Using the Tracing API::
+* Implementation details::
+@end menu
+
+@node Motivation
+@section Motivation
+
+There are many ways to get information out of a program.  The most straightforward
+way is to just directly print the information to the standard output, as in,
+
+@verbatim
+  #include <iostream>
+  ...
+  int main ()
+  {
+    ...
+    std::cout << ``The value of x is `` << x << std::endl;
+    ...
+  } 
+@end verbatim
+
+This is workable in small environments, but as your simulations get more and more
+compliated, you end up with more and more prints and the task of parsing and 
+performing computations on the output begins to get harder and harder.
+
+Another thing to consider is that every time a new tidbit is needed, the software
+core must be edited and another print introduced.  There is no standardized way
+to control all of this output, so the amount of output tends to grow without 
+bounds.  Eventually, the bandwidth required for simply outputting this information
+begins to limit the running time of the simulation.  The output files grow to 
+enormous sizes and parsing them becomes a problem.
+
+@command{ns-3} provides a simple mechanism for logging and providing some control 
+over output via @emph{Log Components}, but the level of control is not very fine
+grained at all.  The logging module is a relatively blunt instrument.
+
+It is desirable to have a facility that allows one to reach into the core system
+and only get the information required without having to change and recompile the
+core system.  Even better would be a system that notified the user when an item
+of interest changed or an interesting event happened.
+
+The @command{ns-3} tracing system is designed to work along those lines and is 
+well-integrated with the Attribute and Config substems allowing for relatively
+simple use scenarios.
+
+@node Overview
+@section Overview
+
+The tracing subsystem relies heavily on the @code{ns-3} Callback and Attribute
+mechanisms.  You should read and understand the corresponding sections of the 
+manual before attempting to understand the tracing system.
+
+The ns-3 tracing system is built on the concepts of independent tracing sources
+and tracing sinks; along with a uniform mechanism for connecting sources to sinks.
+
+Trace sources are entities that can signal events that happen in a simulation and 
+provide access to interesting underlying data.  For example, a trace source could
+indicate when a packet is received by a net device and provide access to the 
+packet contents for interested trace sinks.  A trace source might also indicate 
+when an iteresting state change happens in a model.  For example, the congestion
+window of a TCP model is a prime candidate for a trace source.
+
+Trace sources are not useful by themselves; they must be connected to other pieces
+of code that actually do something useful with the information provided by the source.
+The entities that consume trace information are called trace sinks.  Trace sources 
+are generators of events and trace sinks are consumers. 
+
+This explicit division allows for large numbers of trace sources to be scattered
+around the system in places which model authors believe might be useful.  Unless
+a user connects a trace sink to one of these sources, nothing is output.  This
+arrangement allows relatively unsophisticated users to attach new types of sinks
+to existing tracing sources, without requiring editing and recompiling the core 
+or models of the simulator.  
+
+There can be zero or more consumers of trace events generated by a trace source.  
+One can think of a trace source as a kind of point-to-multipoint information link.  
+
+The ``transport protocol'' for this conceptual point-to-multipoint link as an 
+@code{ns-3} @code{Callback}.
+
+Recall from the Callback Section that callback facility is a way to allow two
+modules in the system to communicate via function calls while at the same time
+decoupling the calling function from the called class completely.  This is the
+same requirement as outlined above for the tracing system.
+
+Basically, a trace source @emph{is} a callback.  When a trace sink expresses
+interest in receiving trace events, it adds a callback to a list of callbacks
+held by the trace source.  When an interesting event happens, the trace source
+invokes its @code{operator()} providing zero or more parameters.  This tells
+the source to go through its list of callbacks invoking each one in turn.  In
+this way, the parameter(s) are communicated to the trace sinks, which are just
+functions.
+
+@subsection The Simplest Example
+
+It will be useful to go walk a quick example just to reinforce what we've said.
+
+@verbose
+  #include ``ns3/object.h''
+  #include ``ns3/uinteger.h''
+  #include ``ns3/traced-value.h''
+  #include ``ns3/trace-source-accessor.h''
+  
+  #include <iostream>
+  
+  using namespace ns3;
+@end verbose
+
+The first thing to do is include the required files.  As mentioned above, the
+trace system makes heavy use of the Object and Attribute systems.  The first
+two includes bring in the declarations for those systems.  The file, 
+@code{traced-value.h} brings in the required declarations for tracing data
+that obeys value semantics.  
+
+In general, value semantics just means that you can pass the object around,
+not an address.  In order to use value semantics at all you have to have an
+object with an associated copy constructor and assignment operator
+available.  We extend the requirements to talk about the set of operators
+that are pre-defined for plain-old-data (POD) types.  Operator=, operator++,
+operator--, operator+, operator==, etc.
+
+What this all means is that you will be able to trace changes to an object
+made using those operators.
+
+@verbatim
+  class MyObject : public Object
+  {
+  public:
+    static TypeId GetTypeId (void)
+    {
+      static TypeId tid = TypeId ("MyObject")
+        .SetParent (Object::GetTypeId ())
+        .AddConstructor<MyObject> ()
+        .AddTraceSource ("MyInteger",
+                         "An integer value to trace.",
+                         MakeTraceSourceAccessor (&MyObject::m_myInt))
+        ;
+      return tid;
+    }
+  
+    MyObject () {}
+    TracedValue<uint32_t> m_myInt;
+  };
+@end verbatim
+
+Since the tracing system is integrated with Attributes, and Attributes work
+with Objects, there must be an @command{ns-3} @code{Object} for the trace source
+to live in.  The two important lines of code are the @code{.AddTraceSource} and 
+the @code{TracedValue} declaration.
+
+The @code{.AddTraceSource} provides the ``hooks'' used for connecting the trace
+source to the outside world.  The @code{TracedValue} declaration provides the
+infrastructure that overloads the operators above and drives the callback 
+process.
+
+@verbatim
+  void
+  IntTrace (Int oldValue, Int newValue)
+  {
+    std::cout << ``Traced `` << oldValue << `` to `` << newValue << std::endl;
+  }
+@end verbatim
+
+This is the definition of the trace sink.  It corresponds directly to a callback
+function.  This function will be called whenever one of the operators of the
+@code{TracedValue} is executed.
+
+@verbatim
+  int
+  main (int argc, char *argv[])
+  {
+    Ptr<MyObject> myObject = CreateObject<MyObject> ();
+  
+    myObject->TraceConnectWithoutContext ("MyInt", MakeCallback(&IntTrace));
+
+    myObject->m_myInt = 1234;
+  }
+@end verbatim
+
+In this snippet, the first thing that needs to be done is to create the object
+in which the trace source lives.
+
+The next step, the @code{TraceConnectWithoutContext}, forms the connection
+between the trace source and the trace sink.  Notice the @code{MakeCallback}
+template function.  Recall from the Callback section that this creates the
+specialized functor responsible for providing the overloaded @code{operator()}
+used to ``fire'' the callback.  The @code{TraceConnectWithoutContext}, takes
+a string parameter that provides the name of the Attribute assigned to the
+trace source.  Let's ignore the bit about context for now.
+
+Finally, the line,
+
+@verbatim
+   myObject->m_myInt = 1234;
+@end verbatim
+
+should be interpreted as an invocation of @code{operator=} on the member 
+variable @code{m_myInt} with the integer @code{1234} passed as a parameter.
+It turns out that this operator is defined (by @code{TracedValue}) to execute
+a callback that returns void and takes two integer values as parameters -- 
+an old value and a new value for the integer in question.  That is exactly 
+the function signature for the callback function we provided -- @code{IntTrace}.
+
+To summarize, a trace source is, in essence, a variable that holds a list of
+callbacks.  A trace sink is a function used as the target of a callback.  The
+Attribute and object type information systems are used to provide a way to 
+connect trace sources to trace sinks.  The act of ``hitting'' a trace source
+is executing an operator on the trace source which fires callbacks.  This 
+results in the trace sink callbacks registering interest in the source being 
+called with the parameters provided by the source.
+
+@subsection Using the Config Subsystem to Connect to Trace Sources
+
+The @code{TraceConnectWithoutContext} call shown above in the simple example is
+actually very rarely used in the system.  More typically, the @code{Config}
+subsystem is used to allow selecting a trace source in the system using what is
+called a @emph{config path}.
+
+For example, one might find something that looks like the following in the system
+(taken from @code{examples/tcp-large-transfer.cc})
+
+@verbatim
+  void CwndTracer (uint32_t oldval, uint32_t newval) {}
+
+  ...
+
+  Config::ConnectWithoutContext (
+    "/NodeList/0/$ns3::TcpL4Protocol/SocketList/0/CongestionWindow", 
+    MakeCallback (&CwndTracer));
+@end verbatim
+
+This should look very familiar.  It is the same thing as the previous example,
+except that a static member function of @code{Config} is being called instead of
+a method on @code{Object}, and instead of an @code{Attribute} name, a path is
+being provided.
+
+The first thing to do is to read the path backward.  The last segment of the path
+must be an @code{Attribute} of an @code{Object}.  In fact, if you had a pointer to
+the @code{Object} that has the @code{Attribute} handy, you could write this just like
+the previous example:
+
+@verbatim
+  void CwndTracer (uint32_t oldval, uint32_t newval) {}
+
+  ...
+
+  object->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&CwndTracer));
+@end verbatim
+
+And it turns out that @code{Config::ConnectWithoutContext} does exactly that.  This
+function takes a path that represents a chain of @code{Object} pointers and follows 
+them until it gets to the end of the path and interprets the last segment as an
+@code{Attribute} on the last object.
+
+The leading ``/'' character in the path refers to a so-called namespace.  One of the
+predefined namespaces in the config system is ``NodeList'' which is a list of all of
+the nodes in the simulation.  Items in the list are referred to by indices into the 
+list, so ``/NodeList/0'' refers to the zeroth node in the list of nodes created by
+the simulation.  This node is actually a @code{Ptr<Node>} and so is a subclass of
+an @code{ns3::Object}.  
+
+As described in the Object Model section, @code{ns-3} supports an object aggregation
+model.  The next path segment begins with the ``$'' character which indicates a
+@code{GetObject} call should be made looking for the type that follows.  When a
+node is initialized by an @code{InternetStackHelper} a number of interfaces are
+aggregated to the node.  One of these is the TCP level four protocol.  The runtime
+type of this protocol object is ``ns3::TcpL4Protocol''.  When the @code{GetObject}
+is executed, it returns a pointer to the object of this type.
+
+The @code{TcpL4Protocol} class defines an Attribute called ``SocketList'' which is
+a list of sockets.  Each socket is actually an @code{ns3::Object} with its own 
+@code{Attributes}.  The items in the list of sockets are referred to by index just
+as in the NodeList, so ``SocketList/0'' refers to the zeroth socket in the list
+of sockets on the zeroth node in the NodeList -- the first node constructed in the
+simulation.
+
+This socket, the type of which turns out to be an @code{ns3::TcpSocketImpl} defines
+an attribute called ``CongestionWindow'' which is a @code{TracedValue<uint32_t>}.
+The @code{Config::ConnectWithoutContext} now does a,
+
+@verbatim
+  object->TraceConnectWithoutContext ("CongestionWindow", MakeCallback (&CwndTracer));
+@end verbatim
+
+using the object pointer from ``SocketList/0'' which makes the connection between
+the trace source defined in the socket to the callback -- @code{CwndTracer}.
+
+Now, whenever a change is made to the @code{TracedValue<uint32_t>} representing the
+congestion window in the TCP socket, the registered callback will be executed and 
+the function @code{Cwndtracer} will be called printing out the old and new values
+of the TCP congestion window.
+
+@node Using the Tracing API
+@section Using the Tracing API
+
+  There 
+are three levels of interaction with the tracing system:
+
+@itemize @bullet
+@item Beginning user can easily control which objects are participating in tracing;
+@item Intermediate users can extend the tracing system to modify the output format 
+generated or use existing trace sources in different ways, without modifying the 
+core of the simulator;
+@item Advanced users can modify the simulator core to add new tracing sources and 
+sinks. 
+
+@node Implementation details
+@section Implementation details