NS-3的日志系统

原文地址:http://hi.baidu.com/czlaner/blog/item/2d19b1888f6cdf93a4c272d3.html

--------------------------------------------------------------------------------------------------------------

 

NS-3日志子系统的提供了各种查看仿真结果的渠道:
一、使用Logging Module
0、【预备知识】日志级别及其对应的宏
NS-3提供了若干个日志级别来满足不同的Debug需求,每一级的日志内容都涵盖了低一级的内容。这些级别对应的宏从低到高排列为:
  *NS_LOG_ERROR — Log error messages;
  *NS_LOG_WARN — Log warning messages;
  *NS_LOG_DEBUG — Log relatively rare, ad-hoc debugging messages;
  *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.
  *NS_LOG_UNCOND — 无条件输出

方式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_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
1、启用ASCII Tracing
  NS-3提供了类似NS-2的日志输出(*.tr文件),记录系统中的动作。在Simulator::Run()之前添加语句:
   #include <fstream>
   ...
   std::ofstream ascii;
   ascii.open ("example.tr");
   PointToPointHelper::EnableAsciiAll (ascii);
  则运行后我们可以在example.tr文件中看到系统的日志(使用ASCII文本阅读器即可),其中每一行都是以+/-/d/r开头的:
   +: An enqueue operation occurred on the device queue;
   -: A dequeue operation occurred on the device queue;
   d: A packet was dropped, typically because the queue was full;
   r: A packet was received by the net device.
  例如我们可以看到文件中的第一行(为了说明方便,这里分段编号显示),显示了一个入队操作:
   00 +
   01 2
   02 /NodeList/0/DeviceList/0/$ns3::PointToPointNetDevice/TxQueue/Enqueue
   03 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表示在传送队列上发 生了入队操作,也就是行开头的+所表现的意义。

2、启用PCAP Tracing
  NS-3也可以生成*.pcap文件,从而可以使用诸如Wireshark、tcpdump(前文NS-3入门[1]概念引入 介绍过)等工具进行分析。
 2.1)在脚本Simulator::Run()之前添加语句:
   PointToPointHelper::EnablePcapAll ("example");
  这个语句将会产生若干*.pcap文件,命名为example-<Node编号>-<NetDevice编号>.pcap, 分别记录每个设备的日志。也可以使用语句***Helper::EnablePcap (filename, NodeId, DeviceId)来只产生特定设备的pcap文件:
   PointToPointHelper::EnablePcap ("example", p2pNodes.Get (0)->GetId (), 0);  //只产生example-0-0.pcap文件
 2.2)使用tcpdump在命令行阅读pcap文件:
   ~/ns-3.2.1 > tcpdump -r example-0-0.pcap -nn -tt
   reading from file second-0-0.pcap, link-type PPP (PPP)
   2.000000 IP 10.1.1.1.49153 > 10.1.2.4.9: UDP, length 1024
   2.007382 IP 10.1.2.4.9 > 10.1.1.1.49153: UDP, length 1024
 2.3)使用Wireshark等软件打开pcap文件。

02f,18aug03,agi added #include 02e,02jun03,agi removed #include "rwproto.h" 02d,02jun03,agi changed #include "rwos.h" to include "ospf_rwos.h" 02c,29may03,agi removed unused includes, added new includes 02c,08may03,asr Changes to make OSPF virtual stack compatible 02b,09may03,agi added #include , removed #include 02a,17feb02,ram SPR 81808 Added OSPF memory partition support 21,13october01,kc Dynamic configuration changes. 20,21september01,kc Removed unused raw socket specific declarations. 19,26september00,reshma Added WindRiver CopyRight 18,25september00,reshma RFC-1587 implementation for OSPF NSSA Option, also tested against ANVL. 17,20july00,reshma Unix compatibility related changes. 16,06july00,reshma Removed unnecessary header files and defines. 15,23february00,reshma Changes for ospf mib 14,23december99,reshma Compatibility with VxWorks-IP and VxWorks RTM-interface 13,13august99,jack compilation fixes no IP case 12,05august99,nishit Replaced including IP header files by the new ospf_ip_structures.h 11,17may99,jack Added new include file ospf_patricia_32_bits_key_prototypes.h 10,28december98,jack Compiled and added some comments 09,25november98,rajive Deleted socket include file 08,11november98,jack Config changes, linted and big endian changes 07,30october98,jack Incorporate changes for compilation on Vxworks 06,12february98,release engineer code style changes, feature enhancements, complete CISCO and BAY compaltibility. OSPF v4.2.0 05,10july97,cindy Pre-release v1.52b 04,10february97,cindy Release Version 1.52 03,22october97,cindy Release Version 1.50 02,05june96,cindy Including visnpstr.h as a kludge for the first beta release. 01,05june96,cindy First Beta Release
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值