Python+企业微信 实现简易自动化运维

一、编程使我快乐

人生苦短,我学Python

快60岁的潘石屹大佬都开始学起了Python编程,出于好奇,我也准备尝试一下,不向大佬看齐,怎么拉近与大佬的距离呢?

体验之后发现,Python的确是适合上了年纪的人学习,可以称得上办公室里的装逼神器!

装逼的场景主要有以下:

1、办公自动化,可帮助领导实现excel、word、pdf、邮件等的自动化处理;

2、网络爬虫,轻松帮助HR的美女同事爬取各人才网站的招聘与人才信息;

喜欢炒股的大咖们,可以轻松爬取各类股票指标,还可以定制适合自己的交易系统;

3、语音、图像识别,可在OA系统中实现简单语音交互功能,如:小P,帮我申请9点钟101会议室;

4、做简单的数据分析和可视化图表;

5、用几行简单的代码可以操控物联网设备等等;

但是在下面这些领域装逼须谨慎,没点基本功可能会装不下去:

人工智能、深度学习、路径规划算法等等

二、实际应用:IT自动化运维

好吧,言归正传,接下来我们探讨下用Python帮我们解决一些实际的问题:IT系统的自动化运维。

众所周知,随着IT技术的进步以及业务需求的快速增长,每家企业内部都有许多的信息系统,如ERP、MES、OA、CRM等等,而每套系统又由许许多多的功能模块组成,如服务器、存储、数据库、备份系统、网络等等,这些节点也从几十台到成百上千台不等,并且各个系统之间又是紧密联系、互相影响,所以任何一个功能模块出现问题,都可能会影响到企业信息系统的正常运行,同样也会影响企业的高效运作,甚至会影响企业可持续发展。

但是,如何能保证各系统安全、稳定、高效地运行呢?

在好莱坞大片中,那些力挽狂澜的英雄往往受到大家的崇拜;当企业出现重大事故时,带领团队公关的领导也同样会受到表彰。

然而,我们都知道,其实真正厉害的人,是那些能够提前预判问题、解决问题并且避免事故发生的人。不战而胜,才是最大的胜利!

千里之堤,溃于蚁穴;见微知著,格物致知。有道之士,贵以近知远,以今知古,以所见知所不见。故审堂下之阴,而知日月之行,阴阳之变;见瓶水之冰,而知天下之寒,鱼鳖之藏矣。

我们每位IT人,都是爱岗敬业的掘蚁人,是默默无闻的幕后英雄!尊敬的老板们,您要是不幸看到这篇文章,请为IT人加点工资好吗?

想多了,扯远了,还是好好学习、天天向上吧,哈哈!

接下来以SAP ERP系统运维为例, 利用Python+企业微信来建立一个简易的自动运维系统:

1、目标:确保SAP系统安全、稳定、高效运行;

2、SAP系统组成:服务器、存储、核心网络、SAP应用、oracle数据库、备份与恢复系统等;

3、问题:子系统多、专业性强、操作风险大(Linux下一不小心就干掉了整个数据库)、运维工作量大、事后诸葛亮(故障发生了运维人员才知道);

4、分析:系统运维的精髓就是要及时感知硬件及系统的故障,并且设置关键参数的阈值,一旦超出阈值就发送预警信息,及时处理并且避免系统事故发生;

5、解决:用程序来自动检测以下内容,异常信息发送至企业微信,这样可省下80%以上的时间,敏捷、高效同时还能避免人为误操作。

所有设备网络通讯情况;

服务器的CPU、内存、文件系统使用情况;

硬件故障检查;

数据库表空间、Cache命中率、报警日志等;

三、程序实现

1、企业微信消息发送接口程序

# -*- encoding:utf-8 -*-
import json
import sys
import urllib
import urllib.request
from urllib import request, parse

# 企业微信后台上设置的参数
CORPID = ''  # CorpID 企业ID
CORPSECRET = ''  # Secret 应用密钥
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"}


def getToken(corpid, corpsecret):
    """功能获取access_token corpid:企业ID corpsecret:应用密钥 """
    url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s' % (corpid, corpsecret)
    req = urllib.request.Request(url, headers=headers)
    results = json.loads(urllib.request.urlopen(req).read())
    # print(results)
    return results['access_token']


def sendmsg(access_token, content , touser):
    """功能:发送消息 """
    url = "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" + access_token
    """ touser 成员 @all 就是所有 toparty 部门ID @all 就是所有 msgtype 文本类型 agentid 企业应用ID content 内容 safe 是否保密 0是不保密 """
    values = {

        "touser": touser,
        "toparty": '2',
        "msgtype": "text",
        "agentid": 1000010,  # 企业微信应用
        "text": {

            "content": content
        },
        "safe": "0"
    }
    send_data = json.dumps(values).encode()
    send_request = urllib.request.Request(url, send_data, headers=headers)
    response = json.loads(urllib.request.urlopen(send_request).read())
    if response['errcode'] == 0:
        print('发送消息成功')

def sentmessage(cont,touser):
    access_token = getToken(CORPID, CORPSECRET)
    sendmsg(access_token, cont ,touser)

2、设备通讯情况检测

     策略:每1-10分钟检测一次

# -*- encoding:utf-8 -*-

import os
import wework
import time

# 此程序用于检测各服务器的通讯情况

def ping(sip):
    #发送一个ping包,如果响应时间>1ms,则需要注意,返回值为1
    res=os.system('ping -n 1 -w 1 %s >nul'%sip)
    time.sleep(3)
    #3秒后再发送一个包,如果仍返回1,则发出警报,这样可以减少误判
    res2=os.system('ping -n 1 -w 1 %s >nul'%sip)
    if res & res2 == 0:
        print('server %s normal'%sip)
    else:
        print('warning:server %s ' % sip)
        sentpingerror(sip)


def sentpingerror(ip):
    str='warning:服务器%s通信中断!'%ip
    #发送微信报警信息
    wework.sentmessage(str)

if __name__ == '__main__':
    while True:
        #设备IP,许多设备可将IP保存在文件、数据库中,进行循环遍历
        DeviceIP=['10.1.1.1','10.1.1.2','10.1.1.3']
        for dip in DeviceIP:    
            ping(DeviceIP)
        #每一轮检测完后,等待1分钟   
        time.sleep(60)  

2、服务器CPU、内存、IO、文件系统使用情况

      策略:每1小时检测一次

这里我们使用SSH的方式来连接客户端系统,SSH连接也有很多种方式,我们直接调用paramiko模块就好,简易连接代码如下:


    #基于ssh命令用于连接远程服务器作操作:远程执行命令
    import paramiko
    #创建一个ssh对象
    client=paramiko.SSHClient()
    #如果之前没有连接过的ip,会出现 Are you sure you want to continue connecting (yes/no)? yes
    #自动选择yes
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    try:
        #连接服务器
        client.connect(hostname=host,
                       port=port,
                       username=user,
                       password=passwd)
    except :
        print('连接%s失败'%host)
    finally:
        #关闭连接
        client.close()

监控服务器CPU使用率:

stdin, stdout, stderr = ssh.exec_command("top -b -n1 | sed -n '3p'|awk '{print $5}'")
cpu_usage = 100 - float(stdout.read().decode().split('%')[0])
# 当cpu使用率超过90时,发送警告到企业微信
if ( cpu_usage > 90 ):
    str='warning:服务器%sCPU使用率过高!'%ip
    wework.sentmessage(str)
    
    

 监控磁盘文件系统使用率:

linux下查看文件系统命令,过滤掉标题行、光驱等

df -TPh | grep -vE '^Filesystem|tmpfs|cdrom|sr' | awk '{ print $6 $1 }'

程序如下: 

#文件系统使用率
stdin, stdout, stderr = ssh.exec_command("df -TPh | grep -vE '^Filesystem|tmpfs|cdrom|sr' | awk '{ print $6 $1 }'")
filesystems= stdout.readlines()
#遍历文件系统,如果有超过85%,则发出警告到企业微信
flag = False  #当任一文件系统>85%时 flag 为True
for fs in filesystems:
    fsuse = fs.split('%')[0]
    #fsname = fs.split('%')[1]   #文件系统名
    if ( fsuse > 85 ):
        flag = True
if flag:
    str='warning:服务器%s有文件系统使用率过高!'%ip
    wework.sentmessage(str)
    

监控服务器内存使用率: 

#物理内存容量
stdin, stdout, stderr = ssh.exec_command("free -m | sed -n '2p'|awk '{print $2}'")
totalmem = float(stdout.read().decode())
#已使用的内存
stdin, stdout, stderr = ssh.exec_command("free -m | sed -n '2p'|awk '{print $3}'")
usedmem = float(stdout.read().decode())
#内存使用率
use = round(float(freemem) / float(totalmem), 2)
#假如内存使用超过90%,则发送警告到企业微信
if ( use > 0.9 ):
    str='warning:服务器%s内存使用率过高!'%ip
    wework.sentmessage(str)

3、数据库表空间、cache命中率(以oracle为例)

因为没有找到管理oracle数据库的python模块,我们可以采用paramiko调用SSH方法连接到数据库服务器,然后再执行sql脚本来获取oracle的信息;

注:paramiko是用root用户来ssh到客户机的,但是执行sql脚本要先以oracle用户登录,所以可以在root用户下用 su - oracle -c '命令' 来登录和执行sql脚本:

su - oraprd -c 'echo @/oracle/python.sql | sqlplus / as sysdba'

接下来写sql脚本,简单地写了两条,大家根据各自需求补充:

脚本中用了“|”号做为分隔符,便于程序中抓取数据。

"表空间利用率
SELECT a.tablespace_name,
  --total "表空间大小",
  -- free "表空间剩余大小",
  -- (total - free) "表空间使用大小",
  total        / (1024 * 1024 * 1024) "表空间大小(G)",
  (total       - free) / (1024 * 1024 * 1024) "表空间使用大小(G)",
  free         / (1024 * 1024 * 1024) "表空间剩余大小(G)",
  '|'||ROUND((total - free) / total, 4) * 100||'|' "使用率 %,|符号用作分隔,便于程序抓取"
FROM
  (SELECT tablespace_name,
    SUM(bytes) free
  FROM dba_free_space
  GROUP BY tablespace_name
  ) a,
  (SELECT tablespace_name,
    SUM(bytes) total
  FROM dba_data_files
  GROUP BY tablespace_name
  ) b
WHERE a.tablespace_name = b.tablespace_name;

"缓存的命中率应保持在95%以上,否则应进行调优
SELECT SUM(pins) "Executions",SUM(reloads) "CacheMisses while
 Executing",ROUND((SUM(pins)/(SUM(reloads)+SUM(pins)))*100,2)
 AS "HitRatio Ratio, %" FROM V$LIBRARYCACHE;

Python程序实现: 

#物理内存容量
stdin, stdout, stderr = ssh.exec_command("su - oracle -c 'echo @/oracle/test.sql | sqlplus / as sysdba'")

#表空间使用率,如果超过90%则发出警告
flag = False
usestr = stdout.readlines() 
for str in usestr:
    if (len(str.split('|')) > 1:
        use = float(str.split('|')[1])
        if use > 90:
            flag = True
if ( flag ):
    str='warning:服务器%s表空间使用率过高!'%ip
    wework.sentmessage(str)

 四、小结

Python优雅、明确和简单,对于初学者学来说,入门容易,同时由于Python具有丰富强大的第三方库,原来非常复杂的业务场景,现在用Python也许几行代码就能解决,并且随着了解的深入,也可以编写出非常复杂的程序。当然,Python也并非十全十美,它也有着许多被人诟病的点,比如性能,比如程序无法加密等等,但是这些,并不能影响Python的优秀,也非常值得编程大家学习。

   

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值