API: Add request logging
Log all the parts of a request if the config flag is set. The logged fields are all server side anyways, so nothing is being exposed to clients. Signed-off-by: kingbri <bdashore3@proton.me>
This commit is contained in:
parent
522999ebb4
commit
3826815edb
4 changed files with 61 additions and 28 deletions
|
|
@ -51,10 +51,7 @@ def from_args(args: dict):
|
||||||
cur_logging_config = logging_config()
|
cur_logging_config = logging_config()
|
||||||
GLOBAL_CONFIG["logging"] = {
|
GLOBAL_CONFIG["logging"] = {
|
||||||
**cur_logging_config,
|
**cur_logging_config,
|
||||||
**{
|
**{k.replace("log_", ""): logging_override[k] for k in logging_override},
|
||||||
k.replace("log_", ""): logging_override[k]
|
|
||||||
for k in logging_override
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
developer_override = args.get("developer")
|
developer_override = args.get("developer")
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
"""Common utility functions"""
|
"""Common utility functions"""
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import json
|
||||||
import socket
|
import socket
|
||||||
import traceback
|
import traceback
|
||||||
from fastapi import HTTPException, Request
|
from fastapi import Depends, HTTPException, Request
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
@ -108,3 +109,32 @@ async def add_request_id(request: Request):
|
||||||
|
|
||||||
request.state.id = uuid4().hex
|
request.state.id = uuid4().hex
|
||||||
return request
|
return request
|
||||||
|
|
||||||
|
|
||||||
|
async def log_request(request: Request):
|
||||||
|
"""FastAPI depends to log a request to the user."""
|
||||||
|
|
||||||
|
log_message = [f"Information for {request.method} request {request.state.id}:"]
|
||||||
|
|
||||||
|
log_message.append(f"URL: {request.url}")
|
||||||
|
log_message.append(f"Headers: {dict(request.headers)}")
|
||||||
|
|
||||||
|
if request.method != "GET":
|
||||||
|
body_bytes = await request.body()
|
||||||
|
if body_bytes:
|
||||||
|
body = json.loads(body_bytes.decode("utf-8"))
|
||||||
|
|
||||||
|
log_message.append(f"Body: {dict(body)}")
|
||||||
|
|
||||||
|
logger.info("\n".join(log_message))
|
||||||
|
|
||||||
|
|
||||||
|
def get_global_depends():
|
||||||
|
"""Returns global dependencies for a FastAPI app."""
|
||||||
|
|
||||||
|
depends = [Depends(add_request_id)]
|
||||||
|
|
||||||
|
if config.logging_config().get("requests"):
|
||||||
|
depends.append(Depends(log_request))
|
||||||
|
|
||||||
|
return depends
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,10 @@ logging:
|
||||||
# Enable generation parameter logging (default: False)
|
# Enable generation parameter logging (default: False)
|
||||||
generation_params: False
|
generation_params: False
|
||||||
|
|
||||||
|
# Enable request logging (default: False)
|
||||||
|
# NOTE: Only use this for debugging!
|
||||||
|
requests: False
|
||||||
|
|
||||||
# Options for sampling
|
# Options for sampling
|
||||||
sampling:
|
sampling:
|
||||||
# Override preset name. Find this in the sampler-overrides folder (default: None)
|
# Override preset name. Find this in the sampler-overrides folder (default: None)
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,44 @@
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from fastapi import Depends, FastAPI
|
from fastapi import FastAPI
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
|
|
||||||
from common.logger import UVICORN_LOG_CONFIG
|
from common.logger import UVICORN_LOG_CONFIG
|
||||||
from common.networking import add_request_id
|
from common.networking import get_global_depends
|
||||||
from endpoints.OAI.router import router as OAIRouter
|
from endpoints.OAI.router import router as OAIRouter
|
||||||
|
|
||||||
app = FastAPI(
|
|
||||||
title="TabbyAPI",
|
|
||||||
summary="An OAI compatible exllamav2 API that's both lightweight and fast",
|
|
||||||
description=(
|
|
||||||
"This docs page is not meant to send requests! Please use a service "
|
|
||||||
"like Postman or a frontend UI."
|
|
||||||
),
|
|
||||||
dependencies=[Depends(add_request_id)],
|
|
||||||
)
|
|
||||||
|
|
||||||
# ALlow CORS requests
|
|
||||||
app.add_middleware(
|
|
||||||
CORSMiddleware,
|
|
||||||
allow_origins=["*"],
|
|
||||||
allow_credentials=True,
|
|
||||||
allow_methods=["*"],
|
|
||||||
allow_headers=["*"],
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def setup_app():
|
def setup_app():
|
||||||
"""Includes the correct routers for startup"""
|
"""Includes the correct routers for startup"""
|
||||||
|
|
||||||
|
app = FastAPI(
|
||||||
|
title="TabbyAPI",
|
||||||
|
summary="An OAI compatible exllamav2 API that's both lightweight and fast",
|
||||||
|
description=(
|
||||||
|
"This docs page is not meant to send requests! Please use a service "
|
||||||
|
"like Postman or a frontend UI."
|
||||||
|
),
|
||||||
|
dependencies=get_global_depends(),
|
||||||
|
)
|
||||||
|
|
||||||
|
# ALlow CORS requests
|
||||||
|
app.add_middleware(
|
||||||
|
CORSMiddleware,
|
||||||
|
allow_origins=["*"],
|
||||||
|
allow_credentials=True,
|
||||||
|
allow_methods=["*"],
|
||||||
|
allow_headers=["*"],
|
||||||
|
)
|
||||||
|
|
||||||
app.include_router(OAIRouter)
|
app.include_router(OAIRouter)
|
||||||
|
|
||||||
|
return app
|
||||||
|
|
||||||
|
|
||||||
def export_openapi():
|
def export_openapi():
|
||||||
"""Function to return the OpenAPI JSON from the API server"""
|
"""Function to return the OpenAPI JSON from the API server"""
|
||||||
|
|
||||||
setup_app()
|
app = setup_app()
|
||||||
return app.openapi()
|
return app.openapi()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -49,7 +51,7 @@ async def start_api(host: str, port: int):
|
||||||
logger.info(f"Chat completions: http://{host}:{port}/v1/chat/completions")
|
logger.info(f"Chat completions: http://{host}:{port}/v1/chat/completions")
|
||||||
|
|
||||||
# Setup app
|
# Setup app
|
||||||
setup_app()
|
app = setup_app()
|
||||||
|
|
||||||
config = uvicorn.Config(
|
config = uvicorn.Config(
|
||||||
app,
|
app,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue