欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

NS3 Logging Module 日志模块

程序员文章站 2022-06-22 09:54:43
...

一 概述日志


日志是快速获得脚本和模型的调试信息、警告信息、错误信息或者其他信息的首选。
NS3日志模块提供了一个直观的、相对简单的方法来获取仿真过程中的有用信息。在NS3中,不同详尽级别的日志都是有用的,为了方便高效,NS3提供了可供选择的、多级别的方法来记录日志,例如可以完全禁用日志、仅对部分组件可用、或者全局可用。并且NS3将日志分成了七个详尽递增的级别:

NS_LOG_ERROR——Log error messages. 记录错误信息

NS_LOG_WARN——Log warning messgaes. 记录警告信息

NS_LOG_DEBUG——Log relatively rare, ad-hoc debugging messages. 记录相对不常见ad-hoc的调试信息

NS_LOG_INFO——Log informational messages about program progress. 记录程序进展信息

NS_LOG_FUNCTION——Log a message describing each function called. 记录描述每个调用函数信息

NS_LOG_LOGIC——Log messages describing logical flow within a function. 记录一个函数内描述逻辑流程的信息

NS_LOG_ALL——Log everything mentioned above. 记录所有信息

此外,还有一种一直被使用的无条件日志级别,与日志级别或者组件选择无关。

NS_LOG_UNCOND——Log theassociated message unconditionally. 无条件记录相关消息


每个级别可以被单独调用或者累计调用。日志的配置可以通过使用一个shell环境变量或者调用日志系统函数。

使用日志


在ns3的目录/ns3/ns-allinone-3.25/ns-3.25/examples/tutorial下边有个third.cc程序,它是一个关于UDP的CS模型(服务器和客户端通信模型),我们拿这个作为例子讲解。
首先,将这个例子复制到 /ns3/ns-allinone-3.25/ns-3.25/scratch
命令./waf –run=scratch/third编译执行这个程序。
NS3 Logging Module 日志模块

输出的四行数据就是我们的CS通信过程。然而为什么会输出四句话呢?我们在程序中并没有输出语句?原因也很简单,就是本文所讲的日志模块。也就是说上面的“sent”和“received”的消息来自于UdpEchoClientApplication和UdpEchoServerApplication的日志消息。我们在third.cc程序中由这样两行:

NS3 Logging Module 日志模块


LogComponentEnable(“UdpEchoClientApplication”,LOG_LEVEL_INFO); //设置日志级别为LOG_LEVEL_INFO,当传递一个日志标志时,实际上打开了该级别及其以下的所有级别。所以,这行代码表示打开了NS_LOG_INFO,NS_LOG_DEBUG,NS_LOG_WARN,NS_LOG_ERROR。(高等级包括低等级)。


然而我们可以修改日志等级,方便我们调试和理解程序实现细节。通过设置NS_LOG环境变量,在不改变脚本和重新编译的情况下来增加日志的级别:

几种常用日志级别

(1)export ‘NS_LOG=UdpEchoClientApplication=level_all’


设置shell环境变量NS_LOG为字符串:
UdpEchoClientApplication=level_all
等号左边:想要设置的日志组件名称
等号右边:要用的日志级别

NS3 Logging Module 日志模块


我们看到输出的信息比之前增加了。这些额外的调试信息是来自NS_LOG_FUNTION级别的日志。这些信息显示了在脚本运行期间程序中每个函数调用过程。

(2)export ‘NS_LOG=UdpEchoClientApplication=level_all|prefix_func’


在某些情况下,很难确定某条日志消息是由哪个方法产生的。所以,为了得知日志消息的来源,可以通过在NS_LOG环境变量中的prefix|func级别来解决。
NS3 Logging Module 日志模块


现在每条消息的来源都非常的明确。

(3)export

‘NS_LOG=UdpEchoClientApplication=level_all|prefix_func:UdpEchoServerApplication=level_all|prefix_func’

这样可以看到来自echo客户端和服务器的所有日志消息,这样方便调试。

NS3 Logging Module 日志模块

(4)可以通过prefix_time来知道仿真时间

NS3 Logging Module 日志模块


可以看到UdpEchoServer的构造函数在仿真的第0秒被调用。事实上这实在仿真开始之前就完成了,但时间显示的是0秒。UdpEchoClient的构造函数也是一样。


在scratch/third.cc脚本中,1秒时启动回显服务器应用。可以看到服务器的StartApplication实际上是在1秒时被调用。同样,客户端响应程序正如我们所预料的在仿真2秒时开始。


我们现在可以看到仿真的进度了,我们可以看到从ScheduleTransmit函数在客户端中调用send函数,到回显服务器中调用HandleRead函数的整个过程了。注意到通过点到点连接发送包消耗时间是3.69毫秒。查看回显服务器日志记录了一条消息告诉你已经响应了数据包。在另一个通道延迟后,可以看到响应客户端用它HandleRead方法收到响应包。


当碰到一个问题或是不知道那里出错了,我们可以选择使用最详细的日志功能,这样可以很简单的跟踪程序,而无需设置断点并且在调试器中一步步运行代码,用喜欢的编辑器来打开查看日志,寻找问题所在。当对错误有了大致了解之后,我们使用调试器对问题有个非常详细的检查。当你的脚本做了完全非预期的事,这种输出将是非常有用的。如果你使用调试器单步运行,或许你会错过偏差的部分。日志使得这些偏差非常明显。

三 为自己的脚本添加日志功能


可以通过几个宏调用日志组件给仿真增加新的日志功能。
例如在first.cc中,我们已经定义了一个组件:
NS_LOG_COMPONENT_DEFINE(“FirstScriptExample”);
我们已经了解了通过设置NS_LOG环境变量来给组件启用日志功能。我们可以给脚本增加一些日志功能。用来增加信息级别的日志消息的宏是NS_LOG_INFO。
现在我们来增加一个日志消息,显示本脚本在“创建拓扑”:

NS3 Logging Module 日志模块


注:用waf编译脚本并且清除NS_LOG环境变量,来关掉之前启用的日志文件
./waf export NS_LOG=


然后运行脚本,但是看不到新的日志消息,那是因为与它相关的日志组件(FirstScriptExample)没有被启用。为了看到该日志的消息,必须使用大于或等于NS_LOG_INFO的日志级别来启用FirstScriptExample日志组件。如果只是想要看某个级别的日志,你可以通过下面的语句来启用它,

$ export NS_LOG=FirstScriptExample=info


再运行脚本,可以看到“Creating Topology”的日志消息。

NS3 Logging Module 日志模块

相关标签: logging