2

我正在寻找Fast API中的中间件,用于为每个请求生成UUID并将其发送到logs

# To see the logs, run this in python interpreter
# import with_logger
# with_logger.main()

import uuid
from logging import getLogger
import logging.config
from yaml import load, FullLoader
from fastapi import FastAPI
import uvicorn

app = FastAPI()


# @app.middleware("http")
@app.get("/")
def gen_uuid():
    # For every get request generate uuid
    global uuid_var
    uuid_var = uuid.uuid4()
    return uuid_var


log_dict = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': '%(uuid_var)s %(asctime)s %(levelname)-8s %(name)-15s %(message)s -Thread id: %(thread)d  Thread name: %(threadName)s'
        },
    },
    'handlers': {
        'default': {
            'level': 'INFO',
            'formatter': 'standard',
            'class': 'logging.StreamHandler',
        },
        'file_handler': {
            'level': 'INFO',
            'filename': 'mylogfile.log',
            'class': 'logging.FileHandler',
            'formatter': 'standard'
        }
    },
    'loggers': {
        '': {
            'handlers': ['file_handler'],
            'level': 'INFO',
            'propagate': True
        },
    }
}


class ContextFilter(logging.Filter):
    def filter(self, record):
        record.uuid_var = gen_uuid()
        return True


def main():
    logging.config.dictConfig(log_dict)

    handler = logging.StreamHandler()
    handler.formatter = logging.Formatter(
        "%(uuid_var)s %(asctime)s %(levelname)-8s %(name)-15s %(message)s -Thread id: %(thread)d  Thread name: %(threadName)s")
    handler.addFilter(ContextFilter())
    logger = getLogger(__name__)
    logger.addHandler(handler)

    logger.warning(" This is a warning message")

    uvicorn.run(app, host="127.0.0.1", port=8080)

我需要将 uuid 发送到 X-Request-ID 标头,我将使用 python 日志库从那里获取它,例如,

@app.middleware("http")
async def get_x_request_id_header(*, x_request_id: str = Header(None)):
    # return x-request-id header
    return {"X-Request-ID": x_request_id}

我需要一个中间件中的所有这些。Fast API 中是否已经存在类似的中间件?

我需要在中间件中生成 uuid,例如,

@app.middleware("http")
def gen_uuid():
    # For every get request generate uuid
    global uuid_var
    uuid_var = uuid.uuid4()
    return uuid_var

但无法做到这一点。我收到错误,例如 gen_uuid 接受 2 个参数但传递 0 个参数

4

2 回答 2

1

中间件需要两个参数:request:Request,call_next request是api请求,call_next是处理请求的实际调用 像这样:

    @app.middleware("http")
async def init_requestvars(request: fastapi.Request, call_next):
    # Customize that SimpleNamespace with hatever you need
    initial_g = types.SimpleNamespace()
    requestvars.request_global.set(initial_g)
    response = await call_next(request)
    return response
于 2020-10-19T18:03:09.203 回答
1

我刚刚为此实现了一个中间件。希望它对您(或将来遇到此问题的任何人)仍然有用。

这是回购:https ://github.com/snok/asgi-correlation-id

于 2021-11-01T22:57:22.367 回答