#代码1,把明文密码123456屏蔽掉,先运行代码1以便生成config.ini文件,供代码2连接Mysql
python
from cryptography.fernet import Fernet
import configparser
key = Fernet.generate_key()
cipher = Fernet(key)
password = '123456'
encripted_password= cipher.encrypt(password.encode()).decode()
config = configparser.ConfigParser()
config['Database'] = {
'DB_HOST': '127.0.0.1',
'DB_USER': 'root',
'DB_PASSWORD': encripted_password,
'DB_PORT': '3306',
'DB_NAME': 'DB1',
'ENCRYPTION_KEY': key.decode()
}
with open('config.ini', 'w') as f:
config.write(f)
#代码2
"""
2.1、定义日志文件,每个函数中需要记录的信息会写入到日志文件中
2.2、定义巡检后发现一切正常的通知邮件模板
2.2、定义巡检后发现异常的报警邮件模板
2.3、定义巡检中需要巡检哪个程序,如果这个程序存在且只有1个进程,那么正常
2.4、定义巡检中需要巡检哪些数据库表,如果数据库表有最新1分钟的数据,那么正常
2.5、定义主函数,如果2.3和2.4都正常,则调用2.1,否则调用2.2
"""
python
import psutil
import logging
import pymysql
import smtplib
import time
import configparser
from email.mime.text import MIMEText
from email.header import Header
from datetime import datetime, timedelta
from cryptography.fernet import Fernet
from pymysql import Connection
#日志文件
logging.basicConfig(filename='log.log',level=logging.INFO,format='%(asctime)s - %(funcName)s - %(message)s')
logger = logging.getLogger(__name__)
#定义正常通知邮件,巡检后一切正常,发送通知邮件信息
def send_normal_email():
# 邮件服务器
smtp_server = "Myemailserver.net" # SMTP服务器
port = 25 # SMTP服务器端口号
sender = "Emailsender@mycomp.com.cn" # 发件邮箱,可以定义一个不存在的发件人
receiver = "Emailgroup@mycomp.com.cn" # 收件邮箱
# 邮件内容
subject = f"Mysystem Python程序自动巡检报告"
body = f"""
<html>
<body>
<h3>Hi Team,</h3>
<p><b>Mysystem Python程序今天自动启动成功并且运行正常,无需人工干预。</b></p>
<p><b>巡检时间:</b> {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
<p><b>Mysystem Python程序自动启动成功并且运行正常的成立条件:</p>
<ol>
<li><b>XX服务器上的Python程序进程Mysystem存在</b></li>
<li><b>Mysql数据库服务器上有最新数据</b></li>
</ol>
</body>
</html>
"""
# 构建邮件
msg = MIMEText(body, 'html', 'utf-8')
msg['From'] = Header(sender)
msg['To'] = Header(receiver)
msg['Subject'] = Header(subject, 'utf-8')
try:
# 发送邮件
with smtplib.SMTP(smtp_server, port) as server:
server.sendmail(sender, receiver, msg.as_string())
except Exception as e:
logger.error(f"邮件发送失败: {e}")
#定义异常报警邮件,巡检后发现异常,发送报警邮件信息
def send_abnormal_email():
# 邮件服务器
smtp_server = "Myemailserver.net" # SMTP服务器
port = 25 # SMTP服务器端口号
sender = "Emailsender@mycomp.com.cn" # 发件邮箱,可以定义一个不存在的发件人
receiver = "Emailgroup@mycomp.com.cn" # 收件邮箱
# 邮件内容
subject = f"Mysystem Python程序自动巡检报告"
body = f"""
<html>
<body>
<h3>Hi Team,</h3>
<p><b><span style="color: red;">Mysystem Python程序今天自动启动异常没有运行正常,请人工干预。</span></b></p>
<p><b>巡检时间:</b> {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}<p>
<p><b>人工干预方式:</b>
<ol>
<li><b>检查XX服务器上的任务管理器进程列表中Mysystem进程</b></li>
<ul style="list-style-type: disc;">
<li>若进程存在:手工结束该进程,再双击"C:\\Mysystem\\Mysystem.exe"启动Mysystem Python程序。</li>
<li>若进程不存在:双击"C:\\Mysystem\\Mysystem.exe"启动Mysystem Python程序。</li>
</ul>
</ol>
</p>
</body>
</html>
"""
# 构建邮件
msg = MIMEText(body, 'html', 'utf-8')
msg['From'] = Header(sender)
msg['To'] = Header(receiver)
msg['Subject'] = Header(subject, 'utf-8')
try:
# 发送邮件
with smtplib.SMTP(smtp_server, port) as server:
server.sendmail(sender, receiver, msg.as_string())
except Exception as e:
logger.error(f"邮件发送失败: {e}")
# 检查Mysystem.exe进程数量是否在1个之间
def check_process_exists(process_name, min_count=1, max_count=1):
count = 0
for proc in psutil.process_iter(['name']):
try:
if proc.info['name'] == process_name:
count += 1
except (psutil.NoSuchProcess, psutil.AccessDenied):
continue
logger.info(f"进程 {process_name} 当前数量: {count}, 要求范围: [{min_count}, {max_count}]")
return min_count <= count <= max_count
#检查Mysystem报表数据源Mysql数据库中表tablename1是否有最近1分钟的数据
def check_recent_data_exists():
try:
dbconfig = configparser.ConfigParser()
dbconfig.read('config.ini')
key = dbconfig.get('Database', 'ENCRYPTION_KEY').encode()
cipher = Fernet(key)
encrypted_password = dbconfig.get('Database', 'DB_PASSWORD')
decrypted_password = cipher.decrypt(encrypted_password.encode()).decode()
with Connection(
host=dbconfig.get('Database', 'DB_HOST'),
user=dbconfig.get('Database', 'DB_USER'),
password=decrypted_password,
port=int(dbconfig.get('Database', 'DB_PORT')),
database=dbconfig.get('Database', 'DB_NAME')
) as conn:
with conn.cursor() as cursor:
one_minute_ago = (datetime.now() - timedelta(minutes=1)).strftime('%Y-%m-%d %H:%M:%S')
sql = "SELECT COUNT(*) as count FROM tablename1 WHERE etltime >= %s"
cursor.execute(sql, (one_minute_ago,))
result = cursor.fetchone()
recent_count = result[0]
conn.commit()
logger.info(f"数据库表tablename1最近1分钟内的数据条数: {recent_count}")
return recent_count > 0
except Exception as e:
logger.error(f"数据库检查失败: {e}")
return False
def main():
"""主函数:执行检查并发送相应的通知邮件"""
logger.info("开始执行系统状态检查...")
# 检查程序进程
process_check = check_process_exists("Mysystem.exe")
# 检查数据库数据
db_check = check_recent_data_exists()
# 根据检查结果发送相应的邮件
if process_check and db_check:
logger.info("系统状态正常,发送正常通知邮件")
send_normal_email()
else:
logger.warning("系统状态异常,发送异常告警邮件")
send_abnormal_email()
logger.info("系统状态检查完成...\n")
if __name__ == "__main__":
main()