Skip to content

CLI 로깅 추가 및 Datahub GMS 연결체크 기능 분리 #95

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,21 @@
Datahub GMS 서버 URL을 설정하고, 필요 시 Streamlit 인터페이스를 실행하는 CLI 프로그램입니다.
"""

import logging
import subprocess

import click

from llm_utils.check_server import CheckServer
from llm_utils.tools import set_gms_server

logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
logger = logging.getLogger(__name__)


@click.group()
@click.version_option(version="0.1.4")
Expand Down Expand Up @@ -64,11 +73,20 @@ def cli(
'set_gms_server' 함수에서 ValueError가 발생할 경우, 프로그램은 비정상 종료(exit code 1)합니다.
"""

try:
logger.info(
"Initialization started: GMS server = %s, run_streamlit = %s, port = %d",
datahub_server,
run_streamlit,
port,
)

if CheckServer.is_gms_server_healthy(url=datahub_server):
set_gms_server(datahub_server)
except ValueError as e:
click.secho(f"GMS 서버 URL 설정 실패: {str(e)}", fg="red")
logger.info("GMS server URL successfully set: %s", datahub_server)
else:
logger.error("GMS server health check failed. URL: %s", datahub_server)
ctx.exit(1)

if run_streamlit:
run_streamlit_command(port)

Expand All @@ -89,6 +107,8 @@ def run_streamlit_command(port: int) -> None:
- subprocess 호출 실패 시 예외가 발생할 수 있습니다.
"""

logger.info("Starting Streamlit application on port %d...", port)

try:
subprocess.run(
[
Expand All @@ -100,8 +120,9 @@ def run_streamlit_command(port: int) -> None:
],
check=True,
)
logger.info("Streamlit application started successfully.")
except subprocess.CalledProcessError as e:
click.echo(f"Streamlit 실행 실패: {e}")
logger.error("Failed to start Streamlit application: %s", e)
raise


Expand Down Expand Up @@ -132,4 +153,5 @@ def run_streamlit_cli_command(port: int) -> None:
- Streamlit 실행에 실패할 경우 subprocess 호출에서 예외가 발생할 수 있습니다.
"""

logger.info("Executing 'run-streamlit' command on port %d...", port)
run_streamlit_command(port)
1 change: 0 additions & 1 deletion data_utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
# data_utils 패키지 초기화 파일
74 changes: 74 additions & 0 deletions llm_utils/check_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""
서버 상태 확인 및 연결 관련 기능을 제공하는 유틸리티 클래스입니다.

이 모듈은 HTTP 기반의 서버에 대해 다음과 같은 기능을 제공합니다:
- `/health` 엔드포인트를 통한 서버 헬스 체크
- 향후 서버 연결 또는 상태 점검과 관련된 기능 추가 예정

각 기능은 요청 실패, 타임아웃, 연결 오류 등의 다양한 예외 상황을 포괄적으로 처리하며,
로깅을 통해 상세한 실패 원인을 기록하고 결과를 boolean 또는 적절한 형태로 반환합니다.
"""

import logging
from urllib.parse import urljoin

import requests

logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)
logger = logging.getLogger(__name__)


class CheckServer:
"""
서버의 상태를 확인하거나 연결을 테스트하는 유틸리티 메서드를 제공하는 클래스입니다.

현재는 GMS 서버의 `/health` 엔드포인트에 대한 헬스 체크 기능을 포함하고 있으며,
향후에는 다양한 서버 연결 확인 및 상태 점검 기능이 추가될 수 있도록 확장 가능한 구조로 설계되었습니다.
모든 기능은 네트워크 오류 및 서버 응답 상태에 따라 예외를 로깅하며, 호출자가 결과를 판단할 수 있도록 boolean 값을 반환합니다.
"""

@staticmethod
def is_gms_server_healthy(*, url: str) -> bool:
"""
지정된 GMS 서버의 `/health` 엔드포인트에 요청을 보내 상태를 확인합니다.

서버가 HTTP 200 응답을 반환하면 True를 반환하며,
요청 실패, 타임아웃, 연결 오류 등의 예외 발생 시 False를 반환하고,
로깅을 통해 상세한 에러 정보를 출력합니다.

Args:
url (str): 헬스 체크를 수행할 GMS 서버의 기본 URL (예: "http://localhost:8080")

Returns:
bool: 서버가 정상적으로 응답하면 True, 예외 발생 시 False
"""

health_url = urljoin(url, "/health")

try:
response = requests.get(
health_url,
timeout=3,
)
response.raise_for_status()
logger.info("GMS server is healthy: %s", url)
return True
except (
requests.exceptions.ConnectTimeout,
requests.exceptions.ReadTimeout,
) as e:
logger.error(
"Timeout while connecting to GMS server: %s | %s", health_url, e
)
except requests.exceptions.ConnectionError as e:
logger.error("Failed to connect to GMS server: %s | %s", health_url, e)
except requests.exceptions.HTTPError as e:
logger.error("GMS server returned HTTP error: %s | %s", health_url, e)
except requests.exceptions.RequestException as e:
logger.exception("Unexpected request error to GMS server: %s", health_url)

return False