Package: beans-logging-fastapi
beans_logging_fastapibeans_logging_fastapiis a middleware for FastAPI to log HTTP access.It is based on'beans-logging'package.FeaturesLoggerbased on'beans-logging'packageFastAPIHTTP access loggingmiddlewareInstallation1. PrerequisitesPython (>= v3.8)PyPi (>= v23)2. Install beans-logging-fastapi packageChoose one of the following methods to install the package[A ~ F]:A.[RECOMMENDED] Install fromPyPi# Install or upgrade package:pipinstall-Ubeans-logging-fastapiB.Install latest version fromGitHub# Install package by git:pipinstallgit+https://github.com/bybatkhuu/module.fastapi-logging.gitC.Install frompre-built releasefilesDownload.whlor.tar.gzfile fromreleases-https://github.com/bybatkhuu/module.fastapi-logging/releasesInstall with pip:# Install from .whl file:pipinstall./beans_logging_fastapi-[VERSION]-py3-none-any.whl# Or install from .tar.gz file:pipinstall./beans_logging_fastapi-[VERSION].tar.gzD.Install fromsource codeby building package# Clone repository by git:gitclonehttps://github.com/bybatkhuu/module.fastapi-logging.gitbeans_logging_fastapicd./beans_logging_fastapi# Install python build tool:pipinstall-Upipbuild# Build python package:python-mbuild_VERSION=$(./scripts/get-version.sh)# Install from .whl file:pipinstall./dist/beans_logging_fastapi-${_VERSION}-py3-none-any.whl# Or install from .tar.gz file:pipinstall./dist/beans_logging_fastapi-${_VERSION}.tar.gzE.Install with pip editabledevelopment mode(from source code)# Clone repository by git:gitclonehttps://github.com/bybatkhuu/module.fastapi-logging.gitbeans_logging_fastapicd./beans_logging_fastapi# Install with editable development mode:pipinstall-e.F.Manually add toPYTHONPATH(not recommended)# Clone repository by git:gitclonehttps://github.com/bybatkhuu/module.fastapi-logging.gitbeans_logging_fastapicd./beans_logging_fastapi# Install python dependencies:pipinstall-r./requirements.txt# Add current path to PYTHONPATH:exportPYTHONPATH="${PWD}:${PYTHONPATH}"Usage/ExamplesTo usebeans_logging_fastapi:FastAPIconfigs/logger.yml:logger:app_name:"fastapi-app"level:"TRACE"use_diagnose:falsestream:use_color:trueuse_icon:falseformat_str:"[<c>{time:YYYY-MM-DDHH:mm:ss.SSSZ}</c>|<level>{level_short:<5}</level>|<w>{name}:{line}</w>]:<level>{message}</level>"std_handler:enabled:truefile:logs_dir:"./logs"rotate_size:10000000# 10MBrotate_time:"00:00:00"backup_count:90log_handlers:enabled:trueformat_str:"[{time:YYYY-MM-DDHH:mm:ss.SSSZ}|{level_short:<5}|{name}:{line}]:{message}"log_path:"{app_name}.std.all.log"err_path:"{app_name}.std.err.log"json_handlers:enabled:trueuse_custom:falselog_path:"json/{app_name}.json.all.log"err_path:"json/{app_name}.json.err.log"intercept:auto_load:enabled:trueonly_base:falseignore_modules:[]include_modules:[]mute_modules:["uvicorn.access"]extra:http_std_debug_format:'<n>[{request_id}]</n>{client_host}{user_id}"<u>{method}{url_path}</u>HTTP/{http_version}"'http_std_msg_format:'<n><w>[{request_id}]</w></n>{client_host}{user_id}"<u>{method}{url_path}</u>HTTP/{http_version}"{status_code}{content_length}B{response_time}ms'http_file_enabled:truehttp_file_format:'{client_host}{request_id}{user_id}[{datetime}]"{method}{url_path}HTTP/{http_version}"{status_code}{content_length}"{h_referer}""{h_user_agent}"{response_time}'http_file_tz:"localtime"http_log_path:"http/{app_name}.http.access.log"http_err_path:"http/{app_name}.http.err.log"http_json_enabled:truehttp_json_path:"json.http/{app_name}.json.http.access.log"http_json_err_path:"json.http/{app_name}.json.http.err.log".env:ENV=developmentDEBUG=trueBEANS_LOGGING_DISABLE_DEFAULT=falseBEANS_LOGGING_CONFIG_PATH="./configs/logger.yml"BEANS_LOGGING_LOGS_DIR="./logs"logger.py:frombeans_loggingimportLogger,LoggerLoaderfrombeans_logging_fastapiimport(add_http_file_handler,add_http_file_json_handler,http_file_format,)logger_loader=LoggerLoader()logger:Logger=logger_loader.load()def_http_file_format(record:dict)->str:_format=http_file_format(record=record,msg_format=logger_loader.config.extra.http_file_format,tz=logger_loader.config.extra.http_file_tz,)return_formatiflogger_loader.config.extra.http_file_enabled:add_http_file_handler(logger_loader=logger_loader,log_path=logger_loader.config.extra.http_log_path,err_path=logger_loader.config.extra.http_err_path,formatter=_http_file_format,)iflogger_loader.config.extra.http_json_enabled:add_http_file_json_handler(logger_loader=logger_loader,log_path=logger_loader.config.extra.http_json_path,err_path=logger_loader.config.extra.http_json_err_path,)main.py:fromtypingimportUnionfromcontextlibimportasynccontextmanagerimportuvicornfromdotenvimportload_dotenvfromfastapiimportFastAPI,HTTPExceptionfromfastapi.responsesimportRedirectResponseload_dotenv()frombeans_logging_fastapiimport(HttpAccessLogMiddleware,RequestHTTPInfoMiddleware,ResponseHTTPInfoMiddleware,)fromloggerimportlogger,logger_loaderfrom__version__import__version__@asynccontextmanagerasyncdeflifespan(app:FastAPI):logger.info("Preparing to startup...")logger.success("Finished preparation to startup.")logger.info(f"API version:{__version__}")yieldlogger.info("Praparing to shutdown...")logger.success("Finished preparation to shutdown.")app=FastAPI(lifespan=lifespan,version=__version__)app.add_middleware(ResponseHTTPInfoMiddleware)app.add_middleware(HttpAccessLogMiddleware,debug_format=logger_loader.config.extra.http_std_debug_format,msg_format=logger_loader.config.extra.http_std_msg_format,)app.add_middleware(RequestHTTPInfoMiddleware,has_proxy_headers=True,has_cf_headers=True)@app.get("/")defroot():return{"Hello":"World"}@app.get("/items/{item_id}")defread_item(item_id:int,q:Union[str,None]=None):return{"item_id":item_id,"q":q}@app.get("/continue",status_code=100)defget_continue():return{}@app.get("/redirect")defredirect():returnRedirectResponse("/")@app.get("/error")deferror():raiseHTTPException(status_code=500)if__name__=="__main__":uvicorn.run(app="main:app",host="0.0.0.0",port=8000,access_log=False,server_header=False,proxy_headers=True,forwarded_allow_ips="*",)Run theexamples:cd./examples# Install python dependencies for examples:pipinstall-r./requirements.txt

uvicornmain:app--host=0.0.0.0--port=8000Output:[2023-10-31 12:38:46.733 +09:00 | TRACE | beans_logging._base:578]: Intercepted modules: ['concurrent', 'concurrent.futures', 'watchfiles.watcher', 'dotenv.main', 'watchfiles.main', 'watchfiles', 'asyncio', 'fastapi', 'uvicorn.error', 'uvicorn', 'dotenv']; Muted modules: ['uvicorn.access'];
[2023-10-31 12:38:46.749 +09:00 | INFO  | uvicorn.server:76]: Started server process [56216]
[2023-10-31 12:38:46.749 +09:00 | INFO  | uvicorn.lifespan.on:46]: Waiting for application startup.
[2023-10-31 12:38:46.750 +09:00 | INFO  | main:26]: Preparing to startup...
[2023-10-31 12:38:46.750 +09:00 | OK    | main:27]: Finished preparation to startup.
[2023-10-31 12:38:46.750 +09:00 | INFO  | main:28]: API version: 0.0.0-000000
[2023-10-31 12:38:46.750 +09:00 | INFO  | uvicorn.lifespan.on:60]: Application startup complete.
[2023-10-31 12:38:46.752 +09:00 | INFO  | uvicorn.server:218]: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
[2023-10-31 12:38:48.701 +09:00 | DEBUG | anyio._backends._asyncio:807]: [c3d76377250947c29559cb103a6d2c56] 127.0.0.1 - "GET / HTTP/1.1"
[2023-10-31 12:38:48.703 +09:00 | OK    | anyio._backends._asyncio:807]: [c3d76377250947c29559cb103a6d2c56] 127.0.0.1 - "GET / HTTP/1.1" 200 17B 0.8ms
^C[2023-10-31 12:38:49.793 +09:00 | INFO  | uvicorn.server:264]: Shutting down
[2023-10-31 12:38:49.903 +09:00 | INFO  | uvicorn.lifespan.on:65]: Waiting for application shutdown.
[2023-10-31 12:38:49.903 +09:00 | INFO  | main:31]: Praparing to shutdown...
[2023-10-31 12:38:49.904 +09:00 | OK    | main:32]: Finished preparation to shutdown.
[2023-10-31 12:38:49.904 +09:00 | INFO  | uvicorn.lifespan.on:76]: Application shutdown complete.
[2023-10-31 12:38:49.904 +09:00 | INFO  | uvicorn.server:86]: Finished server process [56216]Running TestsTo run tests, run the following command:# Install python test dependencies:pipinstall-r./requirements.test.txt# Run tests:python-mpytest-svEnvironment VariablesYou can use the following environment variables inside.env.examplefile:ENV=developmentDEBUG=trueBEANS_LOGGING_DISABLE_DEFAULT=falseBEANS_LOGGING_CONFIG_PATH="./configs/logger.yml"BEANS_LOGGING_LOGS_DIR="./logs"DocumentationdocsscriptsReferenceshttps://github.com/bybatkhuu/module.python-logginghttps://github.com/Delgan/loguruhttps://loguru.readthedocs.io/en/stable/api/logger.htmlhttps://loguru.readthedocs.io/en/stable/resources/recipes.html