python發(fā)送xml格式socket心跳告警
需求
- 1役衡、行內,應用程序發(fā)送心跳,發(fā)送xml到socker.
- 2呢燥、通過ps獲取程序是否存在,判斷是否發(fā)送心跳.
- 3冒萄、使用xml.etree.ElementTree來格式化xml格式
實現
- 1充易、使用socket link來創(chuàng)建socket鏈接
- 2菇民、使用xml.etree.ElementTree來格式化xml格式
- 3禁筏、根據需要監(jiān)控process_name_list 列表來循環(huán) 判斷是否發(fā)送心跳
- 4持钉、根據發(fā)送socket返回信息判斷是否發(fā)送socket是否成功
- 5、記錄日志信息
代碼
#!/usr/bin/python3
"""
需求:
1篱昔、行內,應用程序發(fā)送心跳,發(fā)送xml到socker.
2每强、通過ps獲取程序是否存在,判斷是否發(fā)送心跳.
"""
import xml.etree.ElementTree as ET
import socket,os,time,logging
from logging.handlers import RotatingFileHandler
def build_xml_message(heartbeat_interval, name, SystemName, AlarmRes):
local_time1 = int(round(time.time() * 1000))
local_time2 = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
root = ET.Element("ALARMSTART")
name_element = ET.SubElement(root, "SystemName")
name_element.text = SystemName
age_element = ET.SubElement(root, "AlarmID")
age_element.text = str(local_time1)
city_element = ET.SubElement(root, "AlarmEquipment")
city_element.text = name
city_element = ET.SubElement(root, "AlarmRes")
city_element.text = AlarmRes
city_element = ET.SubElement(root, "EventTime")
city_element.text = local_time2
return ET.tostring(root, encoding="utf-8", method="xml").decode("utf-8")
def send_heartbeat(xml_message, server_address):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(10)
try:
# print(xml_message.encode("utf-8"))
sock.connect(server_address)
sock.sendall(xml_message.encode("utf-8"))
response = sock.recv(1024)
local_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
if "flag=true" in str(response):
log_info = str(local_time) + " info send info ok ,return info: " + str(response)
logger.debug(log_info)
# write_data_to_file_append(log_file_path, log_info)
else:
log_info = str(local_time) + " error send info fail ,return info: " + str(response)
logger.debug(log_info)
#write_data_to_file_app/end(log_file_path, log_info)
except Exception as e:
logger.error("Failed to send heartbeat to " + str(server_address) + " " + str(e))
finally:
sock.close()
def write_data_to_file_append(file_path, data):
with open(file_path, "a") as f:
f.write(data)
def is_process_running(ps_out,process_name):
# 遍歷所有進程,查找具有給定名稱的進程
for line in ps_out.splitlines():
if process_name in line:
return True
return False
if __name__ == "__main__":
#需要鏈接soket 服務端
server_address = ("localhost", 10000)
# log_file_path = "send_socket.log"
heartbeat_interval = 5
#需要監(jiān)控的程序名
process_name_list = ["nginx","mysqld","cdesk_nginx1"]
#xml名稱定義
SystemName = "ccc-test-001"
AlarmRes = "定制接口服務器"
##### logger #####
log_file = "./log/heratbeat.log"
shell = "mkdir -p " + log_file.split("heratbeat.log")[0]
os.popen(shell)
# 創(chuàng)建日志記錄器
logger = logging.getLogger("my_logger")
logger.setLevel(logging.DEBUG)
# 創(chuàng)建RotatingFileHandler對象
max_log_size = 100 * 1024 * 1024 # 100 MB
backup_count = 50
handler = RotatingFileHandler(log_file, maxBytes=max_log_size, backupCount=backup_count)
# 定義日志格式
formatter = logging.Formatter("%(asctime)s %(thread)d %(filename)s:%(lineno)d %(levelname)s %(message)s")
handler.setFormatter(formatter)
# 將處理程序添加到日志記錄器
logger.addHandler(handler)
while True:
#使用os.popen執(zhí)行ps命令州刽,獲取所有進程
ps_output = os.popen("ps aux").read()
# ps_output = os.popen("ps -e").read()
for process_name in process_name_list:
if is_process_running(ps_output,process_name):
xml_message = build_xml_message(heartbeat_interval, process_name, SystemName, AlarmRes)
print(xml_message)
logger.debug(process_name + " is running.")
send_heartbeat(xml_message, server_address)
else:
logger.error(process_name + " is not running.")
time.sleep(heartbeat_interval)
# 程序結束時關閉處理程序
logger.removeHandler(handler)
handler.close()
解決運行情況
2023-09-19 10:32:49,369 140176451651392 heratbeat.py:103 DEBUG nginx is running.
2023-09-19 10:32:49,370 140176451651392 heratbeat.py:45 DEBUG 2023-09-19 10:32:49 error send info fail ,return info: b'<ALARMSTART><SystemName>ccc-test-001</SystemName><AlarmID>1695090769369</AlarmID><AlarmEquipment>nginx</AlarmEquipment><AlarmRes>\xe5\xae\x9a\xe5\x88\xb6\xe6\x8e\xa5\xe5\x8f\xa3\xe6\x9c\x8d\xe5\x8a\xa1\xe5\x99\xa8</AlarmRes><EventTime>2023-09-19 10:32:49</EventTime></ALARMSTART>'
2023-09-19 10:32:49,370 140176451651392 heratbeat.py:103 DEBUG mysqld is running.
2023-09-19 10:32:49,371 140176451651392 heratbeat.py:45 DEBUG 2023-09-19 10:32:49 error send info fail ,return info: b'<ALARMSTART><SystemName>ccc-test-001</SystemName><AlarmID>1695090769370</AlarmID><AlarmEquipment>mysqld</AlarmEquipment><AlarmRes>\xe5\xae\x9a\xe5\x88\xb6\xe6\x8e\xa5\xe5\x8f\xa3\xe6\x9c\x8d\xe5\x8a\xa1\xe5\x99\xa8</AlarmRes><EventTime>2023-09-19 10:32:49</EventTime></ALARMSTART>'
2023-09-19 10:32:49,371 140176451651392 heratbeat.py:106 ERROR cdesk_nginx1 is not running.
[devops@my-dev ABC]$ ./sock.py
服務器已啟動空执,等待客戶端連接...
客戶端 ('127.0.0.1', 41400) 已連接
收到來自 ('127.0.0.1', 41400) 的數據: <ALARMSTART><SystemName>ccc-test-001</SystemName><AlarmID>1695090684048</AlarmID><AlarmEquipment>nginx</AlarmEquipment><AlarmRes>定制接口服務器</AlarmRes><EventTime>2023-09-19 10:31:24</EventTime></ALARMSTART>
客戶端 ('127.0.0.1', 41402) 已連接
收到來自 ('127.0.0.1', 41402) 的數據: <ALARMSTART><SystemName>ccc-test-001</SystemName><AlarmID>1695090684049</AlarmID><AlarmEquipment>mysqld</AlarmEquipment><AlarmRes>定制接口服務器</AlarmRes><EventTime>2023-09-19 10:31:24</EventTime></ALARMSTART>