summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQiuwen Lu <[email protected]>2018-03-10 14:44:03 +0800
committerQiuwen Lu <[email protected]>2018-03-10 14:44:03 +0800
commit12ea152a6d74da8353c4c04cae8cabc41f2ff443 (patch)
tree827e7a878c5cbeaaaa633ded5f9d7288fcb2f1d3
parent2116050524d2cba9fac89844564645770d60e12f (diff)
增加pagstat功能,对接A3项目。v4.2.37-20180310
-rw-r--r--tools/CMakeLists.txt1
-rw-r--r--tools/pagstat/CMakeLists.txt14
-rw-r--r--tools/pagstat/pagstat.py205
3 files changed, 220 insertions, 0 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index a14bd13..d1a3867 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -1,6 +1,7 @@
add_subdirectory(tcpdump)
add_subdirectory(monit_device)
add_subdirectory(monit_stream)
+add_subdirectory(pagstat)
add_subdirectory(dlogreader)
add_subdirectory(devbind)
add_subdirectory(systemd) \ No newline at end of file
diff --git a/tools/pagstat/CMakeLists.txt b/tools/pagstat/CMakeLists.txt
new file mode 100644
index 0000000..1d1d72f
--- /dev/null
+++ b/tools/pagstat/CMakeLists.txt
@@ -0,0 +1,14 @@
+
+set(PI_DIST_PATH ${CMAKE_CURRENT_BINARY_DIR}/pi_dist)
+set(PI_BUILD_PATH ${CMAKE_CURRENT_BINARY_DIR}/pi_build)
+set(PI_SPEC_PATH ${CMAKE_CURRENT_BINARY_DIR}/pi_spec)
+
+add_custom_command(OUTPUT ${PI_DIST_PATH}/pagstat
+ COMMAND pyinstaller -F -y --distpath ${PI_DIST_PATH}
+ --workpath ${PI_BUILD_PATH}
+ --specpath ${PI_SPEC_PATH}
+ --noconsole ${CMAKE_CURRENT_SOURCE_DIR}/pagstat.py
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/pagstat.py)
+
+add_custom_target(pagstat ALL DEPENDS ${PI_DIST_PATH}/pagstat)
+install(PROGRAMS ${PI_DIST_PATH}/pagstat DESTINATION bin COMPONENT Program) \ No newline at end of file
diff --git a/tools/pagstat/pagstat.py b/tools/pagstat/pagstat.py
new file mode 100644
index 0000000..d0f2875
--- /dev/null
+++ b/tools/pagstat/pagstat.py
@@ -0,0 +1,205 @@
+#!/usr/bin/env python2
+
+import argparse
+import json
+import prettytable
+import time
+import sys
+import signal
+import os
+import telegraf
+import socket
+
+TBPS = (1 * 1000 * 1000 * 1000 * 1000)
+GBPS = (1 * 1000 * 1000 * 1000)
+MBPS = (1 * 1000 * 1000)
+KBPS = (1 * 1000)
+
+G_JSON_PATH = '/var/run/mrzcpd/mrmonit.daemon'
+
+TITLE_VECTOR = ['PhyRXFrame','PhyRXBits','PhyRXMissed','PhyRXError',
+ 'PhyRXNoBUF','PhyTXFrame','PhyTXBits','PhyTXError',
+ 'UsrRXDrops', 'UsrTXDrops']
+
+TITLE_MAP = { 'rx_total_packets' : 'ipackets',
+ 'rx_total_bytes' : 'ibytes',
+ 'rx_packets' : 'ipackets',
+ 'rx_bytes' : 'ibytes',
+ 'tx_packets' : 'opackets',
+ 'tx_bytes' : 'obytes',
+ 'port_dropped' : 'imissed',
+ 'rx_dropped' : '',
+ 'rx_errors' : 'ierrors'
+ }
+
+def locate_vector_by_symbol(vector, symbol):
+ return [s for s in vector if s['symbol'] == symbol]
+
+def list_all_phydev(json_fp):
+ return [ s['symbol'] for s in json_fp['device']]
+
+def phydev_value_read(json_fp, str_device, str_item):
+ phydevs = locate_vector_by_symbol(json_fp['device'], str_device)
+ return phydevs[0]['stats']['accumulative'][str_item]
+
+def phydev_speed_read(json_fp, str_device, str_item):
+ phydevs = locate_vector_by_symbol(json_fp['device'], str_device)
+ return phydevs[0]['stats']['speed'][str_item]
+
+def trans_to_human_readable(value):
+ if value > TBPS:
+ return value * 1.0 / TBPS, 'T'
+ if value > GBPS:
+ return value * 1.0 / GBPS, 'G'
+ if value > MBPS:
+ return value * 1.0 / MBPS, 'M'
+ if value > KBPS:
+ return value * 1.0 / KBPS, 'K'
+
+ return value * 1.0, ' '
+
+def dump_human_table(json_fp, devsym, is_human_number = 0):
+
+ print("%16s %16s %16s %16s %16s %16s %16s %16s %16s %16s %16s" %
+ ("rx_total_packets", "rx_total_bytes", "rx_packets", "rx_bytes",
+ "tx_packets","tx_bytes", "port_dropped", "rx_dropped",
+ "rx_errors", "ring_tx_packets", "ring_tx_bytes"))
+
+ print("%16u %16u %16u %16u %16u %16u %16u %16u %16u %16u %16u" % (
+ phydev_value_read(json_fp, devsym, 'ipackets'), phydev_value_read(json_fp, devsym, 'ibytes') / 8,
+ phydev_value_read(json_fp, devsym, 'ipackets'), phydev_value_read(json_fp, devsym, 'ibytes') / 8,
+ phydev_value_read(json_fp, devsym, 'opackets'), phydev_value_read(json_fp, devsym, 'obytes') / 8,
+ phydev_value_read(json_fp, devsym, 'imissed'), 0, 0, 0, 0))
+
+# APM sendlog format
+def dump_apm_sendlog(json_fp, telegraf_client, devsym):
+
+ __metric_dict_speed = {}
+ __metric_dict_value = {}
+ __tags = {'device' : devsym }
+
+ for item in TITLE_VECTOR:
+ value = phydev_speed_read(json_fp, devsym, TITLE_MAP[item])
+ __metric_dict_speed[item] = value
+
+ for item in TITLE_VECTOR:
+ value = phydev_value_read(json_fp, devsym, TITLE_MAP[item])
+ __metric_dict_value[item] = value
+
+ telegraf_client.metric('mr4_device_rxtx_speed', __metric_dict_speed, tags = __tags)
+ telegraf_client.metric('mr4_device_rxtx_value', __metric_dict_value, tags = __tags)
+ return
+
+def setup_argv_parser(phydev_list):
+
+ parser = argparse.ArgumentParser(description='Marsio ZeroCopy Tools -- Monitor NIC devices',
+ version = 'Marsio ZeroCopy Tools Suite 4.1')
+
+ parser.add_argument('-t', '--time', help = 'interval, seconds to wait between updates',
+ type=int, default = 1)
+ parser.add_argument('-l', '--loop', help = 'print loop, exit when recv a signal',
+ action='store_true', default = 0)
+ parser.add_argument('-H', '--human-readable', help = 'print value in human readable format',
+ action = 'store_true', default = 0)
+ parser.add_argument('-i', '--interface', help = 'the name of network interface',
+ action = 'append', choices=phydev_list)
+ parser.add_argument('--clear-screen', help = 'clear screen at start of loop',
+ action='store_true', default = 0)
+
+ # APM sendlog options
+ parser.add_argument('--sendlog-apm', help = 'send log to apm server',
+ action='store_true', default = 0)
+ parser.add_argument('--sendlog-apm-cfg', help = 'send log configure file',
+ type=str, default = '/opt/mrzcpd/etc/mrsendlog.conf')
+
+ return parser.parse_args()
+
+def phydev_json_load():
+ with open(G_JSON_PATH) as json_fp:
+ return json.load(json_fp)
+
+
+def sendlog_hostname(test_hostname, test_port):
+ import socket
+
+ hostname = socket.gethostname()
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ try:
+ s.connect((test_hostname, int(test_port)))
+ local_ip_addr = s.getsockname()[0]
+ except:
+ local_ip_addr = '127.0.0.1'
+ finally:
+ s.close()
+
+ return hostname, local_ip_addr
+
+def sendlog_apm_init(r_option):
+ import ConfigParser
+ import urllib
+
+ config = ConfigParser.ConfigParser()
+ config.read(r_option.sendlog_apm_cfg)
+
+ apm_server_url = config.get('sendlog_apm', 'apm_device_server')
+ url_proto, rest = urllib.splittype(apm_server_url)
+ url_host, rest = urllib.splithost(rest)
+ url_host, url_port = urllib.splitport(url_host)
+
+ hostname, local_ip_addr = sendlog_hostname(url_host, url_port)
+ sendlog_tags = {'host' : hostname, 'local_ip_addr': local_ip_addr}
+
+ if url_proto == 'udp':
+ telegraf_client = telegraf.TelegrafClient(host = url_host,
+ port = int(url_port), tags = sendlog_tags)
+ elif url_proto == 'http':
+ telegraf_client = telegraf.HttpClient(host = url_host,
+ port = int(url_port), tags = sendlog_tags)
+
+ return telegraf_client
+
+def sigint_handler(handler, frame):
+ sys.exit(0)
+
+def main():
+ signal.signal(signal.SIGINT, sigint_handler)
+
+ try:
+ json_fp = phydev_json_load()
+ phydev_list = list_all_phydev(json_fp)
+ r_option = setup_argv_parser(phydev_list)
+
+ if r_option.sendlog_apm:
+ telegraf_client = sendlog_apm_init(r_option)
+
+ phydev_user_list = phydev_list if r_option.interface is None else r_option.interface
+
+ while True:
+ if r_option.clear_screen:
+ os.system('clear')
+
+ json_fp = phydev_json_load()
+
+ if r_option.sendlog_apm:
+ for devsym in phydev_user_list:
+ dump_apm_sendlog(json_fp, telegraf_client, devsym)
+ else:
+ for devsym in phydev_user_list:
+ dump_human_table(json_fp, devsym, r_option.human_readable)
+
+ if not r_option.loop:
+ break
+
+ time.sleep(r_option.time)
+
+ except KeyboardInterrupt:
+ pass
+ except ValueError as err:
+ print(("%s, perhaps mrzcpd program is not running.") % str(err))
+ except IOError as err:
+ print(("%s, perhaps mrzcpd program is not running.") % str(err))
+
+ return 0
+
+if __name__ == '__main__':
+ main() \ No newline at end of file