"""LogHive configuration.""" import os from datetime import datetime, timezone, timedelta from typing import Optional # Beijing timezone offset _BEIJING_TZ = timezone(timedelta(hours=8)) def to_display_time(dt: datetime) -> str: """Convert a UTC datetime to Beijing time for display. Returns ISO format without timezone suffix (e.g. '2026-05-08T14:30:00').""" if dt is None: return None if dt.tzinfo is None: dt = dt.replace(tzinfo=timezone.utc) local = dt.astimezone(_BEIJING_TZ) return local.strftime("%Y-%m-%dT%H:%M:%S") def from_query_time(dt: Optional[datetime]) -> Optional[datetime]: """Interpret a naive datetime query param as Beijing time, return UTC datetime.""" if dt is None: return None if dt.tzinfo is None: dt = dt.replace(tzinfo=_BEIJING_TZ) return dt.astimezone(timezone.utc) class Settings: """Application settings loaded from environment variables.""" # Service name SERVICE_NAME: str = "LogHive" # API API_HOST: str = os.getenv("API_HOST", "0.0.0.0") API_PORT: int = int(os.getenv("API_PORT", "8000")) DEBUG: bool = os.getenv("DEBUG", "false").lower() == "true" CORS_ORIGINS: list[str] = os.getenv("CORS_ORIGINS", "*").split(",") # Security SECRET_KEY: str = os.getenv("SECRET_KEY", "change-me-in-production") TOKEN_EXPIRE_HOURS: int = int(os.getenv("TOKEN_EXPIRE_HOURS", "720")) # PostgreSQL DATABASE_URL: str = os.getenv( "DATABASE_URL", "postgresql+asyncpg://LogHive:LogHive@localhost:5432/LogHive", ) # Redis REDIS_URL: str = os.getenv("REDIS_URL", "redis://localhost:6379/0") # Celery CELERY_BROKER_URL: str = os.getenv("CELERY_BROKER_URL", "redis://localhost:6379/1") CELERY_RESULT_BACKEND: str = os.getenv( "CELERY_RESULT_BACKEND", "redis://localhost:6379/2" ) # Log retention (days) LOG_RETENTION_DAYS: int = int(os.getenv("LOG_RETENTION_DAYS", "30")) LOG_COLD_STORAGE_DAYS: int = int(os.getenv("LOG_COLD_STORAGE_DAYS", "7")) # Rate limit RATE_LIMIT_PER_SECOND: int = int(os.getenv("RATE_LIMIT_PER_SECOND", "1000")) # Alert ALERT_CHECK_INTERVAL_SECONDS: int = int( os.getenv("ALERT_CHECK_INTERVAL_SECONDS", "60") ) # Notification FEISHU_WEBHOOK_URL: Optional[str] = os.getenv("FEISHU_WEBHOOK_URL", None) DINGTALK_WEBHOOK_URL: Optional[str] = os.getenv("DINGTALK_WEBHOOK_URL", None) settings = Settings()