【ns-3】Logging system

foreword

This article introduces the Logging system.


1 Overview

Many large systems will provide a console-based message recording function to give users real-time feedback on program execution. ns-3 is no exception. ns-3 provides an optional, multi-level message logging function—the Logging system. Logging can be disabled completely, enabled on a component-by-component basis, or enabled globally. The Logging system can also choose the verbosity level or severity level of the logged messages, and add different prefixes to the messages. Therefore, the Logging system provides a very flexible and powerful, but relatively simple message logging function [1] [2] .

It should be noted that the Logging system is mainly used in ns-3: first, to facilitate user understanding by outputting the execution process of the internal modules of the network component; second, to facilitate user debugging by outputting simple debugging information, rather than collecting simulation data[3 ] . ns-3 provides a general mechanism for collecting simulation data—Tracing system, which is our first choice for collecting simulation data [2] .


2. Basic concepts

As mentioned above, the Logging system provides a very flexible message recording function. Not only can the Logging function be enabled component by component, but also the level of detail or severity of the recorded messages can be selected, and different prefixes can be added to the messages.

Therefore, before introducing how to use the Logging system, in this section, we first introduce basic concepts such as Log Component, options to control the verbosity or severity of log output, and prefix options.

2.1 Log component

The log component is the smallest management unit of the Logging system. In layman's terms, a log component refers to a C++ source code file. Through the log component, the Logging system can precisely control the information output to a certain C++ file [1] [4] .

It is also very easy to add a C++ file as a log component, as long as the NS_LOG_COMPONENT_DEFINE macro is registered at the beginning of the C++ file within the scope of the ns3 namespace. Logging component names must be globally unique (usually based on the file name or the name of a class defined in the file).

For example, the first parameter in LogComponentEnable() in first.cc is the log component name (we will introduce the LogComponentEnable function later), as shown in the following figure:

insert image description here
The UdpEchoClinetApplication log component and the UdpEchoServerApplication log component represent the udp-echo-client.cc file and the udp-echo-server.cc file respectively, which are registered using the NS_LOG_COMPONENT_DEFINE macro within the ns3 name space at the beginning of the respective files, as shown in the following figure :

insert image description here
insert image description here
 

2.2 Log verbosity (severity) options

As mentioned above, through the log component, the Logging system can accurately control the information output to a certain C++ file. And through the log detail (or severity) option, the Logging system can further control the information output to a certain level of a certain C++ file.

In ns-3, the Logging system usually provides 7 log verbosity (or severity) options, the verbosity of the output information is from low to high (that is, the output information is from less to more) or the severity of the information is from high to low In turn [1] :

  • LOG_ERROR : Log error information (the associated macro is: NS_LOG_ERROR)
  • LOG_WARN : Log warning information (the associated macro is: NS_LOG_WARN)
  • LOG_DEBUG : Log relatively rare, special debug messages (associated macro: NS_LOG_DEBUG)
  • LOG_INFO : Record information related to the program process (the associated macro is: NS_LOG_INFO)
  • LOG_FUNCTION : Log a message describing each function called (associated macros are: NS_LOG_FUNCTION and NS_LOG_FUNCTION_NOARGS)
  • LOG_LOGIC : Record the internal logic flow information of the function (the associated macro is: NS_LOG_LOGIC)
  • LOG_ALL : Log all of the above information (no associated macros)

Notes :

In fact, ns-3 also defines a log level LOG_NONE in src/core/model/log.h , which will not record any information.


Let's still take first.cc as an example. The second parameter in LogComponentEnable() is the log detail (severity) option, as shown in the following figure:

insert image description here

It should be noted that, except for LOG_ALL, the remaining six log verbosity (or severity) options can only control the output of the information output in the associated macro. For example, the LOG_INFO level can only control the output of information output by all NS_LOG_INFO macros in the specified logging component.

In order to illustrate this point more intuitively, let's take a look at the following log-level-demo.cc sample script written by ourselves, and at the same time review and practice the relevant knowledge of the log component introduced above:

insert image description here
First, we register the file as a logging component called "LogLevelDemo" using the NS_LOG_COMPONENT_DEFINE macro in the ns3 namespace scope at the beginning of the file.

Next, we use the LogComponentEnable function in the main function to enable the LogLevelDemo log component, and set the log verbosity (or severity) option to LOG_INFO (about the use of the LogComponentEnable function, we will introduce it in detail later).

Then, we use ./ns3 to compile and run the script in the terminal in the ns-3.37 directory (the log-level-demo.cc file needs to be placed in the ns-3.37/scratch directory):

insert image description here
When compiling and running the log-level-demo.cc file for the first time, the default configuration will be automatically performed first.

The result is as follows:

insert image description here

We can see that only the information in the NS_LOG_INFO macro is output.

We can modify the log verbosity (or severity) option of LogComponentEnable to LOG_DEBUG, compile and run the script again using ./ns3, the results are as follows:

insert image description here

We can see that only the information in the NS_LOG_DEBUG macro is output.


Notes:

  • If no information is output following the above steps, you can check the configuration options (./ns3 show profile):

insert image description here
If the configuration option is optimized, no information will be output. Because the log statement will not be compiled under the optimized configuration [1] .

  • In fact, the above log levels do not have a very strict boundary division (depending on the use of the associated NS_LOG_TYPE macro), so sometimes it is inevitable to read the C++ source code [4] .

If we want to output the information in the NS_LOG_INFO macro and the NS_LOG_DEBUG macro at the same time, then we can do this:

insert image description here
Use ./ns3 to compile and run the script again, the result is as follows:

insert image description here

Both the information in the NS_LOG_INFO macro and the NS_LOG_DEBUG macro are output!

Sometimes, we want to output information with a certain level of detail (or severity) and a lower level of detail (or higher level of severity). For example, we want to output both LOG_INFO and lower verbosity (or higher severity) information. It would be cumbersome to specify explicitly as above, so the Logging system also defines a corresponding LOG_LEVEL_TYPE for each LOG_TYPE (except LOG_NONE), which can output LOG_TYPE and lower verbosity (or higher severity) information [ 1 ] :

  • LOG_LEVEL_ERROR
  • LOG_LEVEL_WARN
  • LOG_LEVEL_DEBUG
  • LOG_LEVEL_INFO
  • LOG_LEVEL_FUNCTION
  • LOG_LEVEL_LOGIC
  • LOG_LEVEL_ALL / LOG_ALL

Notes:

In fact, LOG_LEVEL_ERROR and LOG_ERROR are the same, because they only display logs of their own level; LOG_LEVEL_ALL and LOG_ALL are also consistent, because they both display logs of all levels.


Let's still take the log-level-demo.cc sample script as an example, and modify the second parameter in the LogComponentEnable function as follows:

insert image description here

Use ./ns3 to compile and run the script again, the result is as follows:

insert image description here
You can see that LOG_INFO and lower verbosity (or higher severity) information are output.

 

2.3 Log Prefix Options

In addition to the log verbosity (severity) option, the Logging system also provides a log prefix option. These prefixes help identify when and where a message originated, and the severity level [1] :

  • LOG_PREFIX_FUNC : Prefix the calling function name
  • LOG_PREFIX_TIME : Prefix the simulation time
  • LOG_PREFIX_NODE : plus node id prefix
  • LOG_PREFIX_LEVEL : Prefix the verbosity (or severity) level
  • LOG_PREFIX_ALL : plus all prefixes

Let's still take the log-level-demo.cc sample script as an example, and modify the LogComponentEnable function as follows:

insert image description here
Use ./ns3 to compile and run the script again, the result is as follows:

insert image description here
The output is prefixed with the log verbosity (or severity) level.

Let's modify the LogComponentEnable function as follows:

insert image description here
Use ./ns3 to compile and run the script again, the result is as follows:

insert image description here
The output information is prefixed with the log verbosity (or severity) prefix and the calling function name prefix (it should be noted that the function name prefix main() is preceded by the log component name rather than the file name or class name).

 

3. Control log output

ns-3 provides two commonly used methods of controlling log output [1] :

  • Control log output through the LogComponentEnable function: explicitly declare through the LogComponentEnable function in the main() main function

    insert image description here

    The first parameter of the LogComponentEnable function is the log component name (string), and the second parameter is the LogLevel option, including the log detail (severity) option and the log prefix option. The syntax is as follows:

    LogComponentEnable(<log-component>, <option>) // 单个日志选项
    LogComponentEnable(<log-component>, LogLevel(<option> | <option> | ...)) // 多个日志选项放在LogLevel()中并用|分开
    

    Regarding how to control the log output through the LogComponentEnable function, we will not go into details. For details, please refer to the above content.

  • Control log output through NS_LOG environment variable

    Through a large number of demonstrations of the log-level-demo.cc sample script above, it is not difficult to find that we need to modify the source code over and over again through the LogComponentEnable function to control the log output, which is cumbersome. So ns-3 also provides the way to control the log output through the NS_LOG environment variable, and its syntax is as follows:

    /*
    每个日志组件的选项罗列在日志组件的后面,用“|”隔开,日志组件和其所对应的选项之间用“=”连接
    不同日志组件之间用“:”隔开
    */
    NS_LOG="<log-component>=<option>|<option>... : <log-component>=<option>|<option>..." ./ns3 run <script>
    

    However, it should be noted that in the NS_LOG environment variable, the log detail (severity) option and log prefix option are given by the following token, which is different from the related syntax in the LogComponentEnable function [1 ] :

    insert image description here
    insert image description here
    Let's still take the log-level-demo.cc sample script as an example:
    insert image description here
    the log output is controlled by the NS_LOG environment variable in the terminal:
    insert image description here
    and if we use LOG_INFO and LOG_PREFIX_LEVEL to control the log output in the NS_LOG environment variable like the LogComponentEnable function, then the doesn't work, like this:
    insert image description here


Notes:

  • Whether controlling log output through the LogComponentEnable function or controlling log output through the NS_LOG environment variable, you need to use the NS_LOG_COMPONENT_DEFINE macro to register the log component first.

  • When the log output is controlled through the NS_LOG environment variable, there is no need to explicitly declare the log function through the LogComponentEnable function in the main() main function, as shown in the previous example.

  • NS_LOG="<log-component>:..." (that is, the specified log option is not displayed in the NS_LOG environment variable), the default log verbosity (severity) option is level_all, and the default log prefix option is all [1 ] .

  • If the log function is explicitly declared to be enabled through the LogComponentEnable function in the main() main function, then when the log output is controlled through the NS_LOG environment variable, the two methods will work together.
    For example:
    in the main function of main(), we explicitly declare to enable the log function through the LogComponentEnable function, and at the same time use the NS_LOG environment variable to control the log output: the result is as follows: The
    insert image description here
    LogComponentEnable
    insert image description here
    function and the NS_LOG environment variable work at the same time!

  • If you want to enable all components of a specific level of verbosity (severity), and add a specific prefix, you can use the wildcard "*" to represent all log components [1] :

NS_LOG="*=<option>|<option>“
  • If you want to enable a specific log component and turn on all log verbosity (severity), you can also use the wildcard "*" instead of "all" or "level_all". But wildcards for log verbosity (severity) should be preceded by the "|" symbol (if any) [1] :
NS_LOG="<log-component>=*|<option>“ // 等价于NS_LOG="<log-component>=all|<option>“
                                    // 或者NS_LOG="<log-component>=level_all|<option>“
  • If you want to enable a specific log component and add all log prefixes, you can also use the wildcard character "*" instead of "all. But the wildcard character for the log prefix must be after the "|" symbol [1 ] :
NS_LOG="<log-component>=<option>|*“ // 等价于NS_LOG="<log-component>=<option>|all“
  • The following commands are equivalent to [1] :
    insert image description here

references

[1]: ns-3 Manual
[2]: ns-3 Tutorial
[3]: ns-3 network simulator foundation and application
[4]: Open Source Network Simulator ns-3: Architecture and Practice

Guess you like

Origin blog.csdn.net/Graduate2015/article/details/129481225