• NS3系列—7———NS3日志



    http://www.cnblogs.com/lovemo1314/archive/2011/12/21/2295969.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_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文件。

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


  • 相关阅读:
    读《见识》 | 当别人扇了你一巴掌
    Java集合类
    Java数据结构简述
    Java加密算法
    Java JDK与JRE
    Java String、StringBuilder、StringBuffer[笔记]
    Java同步(Synchronization)
    Java断言(Assertion)
    Java strictfp
    Java Native Interface(JNI)
  • 原文地址:https://www.cnblogs.com/ztguang/p/12645739.html
Copyright © 2020-2023  润新知