前言FastAPI 服務(wù)是通過(guò) uvicorn 來(lái)提供的,日志都是 uvicorn 里配置的。 官方文檔地址:https://www./settings/#logging uvicorn 的 logging 日志我們可以通過(guò) uvicorn.run() 方式啟動(dòng)服務(wù) uvicorn.run("example:app", port=5000, reload=True, access_log=False) 于是可以加一些啟動(dòng)參數(shù),與logging 日志相關(guān)的幾個(gè)參數(shù): --log-config<path> 日志配置文件。 選項(xiàng):dictConfig()格式:.json、.yaml。任何其他格式都將使用fileConfig()處理。 設(shè)置formatters.default.use_colors和formatters.access.use_cors值以覆蓋自動(dòng)檢測(cè)的行為。 如果您希望在日志配置中使用YAML文件,則需要將PyYAML作為項(xiàng)目的依賴項(xiàng),或者安裝帶有[標(biāo)準(zhǔn)]可選附加功能的uvicorn。 --log-level<str> 置日志級(jí)別。 選項(xiàng):’critical’, 'error’, 'warning’, 'info’, 'debug’, 'trace’。默認(rèn)值:’info’。
--no-access-log 僅禁用訪問(wèn)日志,不更改日志級(jí)別。
--use-colors /--no-use-colorss -啟用/禁用日志記錄的彩色格式,如果未設(shè)置此選項(xiàng),則會(huì)自動(dòng)檢測(cè)到。如果使用--log-config CLI選項(xiàng),則會(huì)忽略此選項(xiàng)。
啟動(dòng)服務(wù)當(dāng)我們啟動(dòng)服務(wù),服務(wù)接口的時(shí)候,看到的日志是沒(méi)有顯示時(shí)間格式的 from fastapi import FastAPI app = FastAPI() @app.get("/demo/") async def create_item():
return {"demo": "hello world"}
if __name__ == "__main__": import uvicorn
uvicorn.run( app='main:app', host="127.0.0.1", reload=True, port=8000, )
運(yùn)行日志 INFO: Will watch for changes in these directories: ['D:\\code\\fast_project\\xxx'] INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) INFO: Started reloader process [10924] using StatReload INFO: Started server process [5708] INFO: Waiting for application startup. INFO: Application startup complete. INFO: 127.0.0.1:5161 - "GET / HTTP/1.1" 404 Not Found INFO: 127.0.0.1:5161 - "GET /docs HTTP/1.1" 200 OK INFO: 127.0.0.1:5161 - "GET /demo HTTP/1.1" 307 Temporary Redirect INFO: 127.0.0.1:5161 - "GET /demo/ HTTP/1.1" 200 OK
那么這些日志是從哪來(lái)的,又如何修改日志的默認(rèn)格式呢? LOGGING_CONFIG 日志默認(rèn)格式LOGGING_CONFIG 是uvicorn默認(rèn)的日志配置 from uvicorn.config import LOGGING_CONFIG 找到源碼里面的配置內(nèi)容如下 LOGGING_CONFIG: Dict[str, Any] = { "version": 1, "disable_existing_loggers": False, "formatters": { "default": { "()": "uvicorn.logging.DefaultFormatter", "fmt": "%(levelprefix)s %(message)s", "use_colors": None, }, "access": { "()": "uvicorn.logging.AccessFormatter", "fmt": '%(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s', # noqa: E501
}, }, "handlers": { "default": { "formatter": "default", "class": "logging.StreamHandler", "stream": "ext://sys.stderr",
}, "access": { "formatter": "access", "class": "logging.StreamHandler", "stream": "ext://sys.stdout",
}, }, "loggers": { "uvicorn": { "handlers": ["default"], "level": "INFO", "propagate": False }, "uvicorn.error": { "level": "INFO" }, "uvicorn.access": { "handlers": ["access"], "level": "INFO", "propagate": False },
}, }
我們可以通過(guò)修改”formatters”默認(rèn)的日志格式,來(lái)控制日志輸出的格式 from fastapi import FastAPI from uvicorn.config import LOGGING_CONFIG
LOGGING_CONFIG["formatters"]["default"]["fmt"] = "%(asctime)s - %(levelprefix)s %(message)s"
app = FastAPI()
······
于是就可以看到啟動(dòng)的日志,前面加上了時(shí)間”%(asctime)s” 2024-01-16 09:49:04,408 - INFO: Will watch for changes in these directories: ['D:\\code\\fast_project\\xxx'] 2024-01-16 09:49:04,408 - INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit) 2024-01-16 09:49:04,408 - INFO: Started reloader process [9124] using StatReload 2024-01-16 09:49:04,924 - INFO: Started server process [11020] 2024-01-16 09:49:04,924 - INFO: Waiting for application startup. 2024-01-16 09:49:04,924 - INFO: Application startup complete.
訪問(wèn) http 接口的日志通過(guò)修改”access”格式來(lái)控制 from fastapi import FastAPIfrom uvicorn.config import LOGGING_CONFIGLOGGING_CONFIG["formatters"]["default"]["fmt"] = "%(asctime)s - %(levelprefix)s %(message)s"LOGGING_CONFIG["formatters"]["access"]["fmt"] = "%(asctime)s - %(levelprefix)s %(client_addr)s - \"%(request_line)s\" %(status_code)s"app = FastAPI() log_config 配置文件前面是通過(guò)修改LOGGING_CONFIG 默認(rèn)的參數(shù)來(lái)配置日志,我們也可以把配置文件單獨(dú)寫到一個(gè)uvicorn_config.json文件,加載本地配置文件覆蓋默認(rèn)的LOGGING_CONFIG uvicorn_config.json 啟動(dòng)時(shí)導(dǎo)入配置文件 from fastapi import FastAPI
app = FastAPI() @app.get("/demo/") async def create_item():
return {"demo": "hello world"}
if __name__ == "__main__": import uvicorn
uvicorn.run( app='main:app', host="127.0.0.1", reload=True, port=8000, log_config="./uvicorn_config.json" )
|