Python实现日志收集,监控程序状态并使用Kafka发送消息
本文主要使用Python实现监控程序运行时状态,并对产生的错误日志文件进行收集,最后将收集到的日志数据使用Kafka发送,便于其他服务拉取处理
1.准备一个demo程序用于产生日志
实例代码如下:
import os
import time
log_file_path = "C:/Users/15224/Desktop/log_file.log"
with open(log_file_path, 'w') as file:
file.write("Start Writing.\n")
# 获取当前进程ID并打印
print(f"Current process ID: {os.getpid()}")
print("----------------------------------")
ERROR_MES = '''Log [http-nio-8180-exec-43] ERROR c.r.f.w.e.GlobalExceptionHandler - [handleRuntimeException,96] - 请求地址'/captchaImage',发生未知异常.
java.lang.NullPointerException: null
at sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264)
at sun.awt.FontConfiguration.readFontConfigFile(FontConfiguration.java:219)
at sun.awt.FontConfiguration.init(FontConfiguration.java:107)END'''
def simulated_program():
for i in range(100):
print(f"iteration {i}")
with open(log_file_path, 'a') as file:
if i % 2 == 0:
file.write(f"Log INFO {i}\n")
else:
file.write(ERROR_MES+f"{i}\n")
time.sleep(1)
simulated_program()
这段代码的功能主要是用于模拟正常程序执行过程中产生的日志文件数据,在这个程序中,交替将日志类型为ERROR和INFO的日志文件写入到自定义的一个文件夹中,后面的收集程序将从这个文件夹中获取指定的的日志文件。
运行程序,在对应文件夹下查看是否生成了日志:
成功产生以Log前缀开头的日志文件
2.实现日志收集程序
实例代码如下:
from confluent_kafka import Producer
import psutil
import time
import json
import os
key_msg = "ERROR" # 哪些日志需要收集,这里是含有ERROR的日志都要收集
log_prefix = "Log" # 日志前缀 测试的每个日志都是以Log开头 例:Log [http-nio-8180-exec-43] ERROR c.r.f.w.e.GlobalExceptionHandler...
# 决定根据应用名称或进程ID监控应用程序,二选一即可
process_name = "process_name"
process_id = 8888
log_file_path = "C:/Users/15224/Desktop/log_file.log" # 将这个值替换存放日志的路径
last_position = 0 # 记录上次读取日志的位置
log_list = []
log_map = {}
# Kafka 服务器配置并创建 Kafka 生产者
bootstrap_servers = '127.0.0.1:9092'
topic = 'log-topic'
producer = Producer({'bootstrap.servers': bootstrap_servers})
def delivery_report(err, msg):
if err is not None:
print(f'Message delivery failed: {err}')
else:
print(f'Message delivered to {msg.topic()} [{msg.partition()}]')
def send_map_to_kafka(data):
# 将字典转换为 JSON 格式
data_str = json.dumps(data)
# 发送数据到 Kafka 主题
producer.produce(topic, data_str, callback=delivery_report)
# 刷新缓冲并触发消息传递回调
producer.flush()
# 根据应用名判断状态
def check_process_status(process_name):
for proc in psutil.process_iter(['pid', 'name']):
if process_name.lower() in proc.info['name'].lower():
return True
return False
while True:
if check_process_status(process_name):
print(f"{process_name} is running.")
else:
print(f"{process_name} is not running.")
# 若想根据进程id判断,将上面注释并打开这段注释
# while True:
# if psutil.pid_exists(process_id):
# print(f"Process with PID {process_id} is running.")
# else:
# print(f"Process with PID {process_id} is not running.")
if os.path.exists(log_file_path):
with open(log_file_path, 'rb') as file:
file.seek(last_position)
new_data = file.read().decode('utf-8', errors='ignore') # 从上次位置读取到文件末尾的新内容
new_lines = new_data.splitlines() # 将读取的内容按行拆分
# print(new_lines)
capture = False
for line in new_lines:
if key_msg in line:
log_list.append(line)
capture = True
elif line.startswith(log_prefix) and capture:
capture = False
continue
elif capture:
log_list.append(line)
if log_list: # 如果log_list中有ERROR信息
log_map = {"lastLog": log_list}
# 发送数据到Kafka
send_map_to_kafka(log_map)
print("LatestLogMap:", log_map)
print("---------------------------------------------")
log_list = [] # 清空列表
last_position = file.tell() # 更新文件指针的位置到文件末尾
else:
print(f"Log file {log_file_path} does not exist.")
time.sleep(5) # 5秒执行一次
这段代码主要实现了根据程序名来监控当前程序的运行状态并从日志文件夹中获取指定的日志文件,并且每次读取的日志文件是最新产生的,获取后将这些日志文件封装成Map发送到了特定的Kafka主题中。
注意:如果按照程序名进行状态的监控的话,请确保你的程序名唯一
在运行程序之前,需要启动Kafka服务,并创建对应主题
1)启动Kafka:
找到你的Kafka安装目录,进入bin,进入windows,在windows下运行cmd
Kafka强依赖于Zookepper,先启动Zookeeper
zookeeper-server-start.bat ../../config/zookeeper.properties
在windows目录下再次运行cmd,启动Kafka
kafka-server-start.bat ../../config/server.properties
成功启动Kafka
2)创建Kafka主题
同样打开windows目录下的命令行窗口,输入:
kafka-topics.bat --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic log-topic
其中log-topic是你自定义的主题名称
3)创建Kafka消费者并订阅主题
打开windows目录下的命令行窗口,输入:
kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic log-topic
4)启动程序
程序成功运行,将指定文件夹的日志文件中,含有ERROR的日志收集到,并发送到了Kafka主题中
消费者端也成功收到消息
至此,就实现了使用Python进行对特定程序的状态监控,并且将程序的错误日志文件进行收集,发送到了Kakfa主题中。