Environment(环境)

本项目为python编写的项目

  • python3.6+
    用到的库:

  • paramiko (linux ssh库)

  • smtplib (邮件库)

  • APScheduler (定时任务库)

项目目录结构

monitor-linux()

|--config     |--gol.py               (全局变量字典)     |--init_configs.py      (读取ini初始化配置)     |--linux_config.ini     (linux服务器配置文件)     |--mail_settings.ini    (邮箱设置配置文件)     |--time_config.ini      (cron定时设置配置文件) |--mail     |--send_mails.py        (发送邮件) |--monitor     |--monitor.py           (监控linux模块,连接linux服务器) |--utils     |--util.py              (工具类) |--run.py                   (程序入口) 

主要模块介绍

run .py (程序入口)

先从程序入口介绍!代码如下:

# coding = utf-8 """
@author: sy

@file: run.py

@time: 2018/9/23 18:11

@desc: 程序入口,定时任务

""" import sys, os

from config import gol

BASE_DIR = os.path.dirname((os.path.abspath(__file__)))
sys.path.append(BASE_DIR)

from monitor.monitor import Monitor
from mail.send_mails import SendMail
from config.init_configs import init_config, get_linux_config
from apscheduler.schedulers.blocking import BlockingScheduler


def auto_job():
    linux_dict = get_linux_config()
    content_list = []
    """ [(10.10.111.1,cd $(locate taskmngdomain1/nohuplogs) ; tail -50 *log*`date +%F`*),
         (10.10.111.2,cd $(locate taskmngdomain2/nohuplogs) ; tail -50 *log*`date +%F`*)]"""     cmd_list = gol.get_value('cmd_list')
    for ip in linux_dict:
        linux_info = linux_dict[ip].split(',')  # 根据ip获取user和pwd,通过逗号分隔成list(linux_info--> [user,pwd])         user = linux_info[0]
        pwd = linux_info[1]
        monitor = Monitor(ip, user, pwd)
        # cmd的获取,添加根据ini不同ip实现动态对应linux指令         for cmd_tuple in cmd_list:
            if cmd_tuple[0] == ip:
                cmd = cmd_tuple[1]  # 将指令赋予cmd                 break  # 若找到了,则不浪费循环资源直接跳出         content = f'当前服务器ip:{ip},日志内容:
' + monitor.link_server(cmd) + '

'         content_list.append(content)
    sendMail = SendMail()
    sendMail.send_mails(''.join(content_list))
    sendMail.mail_close()   #关闭连接 def main():
    init_config()  # 初始化配置     """ 基于quartz的定时任务调度器 """     scheduler = BlockingScheduler()
    """ FIELD_NAMES = ('year', 'month', 'day', 'week', 'day_of_week', 'hour', 'minute', 'second') 
        没用过quartz的同学去了解下CRON表达式~文档如下:
        https://apscheduler.readthedocs.io/en/stable/modules/triggers/cron.html#module-apscheduler.triggers.cron
    """     year = str(gol.get_value('year'or None)
    month = str(gol.get_value('month'or None)
    day = str(gol.get_value('day'or None)
    week = str(gol.get_value('week'or None)
    day_of_week = str(gol.get_value('day_of_week'or None)
    hour = str(gol.get_value('hour'or None)
    minute = str(gol.get_value('minute'or None)
    second = str(gol.get_value('second'or None)
    scheduler.add_job(auto_job, 'cron', year=year, month=month, day=day,
                      week=week, day_of_week=day_of_week, hour=hour, minute=minute, second=second, id='auto_job_id')
    try:
        print('程序开始!-------->Job running(Tips: Ctrl + c 终止程序)')
        scheduler.start()
    except (KeyboardInterrupt, SystemExit):
        print('退出程序!')
        scheduler.remove_job('auto_job_id') if __name__ == '__main__':
    main()
    # auto_job() 

这部分主要是程序入口,首先在main方法中对配置文件内容进行初始化加载,将各种变量参数加载到程序中,其次写了一个job方法,此方法中实现了程序逻辑主流程,从读取用户配置的相关linux服务器、邮箱以及linux命令信息,连接到服务,并将linux远程执行后得到的结果以邮件的形式发送。最后通过apscheduler第三方库来实现CRON的定时调用job功能…!

monitor .py  (监控linux模块,连接linux服务器)

# coding = utf-8 """
@author: sy

@file: monitor.py

@time: 2018/9/22 15:33

@desc: 远程连接linux ssh监控后台日志

""" import paramiko class Monitor(object):     def __init__(self, server_ip, user, pwd):         """ 初始化ssh客户端 """         try:
            client = paramiko.SSHClient()
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            self.client = client
            print('------------开始连接服务器(%s)-----------' % server_ip)
            self.client.connect(server_ip, 22, username=user, password=pwd, timeout=4)
            print('------------认证成功!.....-----------')
        except Exception:
            print(f'连接远程linux服务器(ip:{server_ip})发生异常!请检查用户名和密码是否正确!')

    def link_server(self, cmd):         """连接服务器发送命令"""         try:
            stdin, stdout, stderr = self.client.exec_command(cmd)
            content = stdout.read().decode('gbk')
            return content
        except Exception as e:
            print('link_server-->返回命令发生异常,内容:', e)
        finally:
            self.client.close() if __name__ == '__main__':
    pass 

此模块使用了第三库 paramiko .py,进行远程连接,将所配置的命令发给linux,随后将linux相应返回!

send_mails .py (发送邮件)

# coding = utf-8 """
@author: sy

@file: send_mails.py

@time: 2018/9/22 16:55

@desc: 发送邮件模块

""" import smtplib from email.header import Header from email.mime.text import MIMEText from config import gol class SendMail(object):     def __init__(self):         """ 初始化邮箱模块 """         try:
            self.mail_host = gol.get_value("mail_host")  # 邮箱服务器             self.mail_port = gol.get_value("mail_port")  # 邮箱服务端端口             self.mail_user = gol.get_value("mail_user")  # 邮箱用户名             self.mail_pwd = gol.get_value("mail_pwd")  # 邮箱密码             self.mail_receivers = gol.get_value("mail_receivers").split(',')  # 收件人,以逗号分隔成列表             smtp = smtplib.SMTP()
            smtp.connect(self.mail_host, self.mail_port)
            smtp.login(self.mail_user, self.mail_pwd)
            self.smtp = smtp
        except:
            print('发邮件---->初始化失败!请检查用户名和密码是否正确!')

    def send_mails(self, content):         """ 发送邮件 """         try:
            message = MIMEText(content, 'plain''utf-8')
            message['From'] = Header("巡检机器人小咪"'utf-8')
            message['To'] = Header("系统警告"'utf-8')
            subject = '各系统巡检信息'             message['Subject'] = Header(subject, 'utf-8')
            self.smtp.sendmail(self.mail_user, self.mail_receivers, message.as_string())
            print('发送邮件成功!')
        except Exception as e:
            print('发邮件---->失败!原因:', e)

    def mail_close(self):         """ 关闭邮箱资源 """         self.smtp.close() 

此模块使用python自带模块smtp实现发邮件的功能,比较简单,只需将相关配置文件读取进来即可!

程序使用方法

好了介绍完上面的三个主要模块,来说下如何使用:

|--config     |--linux_config.ini     (linux服务器配置文件)     |--mail_settings.ini    (邮箱设置配置文件)     |--time_config.ini      (cron定时设置配置文件) 

在这里,使用者可以配置自己所需要的相关信息
linux_config.ini:

# linux远程服务ip,多个服务器用,隔开,例如(10.10.111.1,10.10.111.2,....) [server-ip]
ip = 10.10.111.1,10.10.111.2,.... #对应用户名,密码,多个服务器用;隔开,例如(user1,pwd1;user2,pwd2;....) [server-login]
login_info = user1,pwd1;user2,pwd2;.... # 不同ip作为key值,不同命令作为value值 [cmd]
10.10.111.1 = cd $(locate taskmngdomain1/nohuplogs) ; tail -50 *log*`date +%F`*
10.10.111.2 = cd $(locate taskmngdomain2/nohuplogs) ; tail -50 *log*`date +%F`* 

mail_settings.ini:

# 邮箱服务端、端口 [mail-server] mail_host = smtp.xxxx.com mail_port = 25 # 邮箱客户端(发邮箱的人),用户名、密码 [mail-client] mail_user = [email protected] mail_pwd = xxxxx # 收邮件的人邮箱,多个用逗号隔开 [mail-receivers] mail_receivers = [email protected],xxxx@163.com 

time_config.ini:
此配置文件可以参考cron的写法!

;year (int|str) – 4-digit year ;month (int|str) – month (1-12)
;day (int|str) – day of the (1-31)
;week (int|str) – ISO week (1-53)
;day_of_week (int|str) – number or name of weekday (0-6 or mon,tue,wed,thu,fri,sat,sun)
;hour (int|str) – hour (0-23)
;minute (int|str) – minute (0-59)
;second (int|str) – second (0-59)
[cron] year = * month = * day = *
week = *
day_of_week = * hour = * minute = 0/1 second = 0
09-07 18:47