#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ LogBoard+ - Веб-панель для просмотра логов микросервисов Автор: Сергей Антропов Сайт: https://devops.org.ru """ import os from fastapi import FastAPI, Request, HTTPException from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from fastapi.middleware.cors import CORSMiddleware from core.config import DEBUG_MODE, SNAP_DIR, STATIC_DIR, APP_PORT from api.v1.router import api_router, pages_router from core.logger import app_logger # Инициализация FastAPI app = FastAPI( title="LogBoard+", description="Веб-панель для просмотра логов микросервисов", version="1.0.0", docs_url="/docs" if DEBUG_MODE else None, redoc_url="/redoc" if DEBUG_MODE else None ) # Настройка CORS app.add_middleware( CORSMiddleware, allow_origins=["*"], # В продакшене лучше указать конкретные домены allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Инициализация шаблонов from core.config import templates # serve snapshots directory (downloadable files) os.makedirs(SNAP_DIR, exist_ok=True) app.mount("/snapshots", StaticFiles(directory=SNAP_DIR), name="snapshots") # serve static files directory os.makedirs(STATIC_DIR, exist_ok=True) app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static") # Обработчики исключений @app.exception_handler(404) async def not_found_handler(request: Request, exc: HTTPException): """Обработчик ошибки 404 - Страница не найдена""" return templates.TemplateResponse("error.html", { "request": request, "error_code": 404, "error_title": "Страница не найдена", "error_message": "Запрашиваемая страница не существует или была перемещена." }, status_code=404) @app.exception_handler(401) async def unauthorized_handler(request: Request, exc: HTTPException): """Обработчик ошибки 401 - Не авторизован""" return templates.TemplateResponse("error.html", { "request": request, "error_code": 401, "error_title": "Требуется авторизация", "error_message": "Для доступа к этой странице необходимо войти в систему." }, status_code=401) @app.exception_handler(403) async def forbidden_handler(request: Request, exc: HTTPException): """Обработчик ошибки 403 - Доступ запрещен""" return templates.TemplateResponse("error.html", { "request": request, "error_code": 403, "error_title": "Доступ запрещен", "error_message": "У вас нет прав для доступа к этой странице." }, status_code=403) @app.exception_handler(500) async def internal_server_error_handler(request: Request, exc: HTTPException): """Обработчик ошибки 500 - Внутренняя ошибка сервера""" return templates.TemplateResponse("error.html", { "request": request, "error_code": 500, "error_title": "Внутренняя ошибка сервера", "error_message": "Произошла непредвиденная ошибка. Попробуйте обновить страницу или обратитесь к администратору." }, status_code=500) # Подключаем роутеры app.include_router(api_router) app.include_router(pages_router) if __name__ == "__main__": import uvicorn app_logger.info(f"LogBoard+ http://0.0.0.0:{APP_PORT}") app_logger.info(f"Debug mode: {'ON' if DEBUG_MODE else 'OFF'}") if DEBUG_MODE: app_logger.info("Swagger UI: http://0.0.0.0:{}/docs".format(APP_PORT)) app_logger.info("ReDoc: http://0.0.0.0:{}/redoc".format(APP_PORT)) uvicorn.run( app, host="0.0.0.0", port=APP_PORT, reload=DEBUG_MODE, log_level="debug" if DEBUG_MODE else "info" )