A Discrete-Event Network Simulator
Manual

Logging

The ns-3 logging facility can be used to monitor or debug the progress of simulation programs. Logging output can be enabled by program statements in your main() program or by the use of the NS_LOG environment variable.

Logging statements are not compiled into optimized builds of ns-3. To use logging, one must build the (default) debug build of ns-3.

The project makes no guarantee about whether logging output will remain the same over time. Users are cautioned against building simulation output frameworks on top of logging code, as the output and the way the output is enabled may change over time.

Logging overview

ns-3 logging statements are typically used to log various program execution events, such as the occurrence of simulation events or the use of a particular function.

For example, this code snippet is from Ipv4L3Protocol::IsDestinationAddress():

if (address == iaddr.GetBroadcast ())
  {
    NS_LOG_LOGIC ("For me (interface broadcast address)");
    return true;
   }

If logging has been enabled for the Ipv4L3Protocol component at a level of LOGIC or above (see below about logging levels), the statement will be printed out; otherwise, it will be suppressed.

Logging levels

The following levels are defined; each level will enable the levels above it, with the ALL level being most verbose:

  1. LOG_NONE: the default, no logging
  2. LOG_ERROR: serious error messages only
  3. LOG_WARN: warning messages
  4. LOG_DEBUG: for use in debugging
  5. LOG_FUNCTION: function tracing
  6. LOG_LOGIC: control flow tracing within functions
  7. LOG_ALL: print everything

A special logging level will cause logging output to unconditionally appear on std::clog, regardless of whether the user has explicitly enabled logging. This macro, NS_LOG_UNCOND(), can be used like a kind of printf() in your code. An example can be found in scratch/scratch-simulator.cc:

NS_LOG_UNCOND ("Scratch Simulator");

Logging prefixes

This section still needs documentation; bug 1496 is open on this:

$ NS_LOG="*=all|prefix_all" ./waf --run scratch-simulator
Scratch Simulator
ScratchSimulator:main(): [ERROR] error message
ScratchSimulator:main(): [WARN] warn message
ScratchSimulator:main(): [DEBUG] debug message
ScratchSimulator:main(): [INFO] info message
ScratchSimulator:main(function)
ScratchSimulator:main(): [LOGIC] logic message

Enabling logging output

There are two ways that users typically control logging output. The first is by setting an NS_LOG environment variable; e.g.:

$ NS_LOG="*" ./waf --run first

will run the first tutorial program with all logging output. This can be made more granular by selecting individual components:

$ NS_LOG="Ipv4L3Protocol" ./waf --run first

The second way to enable this is to use explicit statements in your program, such as in the first tutorial program:

int
main (int argc, char *argv[])
{
  LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
  LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
  ...

Some helpers have special methods to enable the logging of all components in a module (across different compilation units, but logically grouped together such as the ns-3 wifi code:

WifiHelper wifiHelper;
wifiHelper.EnableLogComponents ();

How to add logging to your code

To add logging to your code, please follow the below steps:

  1. Put NS_LOG_COMPONENT_DEFINE macro outside of namespace ns3

Create a unique string identifier (usually based on the name of the file and/or class defined within the file) and register it with a macro call such as follows:

NS_LOG_COMPONENT_DEFINE ("Ipv4L3Protocol");

namespace ns3 {
...

The macro was carefully written to permit inclusion either within or outside of namespace ns3, and usage will vary across the codebase, but the original intent was to register this outside of namespace ns3.

  1. Add logging statements to your functions and function bodies.

There are a couple of guidelines on this:

  • Do not add function logging in operators or explicit copy constructors, since these will cause infinite recursion and stack overflow.
  • Use the NS_LOG_FUNCTION_NOARGS() variant for static methods only. When a non-static member function has no arguments, it should be logged by NS_LOG_FUNCTION (this) macro.
  • Make sure that you test that your logging changes do not break the code; running some example programs with all log components turned on (e.g. NS_LOG="*") is one way to test this.

Table Of Contents

Previous topic

Object names

Next topic

Tracing

This Page