博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NS3 日志(Logging)、命令行参数、Tracing系统概述(转载)
阅读量:4977 次
发布时间:2019-06-12

本文共 7695 字,大约阅读时间需要 25 分钟。

 

NS-3日志子系统的提供了各种查看仿真结果的渠道:

一、使用Logging Module

1 【预备知识】日志级别及其对应的宏

 

NS-3 提供了若干个日志级别来满足不同的 Debug 需求,每一级的日志内容都涵盖了低一级的内容。这些级别对应的宏从低到高排列为:

  • LOG_ERROR — Log error messages (associated macro: NS_LOG_ERROR);
  • LOG_WARN — Log warning messages (associated macro: NS_LOG_WARN);
  • LOG_DEBUG — Log relatively rare, ad-hoc debugging messages (associated macro: NS_LOG_DEBUG);
  • LOG_INFO — Log informational messages about program progress (associated macro: NS_LOG_INFO);
  • LOG_FUNCTION — Log a message describing each function called (two associated macros: NS_LOG_FUNCTION, used for member functions, and NS_LOG_FUNCTION_NOARGS, used for static functions);
  • LOG_LOGIC – Log messages describing logical flow within a function (associated macro: NS_LOG_LOGIC);
  • LOG_ALL — Log everything mentioned above (no associated macro).

 

方式1、通过设置shell环境变量NS_LOG使用日志系统

 

1.1)首先,定义好一个日志模块:

  可以在脚本中使用宏 NS_LOG_COMPONENT_DEFINE(name) 定义一个日志模块。(注意,为了使用宏 NS_LOG(name, level) 来输出这个模块所定义的内容,这个定义语句必须写在每个脚本文件的开始。宏 NS_LOG 将在方式 2 中进行介绍。)

  也有一些日志模块是内置的,比如上文的名为 “UdpEchoClientApplication” 、“UdpEchoServerApplication” 的模块就是 UdpEcho 应用程序内置的日志模块,只要使用了相应的类,就可以启用相应的日志模块。

1.2)在 shell 中通过设置环境变量 NS_LOG,来控制仿真输出级别:

 

$~/ns-3.2.1 > export NS_LOG = '
<日志模块名称>
=level_all | prefix_func | prefix_time' 

    

  • level_all 表示启用所有级别(=error | warn | debug | info | function | logic)
  • prefix_func 表示记录输出该消息的函数
  • prefix_time 表示加上时间前缀

 

$~/ns-3.2.1 > export NS_LOG = '
<日志模块名称1>
=level_all :
<日志模块名称2>
=info'

  

  • 符号 : 表示隔开两个不同的日志模块

 

$~/ns-3.2.1 > export NS_LOG = * = level_all

 

  • 符号 * 作为通配符。上行命令表示启用所有可用模块的所有日志级别。
  • 这一般会形成大量的数据,此时可以使用 shell 的输出重定向保存日志到文件里面:

    

$~/ns-3.2.1 > ./waf --run scratch/example >& log.out

 

方式2、通过在脚本里使用宏NS_LOG调用日志模块

 

2.0)宏 NS_LOG(level, msg) 用于定义对应 level 的输出内容;为了方便使用,系统预定义了各个级别的 NS_LOG 宏 NS_LOG_ERROR等(参见【预备知识】):

  

#define NS_LOG_ERROR(msg)   NS_LOG(ns3::LOG_ERROR, msg)

2.1)如上文,在脚本里使用宏 NS_LOG_COMPONENT_DEFINE(name) 定义一个日志模块;

2.2)使用宏 LogComponentEnable(name, level) 启用日志(对应地,有宏 LogComponentDisable(name, level) 用于禁用日志);

2.3)使用【预备知识】里定义的各种级别的宏输出内容,注意程序只会输出低于等于已经启用的 level 的宏内容。

 

 NS_LOG_COMPONENT_DEFINE("Example"); LogComponentEnable("Example", LOG_LEVEL_INFO);   //等价于shell中:export NS_LOG = 'Example=info'  //运行时显示程序中用语句NS_LOG_INFO(“字符串”)定义的字符串,便于检查错误。 NS_LOG_WARN("Message:level_warn"); NS_LOG_INFO("Message:level_info"); NS_LOG_LOGIC("Message:level_logic"); //由于我们启用的日志level是INFO,因此编译运行后,程序会输出低于和等于INFO级别的内容,而高于INFO级别的宏内容不会被输出 //即,Message:level_warn和Message:level_info会被输出,而Message:level_logic不会被输出

 

===============================================================================================================

二、使用Command Line(命令行)参数

仿真一般是为了收集各种不同条件下的数据,常常需要改变一些变量。NS-3 提供了Command Line 参数接口,可以在运行时对脚本中的变量进行设置,免去了每次更改变量后要重新编译的麻烦。(相当于在运行前进行变量的 scanf/cin 操作,但因为有默认值,CLI 更灵活一些。)

1、在脚本中添加语句

int main (int argc, char *argv[]){  ...  CommandLine cmd;  cmd.Parse (argc, argv);  //将命令行输入的参数作为类CommandLine的参数进行分析  ...}

 

这样可以在 shell 中使用某些附加参数如 PrintHelp:

 

$~/ns-3.2.1 > ./waf --run "scratch/example --PrintHelp"

 

这条命令将会列出 example 当前可用的命令参数:

 

Entering directory '/home/craigdo/repos/ns-3-dev/build'Compilation finished successfully--PrintHelp: Print this help message.--PrintGroups: Print the list of groups.--PrintTypeIds: Print all TypeIds.--PrintGroup=[group]: Print all TypeIds of group.--PrintAttributes=[typeid]: Print all attributes of typeid.--PrintGlobals: Print the list of globals.

  

从输出中(倒数第二行)我们知道可以打印某些类的属性:

 

$~/ns-3.2.1 > ./waf --run "scratch/example --PrintAttributes=ns3::PointToPointNetDevice"

 

这条命令将会列出类型为 PointToPointNetDevice 的设备的属性:

   

--ns3::PointToPointNetDevice::DataRate=[32768bps]:   The default data rate for point to point links

 

知道了属性名称,我们也可以使用命令更改这个属性:

 

$~/ns-3.2.1 > ./waf --run "scratch/example --ns3::PointToPointNetDevice::DataRate=5Mbps"

 

 

2、使用 CommandLine::AddValue 添加自己的变量,使之成为 CommandLine 可以使用的参数:

 

CommandLine cmd;cmd.AddValue("nPackets", "Number of packets to echo", nPackets);   //(属性名称,属性说明,变量)cmd.Parse(argc, argv);

 

这样在 shell 中我们可以在命令中更改这个属性:

$~/ns-3.2.1 > ./waf --run "scratch/example --nPackets=2"

 

===============================================================================================================

 

三、使用Tracing System

 

Ns-3 tracing 系统的基本目标:

  • 基本任务,tracing 系统允许用户生成标准 tracing,且自定义哪些对象生成 tracing;
  • 中级用户必须能扩展 tracing 系统来修改输出的生成格式,或者插入新的 tracing sources ,而不用修改仿真器的核心;
  • 高级用户可以修改仿真器的核心来添加 tracing sources 和 tracing  sinks。

 

Ns-3 tracing 系统建立在独立的 tracing sources 和 tracing sinks 概念之上,有一个统一的机制连接 sources 和 sinks  。Trace sources 是仿真过程中标识事件发生的实体,可以对内部数据进行访问,为感兴趣的潜在数据提供接口。例如,trace sources 可以指示网络设备什么时候接收到数据包,并能对感兴趣的 trace sinks 的数据包内容提供访问。

Traces sources 本身无用,它们必须连接到其他的代码上才行,这些代码会利用 sinks 提供的信息做些有用的事。Trace sinks 是 traces sources 提供的事件和数据的消费者。例如,一个 trace sink 连接到一个 trace source 上,trace sink 会显示接收到的数据包中感兴趣的部分。只有将 trace sink 与 trace source 连接起来才可以对仿真过程中感兴趣的事件或数据进行处理。

明确的划分 trace source 和 trace sink目的是允许用户连接新类型的输出到已有的tracing source 上,而不用编辑和重新编译仿真器的核心。因此,如上述例子,用户只需编辑用户脚本就可以在其脚本上定义新的 tracing sink 并把它连接到仿真核心中。

Tracing 系统的设计遵循两个思想:即 trace source 与 trace sink 相互独立和采用标准的输出格式。

在trace 输出格式上,ns-3 既考虑了标准化的要求,也考虑了前后延续的要求,提供了两种输出格式:ASCII 格式和 PCAP 格式。ASCII 格式类似于 ns-2 中使用的 .tr 文件格式,采用以行为单位的字符串来表示网络事件;PCAP 格式是一种标准的网络抓包文件格式,可以采用多种工具进行分析,如 tcpdump 和 wireshark。

 

1 启用 ASCII Tracing

Ns-3 提供 helper 功能(封装底层 tracing 系统)来帮助你理解配置数据包 traces 的细节。如果启用该功能,你会看到输出为ASCII 的文件。

在我们的脚本 scratch/myfirst.cc 中添加一些 ASCII tracing 输出,在调用 Simulator::Run () 之前添加下列代码:

 

AsciiTraceHelper ascii;pointToPoint.EnableAsciiAll (ascii.CreateFileStream ("myfirst.tr"));

 

上述代码的第二行包含两个嵌套的方法调用。第一个是“内部”方法,CreateFileStream() 使用未命名的对象习语在堆栈上创建文件流对象,并把它传递给调用的方法。需要明确的是,你正在创建一个对象,文件名为 “myfirst.tr”,然后你把它传递给 ns3。

第二个方法是外部调用,EnableAsciiAll() 告诉 helper 你想要在仿真中对所有的点对点设备使能 ASCII tracing,想要 trace sinks 以 ASCII 格式写出数据包运动的信息。

现在可以 build 脚本并在命令行运行。

运行时会创建文件 myfirst.tr,默认创建在资源库的 top-level 路径。若想控制 traces 保存的地方,可以使用 Waf 的 --cwd 选项指定。然后以最喜欢的编辑器打开 ASCII trace 文件 myfirst.tr。(在ns-3.22目录下)

 

2 解析 ASCII Tracing

 

myfirst.tr 文件中有很多信息以密集的形式出现,但是我们首先注意到的事情是文本中出现链路很多独特的行。

文件中的每一行都与一个trace event 相关。我们在每个点对点网络设备的传输队列上tracing events 。

注意,Trace 文件每一行开始都有一个单独的字符,其含义为:

  +:设备队列入队操作;

  -:设备队列出对操作;

  d:丢弃数据包;

  r:网络设备接收数据包。

 

例如我们可以看到文件中的第一行(为了说明方便,这里分段编号显示),显示了一个入队操作:

 

00 +01 202 /NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Enqueue03 ns3::PppHeader (04  Point-to-Point Protocol: IP (0x0021))05  ns3::Ipv4Header (06   tos 0x0 ttl 64 id 0 offset 0 flags [none]07   length: 1052 10.1.1.1 > 10.1.1.2)08   ns3::UdpHeader (09    length: 1032 49153 > 9)10    Payload (size=1024)

 

其中编号为 02 的部分显示了发生操作的路径:根 /NodeList 是 NS-3 维护的所有节点列表,因此 /NodeList/0 表示编号为 0 的节点;随后的 /DeviceList/0 表示在该节点上的编号为 0 的 NetDivece(比如网卡);接下来的$ns3::PointToPointNetDevice 指明了该 NetDivece 的类型;最后的 TxQueue/Enqueue 表示在传送队列上发生了入队操作,也就是行开头的 + 所表现的意义。

 

3 启用 PCAP Tracing

Ns-3设备 helpers 也可以用来创建 .pcap 格式的 trace 文件。首字母缩略词 pcap 表示 packet capture(数据包捕获),通常是包含定义 .pcap 文件格式的 API 。可以显示和读取这种格式的最受欢迎的编程工具是 Wireshark。然而,有很多业务 trace 分析器使用该数据包格式。我们鼓励用户利用多种可用的工具来分析 pcap traces。

 

(1)使用 tcpdump 来查看 pcap traces。

 

启用 pcap tracing的代码:

 

pointToPoint.EnablePcapAll  ("myfirst");

 

在之前 scratch/myfirst.cc 中添加过的 ASCII tracing 代码的后面插入这行代码。

注意,我们只是传递字符串 "myfirst" 而不是 “myfirst.pcap” 或其他相似的。这是因为该参数是一个前缀,而不是一个完整的文件名。helper 会为每个 point-to-point 设备创建 trace 文件,文件名格式会使用前缀、节点编号、设备编号和 .pcap 后缀,例如 “myfirst-0-0.pcap”。

在我们运行完脚本后,我们最终会看到文件 “myfirst-0-0.pcap” “myfirst-1-0.pcap”,分别对应节点0-设备0和节点1-设备0。

一旦添加完这行代码使能 pcap tracing 后,可以按照通常的方式运行脚本:

 

$ ./waf --run scratch/myfirst

 

结果显示为:

 

(2)使用 Wireshark 读取输出

Wireshark 是一款图形用户界面,可以用来显示 trace 文件。

例如,myfirst-0-0.pcap 文件用 Wireshark 打开显示如下:

 

 

=======End===================================================================

 

 

参考文献:

[1] http://www.cnblogs.com/lovemo1314/archive/2011/12/21/2295969.html

[2] https://www.nsnam.org/docs/tutorial/singlehtml/index.html#document-index

转载于:https://www.cnblogs.com/alice123/p/5467936.html

你可能感兴趣的文章
引用类型-Function类型
查看>>
(转)Android 仿订单出票效果 (附DEMO)
查看>>
数据库多张表导出到excel
查看>>
微信小程序去除button默认样式
查看>>
Where does Visual Studio look for C++ Header files?
查看>>
Java打包可执行jar包 包含外部文件
查看>>
Windows Phone开发(37):动画之ColorAnimation
查看>>
js中escape,encodeURI,encodeURIComponent 区别(转)
查看>>
sass学习笔记-安装
查看>>
Flask (二) cookie 与 session 模型
查看>>
修改添加网址的教程文件名
查看>>
[BZOJ 1017][JSOI2008]魔兽地图DotR(树形Dp)
查看>>
裁剪图片
查看>>
数据结构实习 problem L 由二叉树的中序层序重建二叉树
查看>>
VS中展开和折叠代码
查看>>
如何确定VS编译器版本
查看>>
设置PL/SQL 快捷键
查看>>
个人阅读作业7
查看>>
转载:深入浅出Zookeeper
查看>>
GMA Round 1 新程序
查看>>