From 135d7d0ff3e49a3db118f2ef394b364b39d02702 Mon Sep 17 00:00:00 2001 From: roai_linux Date: Sun, 29 Mar 2026 20:24:16 +0330 Subject: [PATCH] feat: add logger.py and add root to livekit.yaml --- Back/core/logger.py | 38 ++++++++++++++++++++++++ Back/docker-compose.yml | 16 +++------- Back/domains/realtime/speaker_service.py | 29 ++++++++++++------ Back/livekit.yaml | 26 ++++++++++------ 4 files changed, 79 insertions(+), 30 deletions(-) create mode 100644 Back/core/logger.py diff --git a/Back/core/logger.py b/Back/core/logger.py new file mode 100644 index 0000000..b834f9b --- /dev/null +++ b/Back/core/logger.py @@ -0,0 +1,38 @@ +import logging +import os +from typing import Final + + +DEFAULT_LOG_LEVEL: Final[str] = "INFO" +DEFAULT_LOG_FORMAT: Final[str] = ( + "%(asctime)s | %(levelname)s | %(name)s | %(message)s" +) + +_configured = False + + +def _resolve_log_level() -> int: + level_name = os.getenv("LOG_LEVEL", DEFAULT_LOG_LEVEL).upper() + return getattr(logging, level_name, logging.INFO) + + +def setup_logging() -> None: + global _configured + + if _configured: + return + + root_logger = logging.getLogger() + root_logger.setLevel(_resolve_log_level()) + + if not root_logger.handlers: + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter(DEFAULT_LOG_FORMAT)) + root_logger.addHandler(handler) + + _configured = True + + +def get_logger(name: str) -> logging.Logger: + setup_logging() + return logging.getLogger(name) diff --git a/Back/docker-compose.yml b/Back/docker-compose.yml index 5640e40..350c220 100755 --- a/Back/docker-compose.yml +++ b/Back/docker-compose.yml @@ -39,24 +39,16 @@ services: livekit: image: livekit/livekit-server container_name: neda_livekit - ports: - - "7780:7880" - - "7781:7881" - - "51000-52000:51000-52000/udp" - - "3478:3478/udp" - - "5349:5349/tcp" + network_mode: "host" env_file: - .env volumes: - ./livekit.yaml:/etc/livekit/livekit.yaml - # - /etc/letsencrypt/live/pathfinder.wikm.ir:/etc/letsencrypt:ro # uncomment when using letsencrypt + - /etc/letsencrypt:/etc/letsencrypt:ro # uncomment when using letsencrypt command: [ "--config", "/etc/livekit/livekit.yaml", "--keys", "${LIVEKIT_API_KEY}: ${LIVEKIT_API_SECRET}" ] restart: always - networks: - - public - - internal healthcheck: - test: [ "CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:7880/health" ] # بررسی سلامت LiveKit + test: [ "CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:7880/health" ] interval: 10s timeout: 5s retries: 3 @@ -109,7 +101,7 @@ networks: driver: bridge internal: driver: bridge - # internal: true + internal: true volumes: postgres_data: diff --git a/Back/domains/realtime/speaker_service.py b/Back/domains/realtime/speaker_service.py index 997905d..1083252 100644 --- a/Back/domains/realtime/speaker_service.py +++ b/Back/domains/realtime/speaker_service.py @@ -1,6 +1,8 @@ import uuid from livekit import api +from livekit.api.twirp_client import TwirpError from sqlalchemy.ext.asyncio import AsyncSession +from core.logger import get_logger from integrations.livekit.client import get_livekit_api from db.redis import ( acquire_speaker, @@ -8,7 +10,8 @@ from db.redis import ( get_active_speaker ) -from domains.groups.repo import get_group_by_id +logger = get_logger(__name__) + async def request_speak( group_id: str | uuid.UUID, @@ -43,13 +46,21 @@ async def current_speaker(group_id: str | uuid.UUID): async def grant_publish_permission(room_name: str, identity: str, can_publish: bool): lk_api = get_livekit_api() - await lk_api.room.update_participant( - api.UpdateParticipantRequest( - room=room_name, - identity=identity, - permission=api.ParticipantPermission( - can_publish=can_publish, - can_subscribe=True + try: + await lk_api.room.update_participant( + api.UpdateParticipantRequest( + room=room_name, + identity=identity, + permission=api.ParticipantPermission( + can_publish=can_publish, + can_subscribe=True + ) ) ) - ) \ No newline at end of file + except TwirpError as e: + if "not_found" in str(e).lower() or "exist" in str(e).lower(): + logger.warning(f"Participant {identity} already left the room.") + else: + logger.error(f"Error updating participant: {e}") + except Exception as e: + logger.error(f"Unexpected error in grant_permission: {e}") diff --git a/Back/livekit.yaml b/Back/livekit.yaml index ad20779..c1a8d1c 100644 --- a/Back/livekit.yaml +++ b/Back/livekit.yaml @@ -3,18 +3,26 @@ port: 7880 rtc: tcp_port: 7881 port_range_start: 51000 - port_range_end: 52000 + port_range_end: 51100 use_external_ip: false - # node_ip: "94.183.170.121" # uncomment when using server ip + node_ip: "188.213.199.211" # uncomment when using server ip + allow_tcp_fallback: true + congestion_control: + enabled: true + +room: + empty_timeout: 600 + departure_timeout: 600 + auto_create: true ##### uncomment when using letsencrypt in server ####### -# turn: -# cert_file: "/etc/letsencrypt/live/pathfinder.wikm.ir/fullchain.pem" -# key_file: "/etc/letsencrypt/live/pathfinder.wikm.ir/privkey.pem" -# tls_port: 5349 -# udp_port: 3478 -# external_tls: false -# domain: "pathfinder.wikm.ir" +turn: + cert_file: "/etc/letsencrypt/live/pathfinder.wikm.ir/fullchain.pem" + key_file: "/etc/letsencrypt/live/pathfinder.wikm.ir/privkey.pem" + tls_port: 5349 + udp_port: 3478 + external_tls: false + domain: "pathfinder.wikm.ir" ####################################################### logging: