405 lines
14 KiB
Python
405 lines
14 KiB
Python
#coding=utf-8
|
|
import argparse
|
|
import json
|
|
import prettytable
|
|
import time
|
|
import sys
|
|
import signal
|
|
import os
|
|
import telegraf
|
|
import socket
|
|
from get_traffic_by_psutil import *
|
|
from get_traffic_by_marsio import *
|
|
from common_telegraf import *
|
|
from common_logger import *
|
|
from common_args import *
|
|
from common_logger import *
|
|
from common_get_tags import *
|
|
|
|
TBPS = (1 * 1000 * 1000 * 1000 * 1000)
|
|
GBPS = (1 * 1000 * 1000 * 1000)
|
|
MBPS = (1 * 1000 * 1000)
|
|
KBPS = (1 * 1000)
|
|
|
|
INTERFACE_JSON_PATH = '/opt/tsg/etc/tsg_chassis_interface.json'
|
|
G_JSON_PATH = '/var/run/mrzcpd/mrmonit.daemon'
|
|
G_APP_JSON_PATH = '/var/run/mrzcpd/mrmonit.app.%s'
|
|
|
|
#TITLE_VECTOR_RX = ['RxOnline', 'RxDeliver', 'RxMissed', 'RxBits']
|
|
#TITLE_VECTOR_TX = ['TxOnline', 'TxDeliver', 'TxMissed', 'TxBits']
|
|
#TITLE_VECTOR_FTX = ['FTXOnline', 'FTXDeliver', 'FTXMissed', 'FTXBits']
|
|
|
|
TITLE_VECTOR_RX = ['RxPkts', 'RxBits', 'RxDrops']
|
|
TITLE_VECTOR_TX = ['TxPkts', 'TxBits', 'TxDrops']
|
|
TITLE_VECTOR_FTX = ['FTxPkts', 'FTxBits', 'FTxDrops']
|
|
|
|
TITLE_APP_STAT = ['PKTRx', 'PKTTx', 'MbufAlloc', 'MbufFree', 'MbufInUse']
|
|
|
|
TITLE_APP_MAP = {
|
|
'PKTRx' : 'packet_recv_count',
|
|
'PKTTx' : 'packet_send_count',
|
|
'MbufAlloc' : 'mbuf_alloc_count',
|
|
'MbufFree' : 'mbuf_free_count',
|
|
'MbufInUse' : 'mbuf_in_use_count'
|
|
}
|
|
|
|
TITLE_MAP = { 'RxOnline' : 'rx_on_line',
|
|
'RxPkts' : 'rx_deliver',
|
|
'RxDrops' : 'rx_missed',
|
|
'RxBits' : 'rx_total_len',
|
|
'TxOnline' : 'tx_on_line',
|
|
'TxPkts' : 'tx_deliver',
|
|
'TxDrops' : 'tx_missed',
|
|
'TxBits' : 'tx_total_len',
|
|
'FTXOnline' : 'ftx_on_line',
|
|
'FTxPkts' : 'ftx_deliver',
|
|
'FTxDrops' : 'ftx_missed',
|
|
'FTxBits' : 'ftx_total_len'
|
|
}
|
|
# ##################################add by lijia for tsg oam
|
|
TITLE_VECTOR = ['RxPkts', 'RxBits', 'RxDrops', 'TxPkts', 'TxBits', 'TxDrops']
|
|
udp_sock_fd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
telegraf_ip = '127.0.0.1'
|
|
telegraf_port = 8126
|
|
# ##################################add by lijia for tsg oam
|
|
|
|
def locate_vector_by_symbol(vector, symbol):
|
|
return [s for s in vector if s['symbol'] == symbol]
|
|
|
|
def list_all_vdev(json_fp):
|
|
return [ s['symbol'] for s in json_fp['raw']]
|
|
|
|
def vdev_value_read(json_fp, str_device, str_item):
|
|
phydevs = locate_vector_by_symbol(json_fp['raw'], str_device)
|
|
return phydevs[0]['stats']['accumulative'][str_item]
|
|
|
|
def vdev_speed_read(json_fp, str_device, str_item):
|
|
phydevs = locate_vector_by_symbol(json_fp['raw'], str_device)
|
|
return phydevs[0]['stats']['speed'][str_item]
|
|
|
|
def vdev_streams_read(json_fp, str_device):
|
|
phydevs = locate_vector_by_symbol(json_fp['raw'], str_device)
|
|
return phydevs[0]['rxstreams'], phydevs[0]['txstreams']
|
|
|
|
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 vec_trans_to_human_readable(vec):
|
|
r_vector = []
|
|
for value in vec:
|
|
h_value, h_value_unit = trans_to_human_readable(value)
|
|
r_vector.append('%7.2f%c' % (h_value, h_value_unit))
|
|
|
|
return r_vector
|
|
|
|
def dump_one_device(json_fp, devsym, title_vector_rx, title_vector_tx, speed):
|
|
|
|
__rd_function = vdev_value_read if speed == 0 else vdev_speed_read
|
|
|
|
ValueListSum = [0] * len(title_vector_rx + title_vector_tx)
|
|
nr_rxstream, nr_txstream = vdev_streams_read(json_fp, devsym)
|
|
|
|
for stream_id in range(max(nr_rxstream, nr_txstream)):
|
|
ValueList = []
|
|
|
|
for item in title_vector_rx:
|
|
value = __rd_function(json_fp, devsym, TITLE_MAP[item])[stream_id] \
|
|
if stream_id < nr_rxstream else 0
|
|
ValueList.append(value)
|
|
|
|
for item in title_vector_tx:
|
|
value = __rd_function(json_fp, devsym, TITLE_MAP[item])[stream_id] \
|
|
if stream_id < nr_txstream else 0
|
|
ValueList.append(value)
|
|
|
|
for i,v in enumerate(ValueList):
|
|
ValueListSum[i] += v
|
|
|
|
return ValueListSum
|
|
|
|
def dump_summary_table(json_fp, appsym, devsym, title_vector_rx, title_vector_tx,
|
|
is_human_number = 0, speed = 1):
|
|
|
|
print('\nTime: %s, App: %s' % (time.strftime('%c'), appsym))
|
|
table_phydev = prettytable.PrettyTable([' '] + title_vector_rx + title_vector_tx,
|
|
vertical_char=' ',horizontal_char = '-', junction_char=' ')
|
|
|
|
for item in[' '] + title_vector_rx + title_vector_tx:
|
|
table_phydev.align[item] = 'r'
|
|
|
|
ValueListTotal = [0] * len(title_vector_rx + title_vector_tx)
|
|
|
|
for dev in devsym:
|
|
ValueListSum = dump_one_device(json_fp, dev, title_vector_rx, title_vector_tx, speed)
|
|
|
|
for i,v in enumerate(ValueListSum):
|
|
ValueListTotal[i] += v
|
|
|
|
if is_human_number:
|
|
table_phydev.add_row([dev] + vec_trans_to_human_readable(ValueListSum))
|
|
else:
|
|
table_phydev.add_row([dev] + ValueListSum)
|
|
|
|
if is_human_number:
|
|
table_phydev.add_row(['Total'] + vec_trans_to_human_readable(ValueListTotal))
|
|
else:
|
|
table_phydev.add_row(['Total'] + ValueListTotal)
|
|
|
|
print(table_phydev)
|
|
|
|
|
|
|
|
def dump_human_table(json_fp, appsym, devsym, title_vector_rx, title_vector_tx,
|
|
is_human_number = 0, speed = 1):
|
|
print("##### into dump_human_table")
|
|
print('\nTime: %s, App: %s, Device: %s ' % (time.strftime('%c'), appsym, devsym))
|
|
|
|
table_phydev = prettytable.PrettyTable([' '] + title_vector_rx + title_vector_tx,
|
|
vertical_char=' ',horizontal_char = '-', junction_char=' ')
|
|
|
|
__rd_function = vdev_value_read if speed == 0 else vdev_speed_read
|
|
|
|
for item in[' '] + title_vector_rx + title_vector_tx:
|
|
table_phydev.align[item] = 'r'
|
|
|
|
ValueListSum = [0] * len(title_vector_rx + title_vector_tx)
|
|
nr_rxstream, nr_txstream = vdev_streams_read(json_fp, devsym)
|
|
|
|
for stream_id in range(max(nr_rxstream, nr_txstream)):
|
|
ValueList = []
|
|
|
|
for item in title_vector_rx:
|
|
value = __rd_function(json_fp, devsym, TITLE_MAP[item])[stream_id] \
|
|
if stream_id < nr_rxstream else 0
|
|
ValueList.append(value)
|
|
|
|
for item in title_vector_tx:
|
|
value = __rd_function(json_fp, devsym, TITLE_MAP[item])[stream_id] \
|
|
if stream_id < nr_txstream else 0
|
|
ValueList.append(value)
|
|
|
|
str_leader = ''
|
|
str_leader += 'RX[%d]' % stream_id if stream_id < nr_rxstream else ''
|
|
str_leader += 'TX[%d]' % stream_id if stream_id < nr_txstream else ''
|
|
|
|
if is_human_number:
|
|
table_phydev.add_row([str_leader] + vec_trans_to_human_readable(ValueList))
|
|
else:
|
|
table_phydev.add_row([str_leader] + ValueList)
|
|
|
|
for i,v in enumerate(ValueList):
|
|
ValueListSum[i] += v
|
|
|
|
if is_human_number:
|
|
table_phydev.add_row(['Total'] + vec_trans_to_human_readable(ValueListSum))
|
|
else:
|
|
table_phydev.add_row(['Total'] + ValueListSum)
|
|
|
|
print(table_phydev)
|
|
|
|
|
|
def dump_status_table(json_fp, appsym):
|
|
print("##### into dump_status_table")
|
|
json_fp_appstat = json_fp['appstat']
|
|
nr_stream = len(json_fp['appstat']['packet_recv_count'])
|
|
|
|
print('\nTime: %s, App: %s' % (time.strftime('%c'), appsym))
|
|
table_phydev = prettytable.PrettyTable(['TID'] + TITLE_APP_STAT,
|
|
vertical_char=' ',horizontal_char = '-', junction_char=' ')
|
|
|
|
for item in['TID'] + TITLE_APP_STAT:
|
|
table_phydev.align[item] = 'r'
|
|
|
|
ValueListSum = [0] * len(TITLE_APP_STAT)
|
|
|
|
for tid in range(nr_stream):
|
|
ValueList = []
|
|
for item in TITLE_APP_STAT:
|
|
value = json_fp_appstat[TITLE_APP_MAP[item]][tid]
|
|
ValueList.append(value)
|
|
|
|
table_phydev.add_row([tid] + ValueList)
|
|
for i,v in enumerate(ValueList):
|
|
ValueListSum[i] += v
|
|
|
|
table_phydev.add_row(['Total'] + ValueListSum)
|
|
print(table_phydev)
|
|
|
|
def dump_apm_sendlog(json_fp, telegraf_client, appsym, user_interface, title_vector_rx, title_vector_tx):
|
|
|
|
for dev in user_interface:
|
|
ValueListSumSpeed = dump_one_device(json_fp, dev, title_vector_rx, title_vector_tx, 1)
|
|
#ValueListSumValue = dump_one_device(json_fp, dev, title_vector_rx, title_vector_tx, 0)
|
|
|
|
sendlog_dict_speed = {}
|
|
#sendlog_dict_value = {}
|
|
sendlog_tag = {'appname': appsym, 'device': dev, 'node' : node_name}
|
|
|
|
for id, value in enumerate(title_vector_rx + title_vector_tx):
|
|
sendlog_dict_speed[value] = int(ValueListSumSpeed[id])
|
|
#sendlog_dict_value[value] = ValueListSumValue[id]
|
|
#print(sendlog_dict_speed)
|
|
telegraf_client.metric('app', sendlog_dict_speed, tags = sendlog_tag)
|
|
#telegraf_client.metric('app', sendlog_dict_value, tags = sendlog_tag)
|
|
|
|
return
|
|
|
|
|
|
def global_json_load():
|
|
with open(G_JSON_PATH) as json_fp:
|
|
return json.load(json_fp)
|
|
|
|
def app_json_load(appsym):
|
|
with open(G_APP_JSON_PATH % appsym) as json_fp:
|
|
return json.load(json_fp)
|
|
|
|
def app_symbol_load():
|
|
j_global = global_json_load()
|
|
return [s["symbol"] for s in j_global["app"] if s["registed"] == 1]
|
|
|
|
def sigint_handler(handler, frame):
|
|
sys.exit(0)
|
|
|
|
def check_vdev_options(json_fp, r_option):
|
|
|
|
if r_option.interface == None:
|
|
return
|
|
|
|
vdev_list = list_all_vdev(json_fp)
|
|
for devsym in r_option.interface:
|
|
if devsym not in vdev_list:
|
|
print("monit_stream: error: argument -i/--interface: invalid interface.")
|
|
sys.exit(1)
|
|
|
|
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 app_setup_argv_parser(applist):
|
|
|
|
parser = setup_common_args()
|
|
|
|
#add monit_stream custom args
|
|
parser.add_argument('app', metavar='APP', help = 'the name of slave application', nargs = '*',
|
|
default=applist)
|
|
parser.add_argument('-i', '--interface', help = 'the name of network interface',
|
|
action = 'append')
|
|
parser.add_argument('-m', '--metrics', help = 'group of metrics', choices=['rx','tx','ftx'],
|
|
default = ['rx','tx'])
|
|
parser.add_argument('--status', help = 'print application running status',
|
|
action='store_true', default = 0)
|
|
|
|
return parser.parse_args()
|
|
|
|
def get_and_send_app_traffic():
|
|
signal.signal(signal.SIGINT, sigint_handler)
|
|
|
|
# Check Parameters
|
|
try:
|
|
applist = app_symbol_load()
|
|
#print("##### %s" %(applist))
|
|
if len(applist) == 0:
|
|
print("monit_stream: error: no running application.")
|
|
sys.exit(1)
|
|
|
|
r_option = app_setup_argv_parser(applist)
|
|
|
|
#for appsym in r_option.app:
|
|
# __json_fp = app_json_load(appsym)
|
|
|
|
except IOError as err:
|
|
print("%s, program %s is not running." % (str(err), appsym))
|
|
sys.exit(1)
|
|
|
|
title_vector_rx = []
|
|
title_vector_tx = []
|
|
if 'rx' in r_option.metrics:
|
|
title_vector_rx.extend(TITLE_VECTOR_RX)
|
|
if 'tx' in r_option.metrics:
|
|
title_vector_tx.extend(TITLE_VECTOR_TX)
|
|
|
|
try:
|
|
while True:
|
|
for appsym in r_option.app:
|
|
if appsym.find('sapp') == -1:
|
|
#only interesting sapp traffic
|
|
continue
|
|
json_fp = app_json_load(appsym)
|
|
check_vdev_options(json_fp, r_option)
|
|
user_interface = r_option.interface if r_option.interface != None else list_all_vdev(json_fp)
|
|
|
|
if r_option.status:
|
|
dump_status_table(json_fp, appsym)
|
|
continue
|
|
|
|
dump_apm_sendlog(json_fp, telegraf_client, appsym, user_interface,
|
|
title_vector_rx, title_vector_tx)
|
|
|
|
if r_option.debug:
|
|
dump_summary_table(json_fp, appsym, user_interface, title_vector_rx, title_vector_tx,
|
|
0, 1)
|
|
|
|
#if not r_option.loop:
|
|
break
|
|
time.sleep(r_option.time)
|
|
|
|
except KeyboardInterrupt:
|
|
pass
|
|
except ValueError as err:
|
|
print(("%s, perhaps program is not running.") % str(err))
|
|
except IOError as err:
|
|
print(("%s, perhaps program is not running.") % str(err))
|
|
|
|
return 0
|
|
|
|
def get_local_node():
|
|
try:
|
|
with open(INTERFACE_JSON_PATH) as json_fp:
|
|
json_dict = json.load(json_fp)
|
|
return json_dict['local_chassis_node']
|
|
except IOError:
|
|
return ""
|
|
|
|
if __name__ == '__main__':
|
|
global node_name
|
|
global telegraf_client
|
|
global logger
|
|
|
|
comm_arg_parser = setup_common_args()
|
|
arg_options = comm_arg_parser.parse_args()
|
|
|
|
logger = logger_init(arg_options.log_level)
|
|
|
|
telegraf_server_ip = arg_options.telegraf_ip
|
|
telegraf_server_port = int(arg_options.telegraf_port)
|
|
|
|
telegraf_tags = tsg_get_tags()
|
|
if len(telegraf_tags) <= 0:
|
|
logger.info("not found telegraf tags.")
|
|
|
|
telegraf_client = telegraf_init(telegraf_server_ip, telegraf_server_port, telegraf_tags)
|
|
node_name = get_local_node()
|
|
|
|
get_and_send_app_traffic() |