Python+MacOS监控移动设备,发送钉钉定时任务

移动设备监控-发送钉钉通知

目的

每次测试要连接N台设备同时自动化,由于可能会出现中断情况,手动找起来太麻烦,尤其是假期的时候,出现特殊情况无法预知,特此增加了设备运行监控

说明

脚本主要是Python编写,移动设备50台,主控设备MacOS一台,设备管理使用Mysql

代码思路

使用mysql管理设备,主表存放设备的devicesID、设备编号、code
通过集线器将所有设备连接到主控机MacOS
批量执行设备运行自动化进程
通过运行的进程,找到进程的别名,例如:com.***sql这样
经实验运行完成和设备发生断电、以及程序异常的时候需要监控的进程会停止
导出设备的最近时间段的日志(太多了会很慢,导出一部分就好),截取需要的时间
使用正则进行拼接,例如:时间、设备ID、进程PID等
对时间进行差值计算,大于一定时间段,说明设备发生了异常,或者运行完成
把异常或完成的设备在数据库中进行标记,发生监控通知对应人员

监控脚本如下

    '''提取日志时间和pid'''
    Url = '这里是钉钉的token'
    HEADERS = {"Content-Type": "application/json ;charset=utf-8 "}
    log_path = "数据源地址"
    for logs in read_path(log_path):
        with open(logs,'r',encoding='utf-8') as file:
            file_content = file.readlines()
            if len(file_content)!=0:
                file_line_last = file_content[-1]
                target = file_line_last[:60]
                log_data = re.findall('\d{2}-\d{2} \d{1,2}:\d{1,2}:\d{1,2}',target) #正则提取日期
                pid = re.findall('\s\s\d{1,4}\s\s',target)  # 正则提取pid
                log_datas = ['2022-'+(i) for i in log_data]
                log_times = "".join(log_datas)
                pids = [str(j)for j in pid]
                pid_id = "".join(pids)
                d1=datetime.datetime.strptime(log_times,'%Y-%m-%d %H:%M:%S')#日志时间
                times = strftime("%Y-%m-%d %H:%M:%S", localtime())#当前时间
                d2 = datetime.datetime.strptime(times, '%Y-%m-%d %H:%M:%S')
                devices = re.findall('.*report/(.*?)-',logs)
                time.sleep(0.5)
                diff=(d2-d1).seconds
                print(diff)
                time.sleep(0.3)
                if diff > 300:
                    for devid in devices:
                        sql = 'UPDATE dev_table SET code = 2 WHERE devices="%s"'%devid
                        db.updateDb(sql)
                        print(sql)
                        msg='️\n监控报警:时间差%s秒,完蛋了吧运行出错了吧\n运行的设备pid:%s' \
                            '\ndevicesID:%s\n更新库中设备状态为异常,大哥快来处理\n️'%(diff,pid_id,devid)
                        String_textMsg = { "msgtype": "text",
                                           "text": {
                                               "content": msg
                                           },
                                           "at":{
                                               "atMobiles":['+86-176*****666'],
                                               #@指定人员
                                               "isAtAll":False
                                           }
                                           }
                        String_textMsgs = json.dumps(String_textMsg)
                        res = requests.post(Url, data=String_textMsgs, headers=HEADERS)
                        print(res.text)
    os.system('adb kill-server')#因为使用了多进程,会调起多个adb命令,这里对adb进行了一次性的关闭,每次跑完都会清除一次(subprocess.Popen,导致程序假死,可自行百度)

设备获取和日志导出

    def __init__(self):
        self.dev_ls = []
        self.dev_numb = []
        sql1 = 'SELECT devices FROM dev_table WHERE `code`!=0 AND devices is NOT NULL'
        re = db.selectDb(sql1)
        for i in re[1]:
            self.dev_ls.append(i[0])
            sql2 = 'SELECT devices,numbers FROM master_table where devices="%s" AND numbers is NOT NULL ' % (i[0])
            res = db.selectDb(sql2)
            self.dev_numb.append(res[1][0][1])

    # def cmd_log(self):
        '''导出logcat到本地'''
        for devid,j in zip(self.dev_ls,self.dev_numb):
            cmd ='adb -s %s logcat -d | grep 你要监控的进程 > ' \
                 '/Users/pro/report%s-%s-log.txt'%(devid,devid,j)
            res = subprocess.Popen(cmd,stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True,universal_newlines=True)
            time.sleep(0.2)
            res.kill()

遇到的问题

1、使用封装好的DingtalkChatbot库,Mac crontab 定时任务会调用失败
使用Mac自带定时任务,会出现调用send_mess中的send_text方法不成功
索性我就使用了requests库,对钉钉发送了一个post请求,解决了crontab调用Python找不到第三库的问题,有的人会说使用launchctl,抱歉个人能力有限同样遇到问题,果断放弃目的实现需求才是最重要的。

class DingTalk_Base:
    def __init__(self):
        '''初始化钉钉机器人'''
        self.__headers = {'Content-Type': 'application/json;charset=utf-8'}
        self.url = '钉钉token'

    def send_mess(self, message):
        webhook = self.url
        xd = DingtalkChatbot(webhook)
        at_mobiles = ['+86-176******6']
        # xd.send_text(msg=message, is_at_all=True)#发送所有人
        xd.send_text(msg=message,at_mobiles=at_mobiles)#发送对应人

2、crontab发送定时任务会出现 编码错误,例如print(‘我是小菜鸡’)
这时候会发生:UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 0-10
这种错误是print中使用了中文,我也查阅了各路文章的解决方法但是都行不通,最后使用变量的方式通过接口发送成功,如果代码中出现print中文了,那定时脚本也会出问题

crontab命令如下 早8-晚8,每隔2小时运行一次

0 8-20/2,8 * * * /usr/local/bin/python3 /Test-Tools/monitor.py >> /Test-Tools/test.log 2>&1

你可能感兴趣的:(学习心得,测试遇到的坑,python,macos,mysql)