网络质量IP获取脚本

 

 

安装python3,并安装所需插件

 yum -y install epel-release ; yum install -y python36 python36-devel; curl https://bootstrap.pypa.io/get-pip.py |python3.6

vi ~/.pip/pip.conf
[global] 
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
[install]
trusted-host = https://pypi.tuna.tsinghua.edu.cn

 

[root@localhost]# more requirements.txt
retrying==1.3.3
IPy==1.0
lxml==4.3.4
pycurl==7.43.0.3

ps:安装可能会出现如下错误:

安装:yum install  curl-devel gcc -y

2,无法引入pycurl

 

 

 解决:

 pip3 uninstall pycurl ; export PYCURL_SSL_LIBRARY=nss ; pip3 install --ignore-installed pycurl

备注:如果uninstall无法移除,则手动移除
mv /usr/local/python3/lib/python3.6/site-packages/pycurl* /home

日志插件脚本: common.py

import logging
import logging.handlers


class LogHandler(object):
    FILE_NAME = None
    def __init__(self, name):
        self.handler = logging.handlers.RotatingFileHandler('/tmp/idc_ping_monitor.log' , maxBytes = 1024*1024 , backupCount = 5)
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(message)s')
        self.handler.setFormatter(formatter)
        self.logger = logging.getLogger(name)
        self.logger.addHandler(self.handler)

    def __call__(self , func , *args , **kwargs):
        if func.__name__ == 'info' :
            self.logger.setLevel(logging.INFO)
            log_record = func(*args , **kwargs)
            self.logger.info(log_record)
            self.logger.removeHandler(self.handler)

  

IP获取脚本:getip.py

#-*- coding:utf-8 -*-
import pycurl
from lxml import etree
from io import BytesIO
import collections
import json
import IPy
import os
import datetime
from retrying import retry
import multiprocessing
from common import LogHandler


def infoInit():
    province_info = collections.defaultdict()

    province_info["beijing"] = {"name" : "北京" , "abbr" : "北京" , "url" : "http://ip.yqie.com/cn/beijing/"}
    province_info["tianjin"] = {"name" : "天津" , "abbr" : "天津" , "url" : "http://ip.yqie.com/cn/tianjin/"}
    province_info["hebei"] = {"name" : "石家庄" , "abbr" : "河北" , "url" : "http://ip.yqie.com/cn/hebei/shijiazhuang/"}
    province_info["neimenggu"] = {"name" : "呼和浩特" , "abbr" : "内蒙" , "url" : "http://ip.yqie.com/cn/neimenggu/huhehaote/"}
    province_info["liaoning"] = {"name" : "沈阳" , "abbr" : "辽宁" , "url" : "http://ip.yqie.com/cn/liaoning/shenyang/"}
    province_info["heilongjiang"] = {"name" : "海尔滨" , "abbr" : "黑龙江" , "url" : "http://ip.yqie.com/cn/heilongjiang/haerbin/"}
    province_info["jilin"] = {"name" : "长春" , "abbr" : "吉林" , "url" : "http://ip.yqie.com/cn/jilin/changchun/"}
    province_info["shandong"] = {"name" : "济南" , "abbr" : "山东" , "url" : "http://ip.yqie.com/cn/shandong/jinan/"}
    province_info["shanxi"] = {"name" : "太原" , "abbr" : "山西" , "url" : "http://ip.yqie.com/cn/sanxi/taiyuan/"}
    province_info["shanghai"] = {"name" : "上海" , "abbr" : "上海" , "url" : "http://ip.yqie.com/cn/shanghai/"}
    province_info["zhejiang"] = {"name" : "杭州" , "abbr" : "浙江" , "url" : "http://ip.yqie.com/cn/zhejiang/hangzhou/"}
    province_info["jiangsu"] = {"name" : "南京" , "abbr" : "江苏" , "url" : "http://ip.yqie.com/cn/jiangsu/nanjing/"}
    province_info["anhui"] = {"name" : "合肥" , "abbr" : "安徽" , "url" : "http://ip.yqie.com/cn/anhui/hefei/"}
    province_info["jiangxi"] = {"name" : "南昌" , "abbr" : "江西" , "url" : "http://ip.yqie.com/cn/jiangxi/nanchang/"}
    province_info["fujian"] = {"name" : "福州" , "abbr" : "福建" , "url" : "http://ip.yqie.com/cn/fujian/fuzhou/"}
    province_info["henan"] = {"name" : "郑州" , "abbr" : "河南" , "url" : "http://ip.yqie.com/cn/henan/zhengzhou/"}
    province_info["hubei"] = {"name" : "武汉" , "abbr" : "湖北" , "url" : "http://ip.yqie.com/cn/hubei/wuhan/"}
    province_info["hunan"] = {"name" : "长沙" , "abbr" : "湖南" , "url" : "http://ip.yqie.com/cn/hunan/changsha/"}
    province_info["guangdong"] = {"name" : "广州" , "abbr" : "广东" , "url" : "http://ip.yqie.com/cn/guangdong/guangzhou/"}
    province_info["guangxi"] = {"name" : "南宁" , "abbr" : "广西" , "url" : "http://ip.yqie.com/cn/guangxi/nanning/"}
    province_info["dongguan"] = {"name" : "东莞" , "abbr" : "广东" , "url" : "http://ip.yqie.com/cn/guangdong/dongguan/"}
    province_info["hainan"] = {"name" : "海口" , "abbr" : "海南" , "url" : "http://ip.yqie.com/cn/hainan/haikou/"}
    province_info["sichuan"] = {"name" : "成都" , "abbr" : "四川" , "url" : "http://ip.yqie.com/cn/sichuan/chengdu/"}
    province_info["chongqing"] = {"name" : "重庆" , "abbr" : "重庆" , "url" : "http://ip.yqie.com/cn/chongqing/"}
    province_info["guizhou"] = {"name" : "贵阳" , "abbr" : "贵州" , "url" : "http://ip.yqie.com/cn/guizhou/guiyang/"}
    province_info["yunnan"] = {"name" : "昆明" , "abbr" : "云南" , "url" : "http://ip.yqie.com/cn/yunnan/kunming/"}
    province_info["xizang"] = {"name" : "拉萨" , "abbr" : "西藏" , "url" : "http://ip.yqie.com/cn/xizang/lasa/"}
    province_info["shaanxi"] = {"name" : "西安" , "abbr" : "陕西" , "url" : "http://ip.yqie.com/cn/shanxi/xian/"}
    province_info["ningxia"] = {"name" : "银川" , "abbr" : "宁夏" , "url" : "http://ip.yqie.com/cn/ningxia/yinchuan/"}
    province_info["gansu"] = {"name" : "兰州" , "abbr" : "甘肃" , "url" : "http://ip.yqie.com/cn/gansu/lanzhou/"}
    province_info["qinghai"] = {"name" : "西宁" , "abbr" : "青海" , "url" : "http://ip.yqie.com/cn/qinghai/xining/"}
    province_info["xinjiang"] = {"name" : "乌鲁木齐" , "abbr" : "新疆" , "url" : "http://ip.yqie.com/cn/xinjiang/wulumuqi/"}

    return province_info



class GetInfo(object):
    
    def __init__(self):
        pass

    @retry(stop_max_attempt_number=1)
    def getHtml(self , province , url , province_info_shared):
        ####
        @LogHandler('getHtml()')
        def info():
            return '[info] get ' + url
        buffer = BytesIO()
        c = pycurl.Curl()
        c.setopt(c.URL, url)
        c.setopt(c.WRITEDATA, buffer)
        try:
            c.perform()
        except Exception as e :
            @LogHandler('getHtml()')
            def error():
                return 'retry ' + url + e
            raise e
        c.close()
        body = buffer.getvalue()
        if province in ('shaanxi' , 'qinghai') :
            body = body[:-2]
            
        html = etree.HTML(body.decode("utf-8","ignore"))
        piece_list = html.xpath('//table[@id="GridViewOrder"]/tr')
        
        results = self.parse(piece_list)
        province_info_temp = province_info_shared[province]
        province_info_temp.update({"cmcc" : results.get('cmcc')[0]})
        province_info_temp.update({"telcom" : results.get('telcom')[0]})
        province_info_temp.update({"unicom" : results.get('unicom')[0]})
        province_info_shared[province] = province_info_temp
        
    def parse(self , piece_list):
        results = collections.defaultdict()
        results['cmcc'] = []
        results['telcom'] = []
        results['unicom'] = []
    
        ip_addr = None
        location = None
    
        for piece in  piece_list:
            ip_start = piece.xpath('./*')[1].text
            ip_end = piece.xpath('./*')[2].text
            location = piece.xpath('./*')[3].text
    
            if results['cmcc'] and results['telcom'] and results['unicom']:
                break
    
            if not results['cmcc'] and '移动' in location :
                (exit_code , ip_addr) = self.pingCheck(ip_start , ip_end)
                if exit_code :
                    results['cmcc'].append(ip_addr)
                    results['cmcc'].append(location)
                    continue
            if not results['telcom'] and '电信' in location :
                (exit_code , ip_addr) = self.pingCheck(ip_start , ip_end)
                if exit_code :
                    results['telcom'].append(ip_addr)
                    results['telcom'].append(location)
                    continue
            if not results['unicom'] and '联通' in location :
                (exit_code , ip_addr) = self.pingCheck(ip_start , ip_end)
                if exit_code :
                    results['unicom'].append(ip_addr)
                    results['unicom'].append(location)
                    continue
            
        return results

    def pingCheck(self , ip_start , ip_end):
        ip_start_int = IPy.IP(ip_start).int()
        ip_end_int = IPy.IP(ip_end).int()
        for_count = 0
        ip_addr = None
        if ip_end_int - ip_start_int > 10 :
            for_count = 10
        else :
            for_count = ip_end_int - ip_start_int + 1
        for count in range(for_count):
            ip_addr = IPy.IP(ip_start_int + count).strNormal(0)
            os_code = not os.system("ping -c 1 -w 1 "+ ip_addr +" > /dev/null") if True else False
            if os_code :
                break
        return (os_code , ip_addr)
        
    
    def getIP(self , province_info):
        pool = multiprocessing.Pool(processes = 4)
        province_info_shared = multiprocessing.Manager().dict()
        province_info_shared.update(province_info)

        for province in province_info_shared:
            pool.apply_async(self.getHtml , (province , province_info_shared.get(province).get("url") , province_info_shared), error_callback=self.throw_error) 
        pool.close()
        pool.join()  

        return province_info_shared

    def throw_error(self , e):
        raise e


def syncToSmokingFile(province_info):
    data = collections.defaultdict()
    data['cmcc'] = "+ CMCC \n" \
                   "menu = 移动 \n" \
                   "title = 移动 \n" \
                   "\n"
    data['unicom'] = "+ UNICOM \n" \
                   "menu = 联通 \n" \
                   "title = 联通 \n" \
                   "\n"
    data['telcom'] = "+ TELCOM \n" \
                   "menu = 电信 \n" \
                   "title = 电信 \n" \
                   "\n"

    for province in province_info:
        if province_info[province].get('cmcc'):
            record = "++ " + province_info[province].get('abbr') + "\n" \
                     "menu = " + province_info[province].get('name') + "\n" \
                     "host = " + province_info[province].get('cmcc') + "\n" \
                     "\n"
            data['cmcc'] += record
        if province_info[province].get('unicom'):
            record = "++ " + province_info[province].get('abbr') + "\n" \
                     "menu = " + province_info[province].get('name') + "\n" \
                     "host = " + province_info[province].get('unicom') + "\n" \
                     "\n"
            data['unicom'] += record
        if province_info[province].get('telcom'):
            record = "++ " + province_info[province].get('abbr') + "\n" \
                     "menu = " + province_info[province].get('name') + "\n" \
                     "host = " + province_info[province].get('telcom') + "\n" \
                     "\n"
            data['telcom'] += record

    for isp in data:
        with open("location/"+isp , "w") as f:
            f.writelines(data[isp])

def getDate():
    return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")


if __name__ == '__main__':
    print(getDate() , 'begin...')
    getinfo = GetInfo()
    province_info = getinfo.getIP(infoInit())
    syncToSmokingFile(province_info)
    print(getDate() , 'end...')

.

拼音问题:

vi collection_to_prometheus.py

#coding:utf-8
import requests
import rrdtool
import os
from common import LogHandler


paras = {
    'province_map' : {
        'anhui'         : '安徽' ,
        'beijing'       : '北京' ,
        'chongqing'     : '重庆' ,
        'fujian'        : '福建' ,
        'gansu'         : '甘肃' ,
        'guangdong'     : '广东' ,
        'guangxi'       : '广西' ,
        'guizhou'       : '贵州' ,
        'hainan'        : '海南' ,
        'hebei'         : '河北' ,
        'heilongjiang'  : '黑龙江' ,
        'henan'         : '河南' ,
        'hubei'         : '湖北' ,
        'hunan'         : '湖南' ,
        'jiangsu'       : '江苏' ,
        'jiangxi'       : '江西' ,
        'jilin'         : '吉林' ,
        'liaoning'      : '辽宁' ,
        'neimenggu'     : '内蒙古' ,
        'ningxia'       : '宁夏' ,
        'qinghai'       : '青海' ,
        'shaanxi'       : '陕西' ,
        'shandong'      : '山东' ,
        'shanghai'      : '上海' ,
        'shanxi'        : '山西' ,
        'shenzhen'      : '深圳' ,
        'sichuan'       : '四川' ,
        'tianjin'       : '天津' ,
        'xinjiang'      : '新疆' ,
        'xizang'        : '西藏' ,
        'yunnan'        : '云南' ,
        'zhejiang'      : '浙江'
    } , 
    'prometheus_gateway' : 'http://192.168.56.101:9091' , 
    'data_dir' : '/usr/local/smokeping/data'
}

def pushMetrics(instance , ISP , key , value):
    headers = {'X-Requested-With': 'Python requests', 'Content-type': 'text/xml'}
    pushgateway = '%s/metrics/job/smokeping-collected-%s/instance/%s' % (paras['prometheus_gateway'] , ISP , instance)
    metrics = 'smokeping_%s{instance=\"%s\" , ISP=\"%s\" , IDC=\"%s\" , alias=\"%s\"} %d' % (key , instance , ISP , 'SH' , paras['province_map'].get(instance) , value)
    request_code = requests.post(pushgateway , data='{0}\n'.format(metrics).encode('utf-8') , headers=headers)
    @LogHandler(pushgateway)
    def info():
        return metrics + ' - ' + str(request_code.status_code)

def getMonitorData(rrd_file): 
    rrd_info = rrdtool.info(rrd_file)
    last_update = rrd_info['last_update'] - 60
    args = '-s ' + str(last_update) 
    results = rrdtool.fetch(rrd_file , 'AVERAGE' , args )
    lost_package_num = int(results[2][0][1])
    average_rrt = 0 if not results[2][0][2] else results[2][0][2] * 1000
    return lost_package_num , round(average_rrt , 4)


if __name__ == '__main__':
    ISP_list = ['TELCOM' , 'CMCC' , 'UNICOM' , 'TENCENT']
    for ISP in ISP_list:
        rrd_data_dir = os.path.join(paras['data_dir'] , ISP)
        for filename in os.listdir(rrd_data_dir):
            (instance , postfix) = os.path.splitext(filename)
            if postfix == '.rrd' :
                (lost_package_num , rrt) = getMonitorData(os.path.join(paras['data_dir'] , ISP , filename))
                pushMetrics(instance , ISP , 'rrt' , rrt)
                pushMetrics(instance , ISP , 'lost_package_num' , lost_package_num)

 

  

posted @ 2020-03-27 22:58  邓聪聪  阅读(296)  评论(0编辑  收藏  举报