Some checks failed
Integration Tests / integration-tests (push) Failing after 20s
Integration Tests / performance-tests (push) Has been skipped
Service Adapters (Python FastAPI) / test (3.11) (push) Failing after 23s
Frontend (React) / test (20) (push) Failing after 1m3s
Frontend (React) / build (push) Has been skipped
Frontend (React) / lighthouse (push) Has been skipped
Service Adapters (Python FastAPI) / test (3.12) (push) Failing after 23s
Service Adapters (Python FastAPI) / test (3.13) (push) Failing after 20s
Service Adapters (Python FastAPI) / build (push) Has been skipped
### Summary of Changes - Removed proxy configuration in `rsbuild.config.js` as the API Gateway is not running. - Added smooth transitions and gentle loading overlays in CSS for improved user experience during data loading. - Updated `Dashboard` component to conditionally display loading spinner and gentle loading overlay based on data fetching state. - Enhanced `useOfflineAwareServiceStatus` and `useOfflineAwareSystemData` hooks to manage loading states and service status more effectively. - Increased refresh intervals for service status and system data to reduce API call frequency. ### Expected Results - Improved user experience with smoother loading transitions and better feedback during data refreshes. - Enhanced handling of service status checks, providing clearer information when services are unavailable. - Streamlined code for managing loading states, making it easier to maintain and extend in the future.
151 lines
5.1 KiB
Python
151 lines
5.1 KiB
Python
import logging
|
|
from datetime import datetime
|
|
|
|
from fastapi import APIRouter
|
|
|
|
from models.schemas import HealthResponse, RootResponse, ServiceStatus
|
|
from services.config import SERVICES
|
|
from services.status_checker import status_checker
|
|
|
|
# Configure logger
|
|
logger = logging.getLogger(__name__)
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get(
|
|
"/",
|
|
response_model=RootResponse,
|
|
summary="API Root",
|
|
description="Get basic API information",
|
|
tags=["General"],
|
|
)
|
|
async def root():
|
|
"""Get basic API information and version"""
|
|
return RootResponse(message="LabFusion Service Adapters API", version="1.0.0")
|
|
|
|
|
|
@router.get(
|
|
"/health",
|
|
response_model=HealthResponse,
|
|
summary="Health Check",
|
|
description="Check service health status",
|
|
tags=["General"],
|
|
)
|
|
async def health_check():
|
|
"""Check the health status of the service adapters"""
|
|
logger.debug("Health check endpoint called")
|
|
return HealthResponse(status="healthy", timestamp=datetime.now().isoformat())
|
|
|
|
|
|
@router.get(
|
|
"/debug/logging",
|
|
summary="Logging Debug Info",
|
|
description="Get current logging configuration and test log levels",
|
|
tags=["Debug"],
|
|
)
|
|
async def debug_logging():
|
|
"""Debug endpoint to test unified logging configuration"""
|
|
# Test different log levels
|
|
logger.debug("This is a DEBUG message from routes.general")
|
|
logger.info("This is an INFO message from routes.general")
|
|
logger.warning("This is a WARNING message from routes.general")
|
|
logger.error("This is an ERROR message from routes.general")
|
|
|
|
# Test request logger
|
|
from services.logging_config import get_request_logger
|
|
request_logger = get_request_logger()
|
|
request_logger.info("This is a request logger message")
|
|
|
|
# Test application logger
|
|
from services.logging_config import get_application_logger
|
|
app_logger = get_application_logger()
|
|
app_logger.info("This is an application logger message")
|
|
|
|
# Get current logging configuration
|
|
root_logger = logging.getLogger()
|
|
config_info = {
|
|
"root_level": logging.getLevelName(root_logger.level),
|
|
"handlers": [str(h) for h in root_logger.handlers],
|
|
"handler_count": len(root_logger.handlers),
|
|
"status_checker_level": logging.getLevelName(logging.getLogger("services.status_checker").level),
|
|
"general_level": logging.getLevelName(logging.getLogger("routes.general").level),
|
|
"request_logger_level": logging.getLevelName(request_logger.level),
|
|
"application_logger_level": logging.getLevelName(app_logger.level),
|
|
"uvicorn_access_level": logging.getLevelName(logging.getLogger("uvicorn.access").level),
|
|
}
|
|
|
|
logger.info("Unified logging debug info requested")
|
|
return {
|
|
"message": "Unified log messages sent to console",
|
|
"config": config_info,
|
|
"note": "All logs now use the same format and handler"
|
|
}
|
|
|
|
|
|
@router.get(
|
|
"/debug/sensor/{service_name}",
|
|
summary="Debug Sensor Data",
|
|
description="Get raw sensor data for debugging health check issues",
|
|
tags=["Debug"],
|
|
)
|
|
async def debug_sensor(service_name: str):
|
|
"""Debug endpoint to inspect raw sensor data"""
|
|
from services.config import SERVICES
|
|
from services.health_checkers import factory
|
|
|
|
if service_name not in SERVICES:
|
|
return {"error": f"Service {service_name} not found"}
|
|
|
|
config = SERVICES[service_name]
|
|
if config.get("health_check_type") != "sensor":
|
|
return {"error": f"Service {service_name} is not using sensor health checking"}
|
|
|
|
try:
|
|
# Create sensor checker
|
|
checker = factory.create_checker("sensor", timeout=10.0)
|
|
|
|
# Get raw sensor data
|
|
result = await checker.check_health(service_name, config)
|
|
|
|
return {
|
|
"service_name": service_name,
|
|
"config": config,
|
|
"result": result.to_dict(),
|
|
"raw_sensor_data": result.metadata
|
|
}
|
|
except Exception as e:
|
|
logger.error(f"Error debugging sensor for {service_name}: {e}")
|
|
return {"error": str(e)}
|
|
|
|
|
|
@router.get(
|
|
"/services",
|
|
response_model=dict,
|
|
summary="Get Service Status",
|
|
description="Get status of all configured external services",
|
|
tags=["Services"],
|
|
)
|
|
async def get_services():
|
|
"""Get status of all configured external services (Home Assistant, Frigate, Immich, n8n)"""
|
|
logger.info("Service status endpoint called - checking all services")
|
|
|
|
# Check all services concurrently
|
|
status_results = await status_checker.check_all_services()
|
|
|
|
service_status = {}
|
|
for service_name, config in SERVICES.items():
|
|
status_info = status_results.get(service_name, {})
|
|
service_status[service_name] = ServiceStatus(
|
|
enabled=config["enabled"],
|
|
url=config["url"],
|
|
status=status_info.get("status", "unknown"),
|
|
response_time=status_info.get("response_time"),
|
|
error=status_info.get("error"),
|
|
uptime=status_info.get("uptime"),
|
|
metadata=status_info.get("metadata", {})
|
|
)
|
|
|
|
logger.info(f"Service status check completed - returning status for {len(service_status)} services")
|
|
return service_status
|