feat(monitoring): add health check endpoint and psutil dependency

Introduce a health check endpoint `/health` to monitor the application's status, including uptime, memory usage, CPU percentage, and thread count. Add `psutil` dependency to gather system metrics. Also, include `curl` in Dockerfile for health check functionality and update the health check configuration in Dockerfile.
This commit is contained in:
danial
2025-04-06 21:47:35 +08:00
parent 752ef17fc8
commit 3896439d08
3 changed files with 48 additions and 10 deletions

View File

@@ -15,7 +15,7 @@ RUN echo "" > /etc/apt/sources.list && \
echo "deb http://mirrors.aliyun.com/debian buster-updates main" >> /etc/apt/sources.list
# 安装cv2依赖和其他依赖
RUN apt-get update && apt-get install -y libgl1-mesa-glx libglib2.0-0
RUN apt-get update && apt-get install -y libgl1-mesa-glx libglib2.0-0 curl
# 下载并安装 Node.js
RUN wget https://nodejs.org/dist/v16.13.0/node-v16.13.0-linux-x64.tar.gz && \
@@ -32,5 +32,9 @@ RUN pip3 install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# 暴露容器端口
EXPOSE 5001
# 添加健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
CMD curl -f http://localhost:5001/health || exit 1
# 运行应用
CMD ["gunicorn", "-c", "gun.conf", "app:app"]

49
app.py
View File

@@ -1,4 +1,7 @@
import json
import os
import time
import psutil
from flask import Flask, g, request, jsonify
@@ -8,6 +11,9 @@ from logger import get_logger
app = Flask(__name__)
logger = get_logger()
# 记录应用启动时间
START_TIME = time.time()
@app.before_request
def before_request():
@@ -20,11 +26,38 @@ def before_request():
g.proxies = {}
@app.route('/xiecheng/v3/card/bind', methods=['GET', 'POST'])
@app.route("/health", methods=["GET"])
def health_check():
"""健康检查接口,用于容器监控服务状态"""
# 获取当前进程信息
process = psutil.Process(os.getpid())
# 计算运行时间
uptime = time.time() - START_TIME
# 获取内存使用情况
memory_info = process.memory_info()
health_data = {
"status": "ok",
"uptime": f"{uptime:.2f} seconds",
"memory": {
"rss": f"{memory_info.rss / (1024 * 1024):.2f} MB", # 物理内存
"vms": f"{memory_info.vms / (1024 * 1024):.2f} MB", # 虚拟内存
},
"cpu_percent": f"{process.cpu_percent(interval=0.1):.2f}%",
"threads": len(process.threads()),
"version": "1.0.0",
}
return jsonify(health_data)
@app.route("/xiecheng/v3/card/bind", methods=["GET", "POST"])
def bind_card_v3():
if request.method == 'GET':
return 'okk'
elif request.method == 'POST':
if request.method == "GET":
return "okk"
elif request.method == "POST":
# 接收参数
data = json.loads(request.get_data())
g.ck = data.get("ck")
@@ -38,7 +71,7 @@ def bind_card_v3():
card_num=g.card_num,
card_pwd=g.card_pwd,
price=g.money,
order_num=g.order_num
order_num=g.order_num,
)
res = trip.run()
logger.info(f"订单ID{g.order_num},返回速代充:{res}")
@@ -47,13 +80,13 @@ def bind_card_v3():
res = trip.check_card()
logger.info(f"订单ID{g.order_num},未知重新查卡返回:{res}")
if res.get("code") in [110, 2001]:
res = {'code': 110, 'msg': '重新查卡返回可重新绑卡', 'data': {}}
res = {"code": 110, "msg": "重新查卡返回可重新绑卡", "data": {}}
return jsonify(res)
if res.get("code") == 111:
continue
res = {'code': 111, 'msg': '重新查卡未知', 'data': {}}
res = {"code": 111, "msg": "重新查卡未知", "data": {}}
return jsonify(res)
if __name__ == '__main__':
if __name__ == "__main__":
app.run()

View File

@@ -12,3 +12,4 @@ pillow==10.3.0
pycryptodome==3.21.0
pytz==2024.2
loguru==0.7.2
psutil==5.9.5