Skip to content
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

Add Healthcheck to Auto_Bangumi #803

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ RUN set -ex && \
su-exec \
shadow \
tini \
curl \
openssl \
tzdata && \
python3 -m pip install --no-cache-dir --upgrade pip && \
Expand All @@ -39,6 +40,9 @@ RUN set -ex && \
COPY --chmod=755 backend/src/. .
COPY --chmod=755 entrypoint.sh /entrypoint.sh

# Add healthcheck endpoint
HEALTHCHECK --interval=5s --timeout=10s --retries=3 CMD curl --silent --fail http://localhost:7892/api/v1/health || exit 1

ENTRYPOINT ["tini", "-g", "--", "/entrypoint.sh"]

EXPOSE 7892
Expand Down
2 changes: 2 additions & 0 deletions backend/src/module/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .program import router as program_router
from .rss import router as rss_router
from .search import router as search_router
from .health import router as health_router

__all__ = "v1"

Expand All @@ -19,3 +20,4 @@
v1.include_router(config_router)
v1.include_router(rss_router)
v1.include_router(search_router)
v1.include_router(health_router)
46 changes: 46 additions & 0 deletions backend/src/module/api/health.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import logging
from fastapi import APIRouter
from fastapi.responses import JSONResponse
from typing import Literal

from module.models import APIResponse
from module.checker import Checker

router = APIRouter(prefix="/health", tags=["health"])
logger = logging.getLogger(__name__)

current_health_status = "healthy"

@router.get("", response_model=APIResponse)
async def health_check():
global current_health_status
if not Checker.check_downloader():
current_health_status = "unhealthy"
if current_health_status == "healthy":
return JSONResponse(
status_code=200,
content={"status": "healthy"},
)
else:
current_health_status = "unhealthy"
return JSONResponse(
status_code=500,
content={"status": "unhealthy"},
)

@router.patch("", response_model=APIResponse)
async def update_health_status(status: Literal["healthy", "unhealthy"]):
global current_health_status
try:
logger.debug(f"[Health] Health status changed from {current_health_status} to {status}")
current_health_status = status
return JSONResponse(
status_code=200,
content={"msg_en": "Health status updated successfully.", "msg_zh": "健康状态更新成功。"},
)
except Exception as e:
logger.warning(f"[Health] Health status updated failed: {str(e)}")
return JSONResponse(
status_code=406,
content={"msg_en": "Health status updated failed.", "msg_zh": "健康状态更新失败。"},
)
19 changes: 19 additions & 0 deletions backend/src/module/network/request_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@ class RequestURL:
def __init__(self):
self.header = {"user-agent": "Mozilla/5.0", "Accept": "application/xml"}
self._socks5_proxy = False

# Patch the health api endpoint if Network connection was changed
def change_health_status(self,health_status):
health_check_url = f"http://localhost:7892/api/v1/health?status={health_status}"

try:
response = requests.patch(health_check_url)
response.raise_for_status()
logger.debug(
f"[Health] Health status changed to {health_status}."
)
except requests.exceptions.RequestException as e:
logger.debug(
f"[Health] Failed to update health status: {e}"
)

def get_url(self, url, retry=3):
try_time = 0
Expand All @@ -22,6 +37,7 @@ def get_url(self, url, retry=3):
req = self.session.get(url=url, headers=self.header, timeout=5)
logger.debug(f"[Network] Successfully connected to {url}. Status: {req.status_code}")
req.raise_for_status()
self.change_health_status("healthy")
return req
except requests.RequestException:
logger.debug(
Expand All @@ -35,6 +51,7 @@ def get_url(self, url, retry=3):
logger.debug(e)
break
logger.error(f"[Network] Unable to connect to {url}, Please check your network settings")
self.change_health_status("unhealthy")
return None

def post_url(self, url: str, data: dict, retry=3):
Expand All @@ -45,6 +62,7 @@ def post_url(self, url: str, data: dict, retry=3):
url=url, headers=self.header, data=data, timeout=5
)
req.raise_for_status()
self.change_health_status("healthy")
return req
except requests.RequestException:
logger.warning(
Expand All @@ -59,6 +77,7 @@ def post_url(self, url: str, data: dict, retry=3):
break
logger.error(f"[Network] Failed connecting to {url}")
logger.warning("[Network] Please check DNS/Connection settings")
self.change_health_status("unhealthy")
return None

def check_url(self, url: str):
Expand Down