This repository has been archived on 2025-09-14. You can view files and clone it, but cannot push or open issues or pull requests.
Files
lijia-tsg-oam/py_cmd/tsg_monit_device.py
2019-08-06 18:54:58 +08:00

339 lines
11 KiB
Python

#!/usr/bin/python3
#coding=utf-8
import argparse
import json
import prettytable
import time
import sys
import signal
import os
import telegraf
import socket
import logging
import logging.handlers
TBPS = (1 * 1000 * 1000 * 1000 * 1000)
GBPS = (1 * 1000 * 1000 * 1000)
MBPS = (1 * 1000 * 1000)
KBPS = (1 * 1000)
#G_JSON_PATH = './mrmonit.daemon'
G_JSON_PATH = '/var/run/mrzcpd/mrmonit.daemon'
TITLE_VECTOR = ['PhyRXFrame','PhyRXBits','PhyRXMissed','PhyRXError',
'PhyRXNoBUF','PhyTXFrame','PhyTXBits','PhyTXError',
'UsrRXDrops', 'UsrTXDrops']
TITLE_MAP = { 'PhyRXFrame' : 'ipackets',
'PhyRXBits' : 'ibytes',
'PhyRXMissed' : 'imissed',
'PhyRXError' : 'ierrors',
'PhyRXNoBUF' : 'rxnombuf',
'PhyTXFrame' : 'opackets',
'PhyTXBits' : 'obytes',
'PhyTXError' : 'oerrors',
'UsrRXDrops' : 'userrxdrop',
'UsrTXDrops' : 'usertxdrop'
}
g_debug_mode = 0
def debug_print(msg):
#print("###### in debug_print(), g_debug_mode=%d " %(g_debug_mode))
if g_debug_mode != 0:
print("##### %s" %(msg))
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('\nTime: %s, Physical device: %s' % (time.strftime('%c'), devsym))
table_phydev = prettytable.PrettyTable([' '] + TITLE_VECTOR,
vertical_char=' ',horizontal_char = '-', junction_char=' ')
ValueList = ['Accumulative']
SpeedList = ['Per Second']
table_phydev.align[' '] = 'r'
for item in TITLE_VECTOR:
table_phydev.align[item] = 'r'
for item in TITLE_VECTOR:
value = phydev_value_read(json_fp, devsym, TITLE_MAP[item])
if is_human_number:
h_value, h_value_unit = trans_to_human_readable(value)
ValueList.append('%7.2f%c' % (h_value, h_value_unit))
else:
ValueList.append(value)
for item in TITLE_VECTOR:
speed = phydev_speed_read(json_fp, devsym, TITLE_MAP[item])
if is_human_number:
h_speed, h_speed_unit = trans_to_human_readable(speed)
SpeedList.append('%7.2f%c' % (h_speed, h_speed_unit))
else:
SpeedList.append(speed)
# ##################################add by lijia for tsg oam
print(table_phydev)
line_prot_buf = "interface,device=%s,flow_type=inline " %(devsym)
for num in range(0,9):
#Accumulative
#tmp_str = "%s=%s," %(TITLE_VECTOR[num],ValueList[num+1])
# per second
tmp_str = "%s=%s," %(TITLE_VECTOR[num],SpeedList[num+1])
line_prot_buf += tmp_str
num += 1
#tmp_str = "%s=%s" %(TITLE_VECTOR[num],ValueList[num+1])
tmp_str = "%s=%s" %(TITLE_VECTOR[num],SpeedList[num+1])
line_prot_buf += tmp_str
logger.debug("##### sendto line_protocol: %s" %(line_prot_buf))
try:
# for python2.x
sock_ret = udp_sock_fd.sendto(line_prot_buf, (telegraf_ip, telegraf_port))
# for python3.x, str to bytes
#sock_ret = udp_sock_fd.sendto(line_prot_buf.encode(), (telegraf_ip, telegraf_port))
except socket.err:
logger.critical("##### sendto error!")
sys.exit(1)
logger.debug("##### udp_sock_fd.sendto ret=%d" %(sock_ret))
# ################################## add by lijia for tsg oam
table_phydev.add_row(ValueList)
table_phydev.add_row(SpeedList)
print(table_phydev)
# 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')
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')
############### add by lijia for OAM
parser.add_argument('-d', '--debug', help = 'debug mode',
action='store_true', default = 0)
parser.add_argument('--telegraf-ip', help = 'send log to telegraf ip address',
type=str, default = '192.168.200.5')
parser.add_argument('--telegraf-port', help = 'send log to telegraf port',
type=int, default = 8126)
############### add by lijia for OAM
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():
global g_debug_mode
signal.signal(signal.SIGINT, sigint_handler)
try:
json_fp = phydev_json_load()
phydev_list = list_all_phydev(json_fp)
print("##### phydev_list:%s" %(phydev_list))
r_option = setup_argv_parser(phydev_list)
if r_option.debug :
g_debug_mode = 1
debug_print("##### debug mode is on!")
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
debug_print("phydev_user_list:%s" %(phydev_user_list))
telegraf_ip = r_option.telegraf_ip
telegraf_port = r_option.telegraf_port
debug_print("telegraf_ip:%s, telegraf_port:%u" %(telegraf_ip, telegraf_port))
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
def logger_init():
global logger
logger = logging.getLogger("logger")
handler1 = logging.StreamHandler()
#handler2 = logging.FileHandler(filename="test.log")
logger.setLevel(logging.DEBUG)
handler1.setLevel(logging.DEBUG)
#handler2.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")
handler1.setFormatter(formatter)
#handler2.setFormatter(formatter)
print("logger level debug val: %d" %(logging.DEBUG))
print("logger level info val: %d" %(logging.INFO))
print("logger level warning val: %d" %(logging.WARNING))
print("logger level error val: %d" %(logging.ERROR))
print("logger level critical val: %d" %(logging.CRITICAL))
logger.addHandler(handler1)
#logger.addHandler(handler2)
logger.info("logger init succ!")
def socket_init():
global udp_sock_fd
global telegraf_ip
global telegraf_port
try:
udp_sock_fd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
except socket.error:
logger.critical("logger init succ!")
sys.exit(1)
#set default
telegraf_ip = '192.168.200.5'
telegraf_port = 8126
def init():
logger_init()
socket_init()
if __name__ == '__main__':
init()
main()