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. > export NS_LOG = '<日志模块名称> =level_all | prefix_func | prefix_time' 

  

  • level_all 表示启用所有级别(=error | warn | debug | info | function | logic)
  • prefix_func 表示记录输出该消息的函数
  • prefix_time 表示加上时间前缀
$~/ns-3.2. > export NS_LOG = '<日志模块名称1>=level_all : <日志模块名称2>=info'

  

  • 符号 : 表示隔开两个不同的日志模块
$~/ns-3.2. > export NS_LOG = * = level_all
  • 符号 * 作为通配符。上行命令表示启用所有可用模块的所有日志级别。
  • 这一般会形成大量的数据,此时可以使用 shell 的输出重定向保存日志到文件里面:

    

$~/ns-3.2. > ./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. > ./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. > ./waf --run "scratch/example --PrintAttributes=ns3::PointToPointNetDevice"

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

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

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

$~/ns-3.2. > ./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. > ./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:网络设备接收数据包。

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

 +

 /NodeList//DeviceList//$ns3::PointToPointNetDevice/TxQueue/Enqueue
ns3::PppHeader (
 Point-to-Point Protocol: IP (0x0021))
 ns3::Ipv4Header (
  tos 0x0 ttl id offset flags [none]
  length: 10.1.1.1 > 10.1.1.2)
  ns3::UdpHeader (
   length: > )
   Payload (size=)

其中编号为 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

NS3 日志(Logging)、命令行参数、Tracing系统概述(转载)的更多相关文章

  1. 【NS-3学习】ns3-模拟基础:关键概念,日志,命令行参数

    前言 本篇博客先介绍在仿真过程中会使用到的一些关键概念,然后介绍便于调试仿真脚本的常用技术:日志.命令行参数. 关键概念 节点 在因特网术语中,主机(终端)是指任何一台连接到网络的计算设备.ns-3并 ...

  2. Win32程序支持命令行参数的做法(转载)

    转载:http://www.cnblogs.com/lanzhi/p/6470406.html 转载:http://blog.csdn.net/kelsel/article/details/52759 ...

  3. 【前端】Vue和Vux开发WebApp日志四、增加命令行参数

    转载请注明出处:http://www.cnblogs.com/shamoyuu/p/vue_vux_4.html 项目github地址:https://github.com/shamoyuu/vue- ...

  4. ns3的输入输出奥秘(二) 命令行参数

    命令行参数 (1) UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9); echoClient.SetAttribute (&q ...

  5. httprunner学习15-运行用例命令行参数详解

    前言 HttpRunner 在命令行中启动测试时,通过指定参数,可实现丰富的测试特性控制. 命令行参数CLI 使用 -h 查看相关命令行参数 hrun -h 参数名称 参数值 参数说明 -h, --h ...

  6. pytest封神之路第二步 132个命令行参数用法

    在Shell执行pytest -h可以看到pytest的命令行参数有这10大类,共132个 序号 类别 中文名 包含命令行参数数量 1 positional arguments 形参 1 2 gene ...

  7. pytest132个命令行参数用法

    在Shell执行pytest -h可以看到pytest的命令行参数有这10大类,共132个 序号 类别 中文名 包含命令行参数数量 1 positional arguments 形参 1 2 gene ...

  8. Python测试框架pytest命令行参数用法

    在Shell执行pytest -h可以看到pytest的命令行参数有这10大类,共132个 序号 类别 中文名 包含命令行参数数量 1 positional arguments 形参 1 2 gene ...

  9. Chrome浏览器启动参数大全(命令行参数)

    前言 在开发Web项目当中,浏览器必不可少,而浏览器的启动参数可以帮我们实现很多功能. 常用参数 常用参数请参考下表. 序号 参数 说明 1 --allow-outdated-plugins 不停用过 ...

  10. mysql命令行参数(转)

    MySQL命令行参数 Usage: mysql [OPTIONS] [database] //命令方式  -?, --help //显示帮助信息并退出  -I, --help //显示帮助信息并退出  ...

随机推荐

  1. [ERROR][org.springframework.web.context.ContextLoader][main] Context initialization failed org.sprin

    做一个SSH为基础框架的webapp小DEMO,复制了一把以前可以跑的代码,竟发现无法初始化数据源,报错如下: [ERROR][org.springframework.web.context.Cont ...

  2. Android系统版本与API Level对照表

    Platform Version API Level VERSION_CODE Notes Android 4.2 17 JELLY_BEAN_MR1   Android 4.1, 4.1.1 16 ...

  3. iOS开发- 蓝牙后台接收数据(BLE4.0)

    最近在做一个蓝牙相关的项目, 需要在应用进入后台, 或者手机属于锁屏状态的情况下, 仍然保持蓝牙连接, 并且能正常接收数据. 本来以后会很麻烦, 但是学习了下..发现就2步而已.简单的不能再简单了. ...

  4. hdwiki 框架简介

    虽然HDwiki是一个开源的wiki系统,并且代码简洁易懂,但如果想在系统上做做进一步开发还需要对框架有一个整体的认识.熟悉了HDwiki的框架以后完全可以独立出来做其他功能的开发,当做一个开源的PH ...

  5. char 型变量中能不能存贮一个中文汉字,为什么?

    char类型可以存储一个中文汉字,因为Java中使用的编码是Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个char类型占2个字节(16比特),所以放一个 ...

  6. python: shutil模块 -拷贝文件

    import shutil #拷贝文件 #存在文档1文件 shutil.copyfile('文档1','新文件') 随机验证码-4位 import random random_code='' for ...

  7. HDU-1042 N!

    首先明白这是大数问题,大数问题大多采用数组来实现.如何进位.求余等.比如1047 (Integer Inquiry): 对于1042问题 计算10000以内数的阶乘,因为10000的阶乘达到35660 ...

  8. android pbap client 蓝牙

    一.  简介: 此功能具体使用的是bluetoothV2.1之后的Phone Book Access Profile功能,简称PBAP .目前MTK Android中只实现了server端的功能,并没 ...

  9. 数据库查询优化器的艺术:原理解析与SQL性能优化

    数据库查询优化器的艺术 作者:李海翔 Oracle公司MySQL全球开发团队.资深专家 简单的浏览了一遍,由于以前没有接触过SQL优化这些知识,读起来还是非常吃力的,不过收获还是很大的. 作者通过对M ...

  10. 开发与测试整体过程中的Git分支merge流程

    开发与测试整体过程中的Git分支merge流程 Git分支merge之开发流程 首先在Gitlab上有个仓库存储着原始的项目代码,其中包含一个叫master的分支.然后可能按功能进行分配,由不同的开发 ...