A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
interface_statistics.py
1 import gtk
2 import ns.core
3 import ns.network
4 from visualizer.base import InformationWindow
5 
6 NODE_STATISTICS_MEMORY = 10
7 
8 
9 class StatisticsCollector(object):
10  """
11  Collects interface statistics for all nodes.
12  """
13 
14  class NetDevStats(object):
15  __slots__ = ['rxPackets', 'rxBytes', 'txPackets', 'txBytes',
16  'rxPacketRate', 'rxBitRate', 'txPacketRate', 'txBitRate']
17 
18  def __init__(self, visualizer):
19  self.node_statistics = {} # nodeid -> list(raw statistics)
20  self.visualizer = visualizer
21 
22  def simulation_periodic_update(self, viz):
23  nodes_statistics = viz.simulation.sim_helper.GetNodesStatistics()
24  for stats in nodes_statistics:
25  try:
26  raw_stats_list = self.node_statistics[stats.nodeId]
27  except KeyError:
28  raw_stats_list = []
29  self.node_statistics[stats.nodeId] = raw_stats_list
30  raw_stats_list.append(stats.statistics)
31  while len(raw_stats_list) > NODE_STATISTICS_MEMORY:
32  raw_stats_list.pop(0)
33 
34  def get_interface_statistics(self, nodeId):
35  try:
36  raw_stats_list = self.node_statistics[nodeId]
37  except KeyError:
38  return []
39 
40  if len(raw_stats_list) < NODE_STATISTICS_MEMORY:
41  return []
42  assert len(raw_stats_list) == NODE_STATISTICS_MEMORY
43  tx_packets1 = [] # transmitted packets, one value per interface
44  rx_packets1 = []
45  tx_bytes1 = []
46  rx_bytes1 = []
47  for iface, stats in enumerate(raw_stats_list[0]):
48  tx_packets1.append(stats.transmittedPackets)
49  tx_bytes1.append(stats.transmittedBytes)
50  rx_packets1.append(stats.receivedPackets)
51  rx_bytes1.append(stats.receivedBytes)
52 
53  retval = []
54 
55  k = self.visualizer.sample_period*(NODE_STATISTICS_MEMORY-1)
56  for iface, stats in enumerate(raw_stats_list[-1]):
57  outStat = self.NetDevStats()
58  outStat.txPackets = stats.transmittedPackets
59  outStat.txBytes = stats.transmittedBytes
60  outStat.rxPackets = stats.receivedPackets
61  outStat.rxBytes = stats.receivedBytes
62 
63  outStat.txPacketRate = (stats.transmittedPackets - tx_packets1[iface])/k
64  outStat.rxPacketRate = (stats.receivedPackets - rx_packets1[iface])/k
65  outStat.txBitRate = (stats.transmittedBytes - tx_bytes1[iface])*8/k
66  outStat.rxBitRate = (stats.receivedBytes - rx_bytes1[iface])*8/k
67  retval.append(outStat)
68  return retval
69 
70 
72  (
73  COLUMN_INTERFACE,
74 
75  COLUMN_TX_PACKETS,
76  COLUMN_TX_BYTES,
77  COLUMN_TX_PACKET_RATE,
78  COLUMN_TX_BIT_RATE,
79 
80  COLUMN_RX_PACKETS,
81  COLUMN_RX_BYTES,
82  COLUMN_RX_PACKET_RATE,
83  COLUMN_RX_BIT_RATE,
84 
85  ) = range(9)
86 
87  def __init__(self, visualizer, node_index, statistics_collector):
88  InformationWindow.__init__(self)
89  self.win = gtk.Dialog(parent=visualizer.window,
90  flags=gtk.DIALOG_DESTROY_WITH_PARENT|gtk.DIALOG_NO_SEPARATOR,
91  buttons=(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE))
92  self.win.connect("response", self._response_cb)
93  self.win.set_title("Statistics for node %i" % node_index)
94  self.visualizer = visualizer
95  self.statistics_collector = statistics_collector
96  self.node_index = node_index
97  self.viz_node = visualizer.get_node(node_index)
98 
99  self.table_model = gtk.ListStore(*([str]*13))
100 
101  treeview = gtk.TreeView(self.table_model)
102  treeview.show()
103  self.win.vbox.add(treeview)
104 
105  def add_column(descr, colid):
106  column = gtk.TreeViewColumn(descr, gtk.CellRendererText(), text=colid)
107  treeview.append_column(column)
108 
109  add_column("Interface", self.COLUMN_INTERFACE)
110 
111  add_column("Tx Packets", self.COLUMN_TX_PACKETS)
112  add_column("Tx Bytes", self.COLUMN_TX_BYTES)
113  add_column("Tx pkt/1s", self.COLUMN_TX_PACKET_RATE)
114  add_column("Tx bit/1s", self.COLUMN_TX_BIT_RATE)
115 
116  add_column("Rx Packets", self.COLUMN_RX_PACKETS)
117  add_column("Rx Bytes", self.COLUMN_RX_BYTES)
118  add_column("Rx pkt/1s", self.COLUMN_RX_PACKET_RATE)
119  add_column("Rx bit/1s", self.COLUMN_RX_BIT_RATE)
120 
121  self.visualizer.add_information_window(self)
122  self.win.show()
123 
124  def _response_cb(self, win, response):
125  self.win.destroy()
126  self.visualizer.remove_information_window(self)
127 
128  def update(self):
129  node = ns.network.NodeList.GetNode(self.node_index)
130  stats_list = self.statistics_collector.get_interface_statistics(self.node_index)
131  self.table_model.clear()
132  for iface, stats in enumerate(stats_list):
133  tree_iter = self.table_model.append()
134  netdevice = node.GetDevice(iface)
135  interface_name = ns.core.Names.FindName(netdevice)
136  if not interface_name:
137  interface_name = "(interface %i)" % iface
138  self.table_model.set(tree_iter,
139  self.COLUMN_INTERFACE, interface_name,
140 
141  self.COLUMN_TX_PACKETS, str(stats.txPackets),
142  self.COLUMN_TX_BYTES, str(stats.txBytes),
143  self.COLUMN_TX_PACKET_RATE, str(stats.txPacketRate),
144  self.COLUMN_TX_BIT_RATE, str(stats.txBitRate),
145 
146  self.COLUMN_RX_PACKETS, str(stats.rxPackets),
147  self.COLUMN_RX_BYTES, str(stats.rxBytes),
148  self.COLUMN_RX_PACKET_RATE, str(stats.rxPacketRate),
149  self.COLUMN_RX_BIT_RATE, str(stats.rxBitRate)
150  )
151 
152 
153 def populate_node_menu(viz, node, menu, statistics_collector):
154 
155  menu_item = gtk.MenuItem("Show Interface Statistics")
156  menu_item.show()
157 
158  def _show_it(dummy_menu_item):
159  ShowInterfaceStatistics(viz, node.node_index, statistics_collector)
160 
161  menu_item.connect("activate", _show_it)
162  menu.add(menu_item)
163 
164 
165 def register(viz):
166  statistics_collector = StatisticsCollector(viz)
167  viz.connect("populate-node-menu", populate_node_menu, statistics_collector)
168  viz.connect("simulation-periodic-update", statistics_collector.simulation_periodic_update)