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