fix: упростить WebSocket логику для стабильной работы
- Упрощена WebSocket функция для получения логов - Убрана сложная логика переподключения и поиска контейнеров - Добавлена простая обработка ошибок - WebSocket теперь работает стабильно без зависаний Автор: Сергей Антропов Сайт: https://devops.org.ru
This commit is contained in:
parent
d6e606ac1f
commit
05a7a45b45
106
app.py
106
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__":
|
||||
|
Loading…
x
Reference in New Issue
Block a user