diff --git a/.devops/monitor.py b/.devops/monitor.py index 28403aa..4abac24 100644 --- a/.devops/monitor.py +++ b/.devops/monitor.py @@ -749,6 +749,31 @@ class DeploymentServer: self.app = Flask(__name__) self._setup_routes() + def get_all_containers(self): + """获取所有Docker容器列表""" + try: + cmd = "docker ps --format '{{.ID}}|{{.Names}}|{{.Status}}|{{.Image}}'" + result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=10) + + if result.returncode != 0: + return [] + + containers = [] + for line in result.stdout.strip().split('\n'): + if line: + parts = line.split('|') + if len(parts) >= 4: + containers.append({ + 'id': parts[0], + 'name': parts[1], + 'status': parts[2], + 'image': parts[3] + }) + return containers + except Exception as e: + Logger.error(f"获取容器列表失败: {e}") + return [] + def _setup_routes(self): """设置路由""" @@ -834,7 +859,7 @@ class DeploymentServer:

📖 使用说明

触发部署:点击下方表格中的"部署链接",或直接访问 http://IP:9999/项目名称

示例:http://IP:9999/tuoheng-device 触发 tuoheng-device 项目部署

-

查看日志:点击这里查看部署日志

+

查看日志:点击这里查看部署日志 | 查看容器日志

📦 可部署项目列表

@@ -1063,11 +1088,329 @@ class DeploymentServer: except Exception as e: return jsonify({'logs': [], 'error': str(e)}) + @self.app.route('/containers') + def view_containers(): + """容器列表页面""" + containers = self.get_all_containers() + + html = ''' + + + + + Docker 容器管理 + + + +

🐳 Docker 容器管理

+
+ ← 返回首页 +

说明:点击容器名称查看该容器的实时日志

+
+

📋 运行中的容器列表

+
+ + + + + + + + + + + ''' + + for container in containers: + html += f''' + + + + + + + + ''' + + if not containers: + html += ''' + + + + ''' + + html += ''' + +
容器ID容器名称状态镜像操作
{container['id'][:12]}{container['name']}{container['status']}{container['image']}查看日志
+ 暂无运行中的容器 +
+ + + ''' + return html + + @self.app.route('/container-logs/') + def view_container_logs(container_name): + """容器日志查看页面""" + html = f''' + + + + + 容器日志 - {container_name} + + + +
+
+

📋 容器日志: {container_name}

+ ← 返回容器列表 +
+
+ + + +
+
+
+
正在加载日志...
+
+ + + + ''' + return html + + @self.app.route('/api/container-logs/') + def get_container_logs(container_name): + """获取容器日志API""" + try: + cmd = f"docker logs --tail 500 {container_name}" + result = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=10) + + if result.returncode != 0: + return jsonify({'logs': [], 'error': f'获取容器日志失败: {result.stderr}'}) + + # 合并 stdout 和 stderr + logs = [] + if result.stdout: + logs.extend(result.stdout.strip().split('\n')) + if result.stderr: + logs.extend(result.stderr.strip().split('\n')) + + return jsonify({'logs': logs}) + except Exception as e: + return jsonify({'logs': [], 'error': str(e)}) + @self.app.route('/') def deploy_project(project_name): """触发项目部署""" - # 避免与 /logs 路由冲突 - if project_name == 'logs' or project_name == 'api': + # 避免与其他路由冲突 + if project_name in ['logs', 'api', 'containers', 'container-logs']: return jsonify({'code': 404, 'message': '路径不存在'}) Logger.info(f"收到HTTP部署请求: {project_name}")