{"id":30111062,"url":"https://github.com/dantetemplar/fastapi-how-to-log","last_synced_at":"2025-10-25T13:47:50.144Z","repository":{"id":306816723,"uuid":"1027295849","full_name":"dantetemplar/fastapi-how-to-log","owner":"dantetemplar","description":"Way to improve logging for FastAPI projects.","archived":false,"fork":false,"pushed_at":"2025-07-27T19:00:12.000Z","size":39,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-27T20:54:12.819Z","etag":null,"topics":["fastapi","logging","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dantetemplar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-27T18:13:45.000Z","updated_at":"2025-07-27T20:00:18.000Z","dependencies_parsed_at":"2025-07-27T20:54:20.155Z","dependency_job_id":"aedd8198-2023-45a5-8580-8dbf07f91c71","html_url":"https://github.com/dantetemplar/fastapi-how-to-log","commit_stats":null,"previous_names":["dantetemplar/fastapi-how-to-log"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/dantetemplar/fastapi-how-to-log","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dantetemplar%2Ffastapi-how-to-log","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dantetemplar%2Ffastapi-how-to-log/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dantetemplar%2Ffastapi-how-to-log/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dantetemplar%2Ffastapi-how-to-log/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dantetemplar","download_url":"https://codeload.github.com/dantetemplar/fastapi-how-to-log/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dantetemplar%2Ffastapi-how-to-log/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269677801,"owners_count":24457876,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-10T02:00:08.965Z","response_time":71,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fastapi","logging","python"],"created_at":"2025-08-10T05:06:51.817Z","updated_at":"2025-10-25T13:47:45.104Z","avatar_url":"https://github.com/dantetemplar.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FastAPI Enhanced Logging\n\nA comprehensive logging solution for FastAPI applications that provides enhanced debugging capabilities, performance monitoring, and cleaner log output.\n\n## Features\n\n### 🔗 Clickable Source Code Links\n- **IDE Integration**: Log messages include clickable file paths that work in both PyCharm and VS Code\n- **Precise Location**: Shows exact line numbers where log messages originate\n- **Relative Paths**: Uses relative paths for cleaner output\n\nhttps://github.com/user-attachments/assets/1badb8a6-b525-405e-8e5f-e5585be2be37\n\n### 🧹 Clean Log Output\n- **Reduced Boilerplate**: Filters out verbose FastAPI and uvicorn logs\n- **HTTPX Filtering**: Suppresses noisy HTTP client library logs\n- **Error Focus**: Shows only your application's errors, not framework noise\n- **Stack Trace Cleanup**: Removes irrelevant framework stack\n\n\nhttps://github.com/user-attachments/assets/572d0217-c10d-4af8-b4d8-deeac88ceb54\n\n### ⏱️ Performance Monitoring\n- **Handler Timing**: Automatically measures and logs execution time for each endpoint handler\n\n\u003cimg width=\"864\" height=\"280\" alt=\"image\" src=\"https://github.com/user-attachments/assets/b8f3dbb0-77b8-4fcd-92cb-5bab1395f6c8\" /\u003e\n\n\u003ch3 id=\"exceptions\"\u003e🚨 Exception Handling \u0026 Logging\u003c/h3\u003e\n\n- **Validation Error Logging**: Automatically logs Pydantic validation errors with detailed context\n- **HTTP Exception Tracking**: Captures and logs HTTP exceptions with proper error details\n- **Human Readable Error Messages**: Returns clean error messages while maintaining comprehensive logging\n\n\u003cimg width=\"916\" height=\"378\" alt=\"image\" src=\"https://github.com/user-attachments/assets/e26e14e6-935e-4026-8a35-7dfe5d7fa25c\" /\u003e\n\n\n## Usage\n\nCopy the `logging_.py` module into your project and use it as follows:\n\n```python\nimport logging_  # noqa\nfrom logging_ import logger\n\nfrom fastapi import FastAPI, HTTPException\nfrom fastapi.exception_handlers import http_exception_handler\nfrom fastapi.exceptions import RequestValidationError\nfrom fastapi.requests import Request\nfrom fastapi.responses import PlainTextResponse\nfrom pydantic import ValidationError\nfrom starlette.exceptions import HTTPException as StarletteHTTPException\n\napp = FastAPI()\n\n@app.exception_handler(RequestValidationError)\nasync def validation_exception_handler(request: Request, exc: RequestValidationError):\n    as_validation_error = ValidationError.from_exception_data(\n        str(request.url.path),\n        line_errors=exc.errors(),\n    )\n    error_str = str(as_validation_error)\n    logger.warning(error_str, exc_info=False)\n    return PlainTextResponse(error_str, status_code=422)\n\n\n@app.exception_handler(StarletteHTTPException)\nasync def custom_http_exception_handler(request: Request, exc: StarletteHTTPException):\n    logger.warning(exc, exc_info=exc)\n    return await http_exception_handler(request, exc)\n\n@app.get(\"/\")\nasync def root():\n    logger.info(\"This will show with source code location and timing\")\n    return {\"message\": \"Hello World\"}\n\n@app.get(\"/error\")\nasync def error():\n    raise Exception(\"This is a test error\")\n```\n\n## Example Output\n\n```\n[2025-07-27 20:24:48,880] [INFO] [File \"app.py\", line 19] This will show with source code location and timing\n[2025-07-27 20:24:48,880] [INFO] [File \"app.py\", line 20] Handler `root` took 1 ms\n[2025-07-27 21:59:30,463] [INFO] [uvicorn.access] 127.0.0.1:59962 - \"GET /error HTTP/1.1\" 500\n[2025-07-27 21:59:30,464] [ERROR] [uvicorn.error] Exception in ASGI application\n\nTraceback (most recent call last):\n  File \"/home/dante/fastapi-how-to-log/app.py\", line 54, in error\n    raise Exception(\"This is a test error\")\nException: This is a test error\n```\n\nThe file path in the log message will be clickable ([File \"app.py\", line 19]) in your IDE, taking you directly to the source code.\n\n## Customization\n\nYou can modify the `dictConfig` in `logging_.py` to adjust:\n\n- Log levels for different components\n- Output formatting\n- Color schemes\n- Filtered paths and libraries\n\n## How It Works\n\n### Source Code Linking\nThe `RelativePathFilter` adds relative file paths to log records, making them clickable in IDEs.\n\n### Performance Monitoring\nThe `run_endpoint_function` is monkey-patched into FastAPI to automatically measure handler execution time.\n\n### Log Filtering\nThe `CleanErrorFilter` removes framework noise from stack traces and suppresses unwanted log sources.\n\n### Exception Handling\nThe custom exception handlers provide structured logging for validation errors and HTTP exceptions:\n\n- **Validation Errors**: Converts FastAPI's `RequestValidationError` to Pydantic's `ValidationError` format for human readable messages\n- **HTTP Exceptions**: Logs HTTP exceptions with full context while maintaining FastAPI's default error response behavior\n\n## ⚠️ Disclaimer\n\n**This solution uses some \"cursed\" techniques:**\n\n- **Monkey Patching**: Directly modifies FastAPI's internal `run_endpoint_function`\n- **Internal API Usage**: Relies on FastAPI's internal dependency injection system\n- **Framework Coupling**: Tightly coupled to specific FastAPI and Starlette versions\n\nWhile effective, these techniques may break with framework updates. Use at your own risk in production environments.\n\n## Requirements\n\n- Python 3.11+\n- FastAPI\n- colorlog\n- uvicorn (for ASGI server)\n\n## License\n\nMIT License - feel free to use and modify as needed.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdantetemplar%2Ffastapi-how-to-log","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdantetemplar%2Ffastapi-how-to-log","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdantetemplar%2Ffastapi-how-to-log/lists"}