diff --git a/app.py b/app.py index 8b991b6..1722969 100644 --- a/app.py +++ b/app.py @@ -161,98 +161,58 @@ def api_snapshot( @app.websocket("/ws/logs/{container_id}") async def ws_logs(ws: WebSocket, container_id: str, tail: int = DEFAULT_TAIL, token: Optional[str] = None, service: Optional[str] = None, project: Optional[str] = None): + """Упрощенный WebSocket для получения логов контейнера""" + + # Принимаем соединение await ws.accept() + + # Проверяем токен if not token or not verify_ws_token(token): await ws.send_text("ERROR: unauthorized") - await ws.close(); return + await ws.close() + return - def find_by_id_prefix(prefix: str): - """Простой поиск контейнера по ID""" - try: - for c in docker_client.containers.list(all=True): - if c.id.startswith(prefix): - return c - except Exception as e: - print(f"❌ Ошибка поиска контейнера по ID {prefix}: {e}") - return None - - def find_by_service(service_name: str, project_name: Optional[str] = None): - """Простой поиск контейнера по сервису""" - try: - found = [] - for c in docker_client.containers.list(all=True): - try: - lbl = c.labels or {} - if lbl.get("com.docker.compose.service") == service_name and (project_name is None or lbl.get("com.docker.compose.project")==project_name): - found.append(c) - except Exception: - continue # Пропускаем контейнеры с проблемными метками - - if not found: - return None - - # Возвращаем первый найденный контейнер - return found[0] - except Exception as e: - print(f"❌ Ошибка поиска контейнера по сервису {service_name}: {e}") - return None - - # initial resolve - container = None - svc_label = None - proj_label = None - - # If service provided, prefer it for resolving container - if service: - container = find_by_service(service, project) - if container is None: - container = find_by_id_prefix(container_id) - - if container: - lbls = container.labels or {} - svc_label = service or lbls.get("com.docker.compose.service") - proj_label = project or lbls.get("com.docker.compose.project") - else: - # if cannot resolve anything - and we do have service, try waiting a bit (maybe recreating) - svc_label = service - proj_label = project - - # Упрощенная логика получения логов try: + # Простой поиск контейнера по ID + container = None + try: + for c in docker_client.containers.list(all=True): + if c.id.startswith(container_id): + container = c + break + except Exception as e: + await ws.send_text(f"ERROR: cannot list containers - {e}") + return + if container is None: await ws.send_text("ERROR: container not found") return - # Получаем логи контейнера + # Отправляем начальное сообщение + await ws.send_text(f"Connected to container: {container.name}") + + # Получаем логи (только последние строки, без follow) try: - stream = container.logs(stream=True, follow=True, tail=tail) - - # Отправляем логи клиенту - for chunk in stream: - if chunk is None: - break - try: - await ws.send_text(chunk.decode(errors="ignore")) - except Exception: - # Клиент отключился - break - - stream.close() - + logs = container.logs(tail=tail).decode(errors="ignore") + if logs: + await ws.send_text(logs) + else: + await ws.send_text("No logs available") except Exception as e: - await ws.send_text(f"ERROR: {e}") - + await ws.send_text(f"ERROR getting logs: {e}") + except WebSocketDisconnect: - pass # Клиент отключился + print("WebSocket client disconnected") except Exception as e: + print(f"WebSocket error: {e}") try: await ws.send_text(f"ERROR: {e}") - except Exception: + except: pass finally: try: await ws.close() - except Exception: + except: pass if __name__ == "__main__":