mirror of https://gitee.com/anolis/sysom.git
171 lines
5.0 KiB
Python
Executable File
171 lines
5.0 KiB
Python
Executable File
#!/usr/bin/python3
|
||
# coding=utf-8
|
||
import sys
|
||
import json
|
||
|
||
ALL_DROP_REASONS = {
|
||
# hardware
|
||
'sent_errs': '硬件发包出错',
|
||
'sent_drop': '内核发包出错',
|
||
'sent_fifo': '硬件发包出错, fifo缓冲区不足',
|
||
'sent_carrier': '硬件发包出错, 出现冲突',
|
||
'sent_colls': '硬件发包出错, 出现冲突',
|
||
'recv_errs': '硬件收包出错, 可能是包解析出错',
|
||
'recv_drop': '硬件收包出错, 可能是内存不足或错包',
|
||
'recv_fifo': '硬件收包出错, fifo缓冲区不足, 可能是流量过大',
|
||
'recv_frame': '硬件收包出错, 包帧错误',
|
||
# netstat
|
||
'TcpExt::TCPOFODrop': 'tcp协议内存不足',
|
||
'TcpExt::TCPOFOMerge': '该报文是乱序报文,且该乱序报文携带的数据已经在乱序队列里了',
|
||
'TcpExt::DelayedACKLost': '收到的 TCP 数据之前已经收到(可能发生虚假重传)',
|
||
'TcpExt::TCPRcvQDrop': 'tcp协议内存不足',
|
||
'TcpExt::TCPZeroWindowDrop': 'tcp接收窗口不足',
|
||
'TcpExt::OfoPruned': '该报文是从tcp乱序队列中删除的',
|
||
'TcpExt::PAWSEstabRejected': 'PAWS 检查失败',
|
||
'TcpExt::PAWSEstab': 'PAWS 检查失败',
|
||
'TcpExt::TCPACKSkippedSeq': 'tcp报文携带的序号不对',
|
||
'TcpExt::TCPSYNChallenge': 'tcp处于established状态,但是收到的报文携带有syn标记',
|
||
'TcpExt::InCsumErrors': '报文checksum值不对',
|
||
# snmp
|
||
}
|
||
|
||
HARDWARE_DROP_KEY = ['sent_errs', 'sent_fifo', 'sent_colls',
|
||
'sent_carrier', 'recv_errs', 'recv_drop', 'recv_fifo', 'recv_frame']
|
||
|
||
TCP_DROP = 0
|
||
UDP_DROP = 0
|
||
ICMP_DROP = 0
|
||
HARDWARE_DROP = 0
|
||
|
||
DROP_REASONS = {}
|
||
|
||
|
||
def delta_map(pre, now):
|
||
delta = {}
|
||
for k, v in pre.items():
|
||
delta[k] = now[k] - v
|
||
return delta
|
||
|
||
|
||
def protocol_string(proto):
|
||
global TCP_DROP
|
||
global UDP_DROP
|
||
global ICMP_DROP
|
||
if proto == 1:
|
||
ICMP_DROP += 1
|
||
return "icmp"
|
||
elif proto == 6:
|
||
TCP_DROP += 1
|
||
return "tcp"
|
||
elif proto == 17:
|
||
UDP_DROP += 1
|
||
return "udp"
|
||
else:
|
||
return ""
|
||
|
||
|
||
def compute_hardware_drop(res):
|
||
global HARDWARE_DROP
|
||
devs = res[2]['dev']
|
||
for name, value in devs.items():
|
||
if name in res[-1]['dev']:
|
||
value2 = res[-1]['dev'][name]
|
||
dev = delta_map(value, value2)
|
||
for k, v in dev.items():
|
||
if v > 0 and k in HARDWARE_DROP_KEY:
|
||
HARDWARE_DROP += v
|
||
|
||
|
||
def infer_drop_reason(res):
|
||
global ALL_DROP_REASONS
|
||
global DROP_REASONS
|
||
|
||
netstat = delta_map(res[0]['netstat'], res[-3]['netstat'])
|
||
snmp = delta_map(res[1]['snmp'], res[-2]['snmp'])
|
||
|
||
for k, v in netstat.items():
|
||
if v > 0 and k in ALL_DROP_REASONS:
|
||
DROP_REASONS[ALL_DROP_REASONS[k]] = 1
|
||
|
||
for k, v in snmp.items():
|
||
if v > 0 and k in ALL_DROP_REASONS:
|
||
DROP_REASONS[ALL_DROP_REASONS[k]] = 1
|
||
|
||
devs = res[2]['dev']
|
||
for name, value in devs.items():
|
||
if name in res[-1]['dev']:
|
||
value2 = res[-1]['dev'][name]
|
||
dev = delta_map(value, value2)
|
||
for k, v in dev.items():
|
||
if v > 0 and k in HARDWARE_DROP_KEY:
|
||
DROP_REASONS[ALL_DROP_REASONS[k]] = 1
|
||
|
||
|
||
def packetdrop_result(res):
|
||
global TCP_DROP
|
||
global UDP_DROP
|
||
global ICMP_DROP
|
||
global HARDWARE_DROP
|
||
global DROP_REASONS
|
||
|
||
postprocess_result = {
|
||
"code": 0,
|
||
"err_msg": "",
|
||
"result": {},
|
||
# "rawresult": res,
|
||
}
|
||
|
||
if len(res) < 6:
|
||
postprocess_result["code"] = 1
|
||
postprocess_result["err_msg"] = "Failed to parse output"
|
||
print(json.dumps(postprocess_result, ensure_ascii=False))
|
||
return
|
||
|
||
compute_hardware_drop(res)
|
||
packetdrop = {}
|
||
packetdrop['packetDropList'] = {'data': []}
|
||
droplist = []
|
||
index = 0
|
||
for drop in res[3: -3]:
|
||
pstr = protocol_string(drop['proto'])
|
||
if len(pstr) == 0:
|
||
continue
|
||
index += 1
|
||
droplist.append({'key': index, 'protocol': pstr, 'local': drop['src'],
|
||
'remote': drop['dst'], 'dropPoint': drop['symbol']})
|
||
|
||
packetdrop['packetDropList']['data'] = droplist
|
||
|
||
packetdrop["packetDropSummary"] = {"data": {}}
|
||
packetdrop["packetDropSummary"]["data"] = [
|
||
{"key": "tcp", "value": TCP_DROP},
|
||
{"key": "udp", "value": UDP_DROP},
|
||
{"key": "icmp", "value": ICMP_DROP},
|
||
{"key": "hardware", "value": HARDWARE_DROP},
|
||
]
|
||
|
||
infer_drop_reason(res)
|
||
packetdrop['packetDropAnalysis'] = {"data": {}}
|
||
packetdrop["packetDropAnalysis"]['data'] = [
|
||
{'key': index, 'dropReason': reason}
|
||
for index, (reason, _) in enumerate(DROP_REASONS.items())
|
||
]
|
||
|
||
postprocess_result['result'] = packetdrop
|
||
print(json.dumps(postprocess_result, ensure_ascii=False))
|
||
|
||
|
||
def extract_params():
|
||
path, res, task_id = sys.argv[1], [], sys.argv[2]
|
||
with open(path, 'r') as tmp:
|
||
for line in tmp.readlines():
|
||
obj = json.loads(line)
|
||
res.append(obj)
|
||
|
||
return res, task_id
|
||
|
||
|
||
if __name__ == "__main__":
|
||
res, _ = extract_params()
|
||
packetdrop_result(res)
|