每次测试要连接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中文了,那定时脚本也会出问题
0 8-20/2,8 * * * /usr/local/bin/python3 /Test-Tools/monitor.py >> /Test-Tools/test.log 2>&1