From ee7123f38219c99f37c21e92b8cb96e014748b16 Mon Sep 17 00:00:00 2001 From: Stas Medvedev Date: Tue, 11 Jun 2024 01:24:14 +0300 Subject: utils.py, logging.py, log_config.json --- .vscode/launch.json | 2 +- app/logging.py | 9 +++++++++ app/main.py | 36 ++++++--------------------------- app/utils.py | 31 +++++++++++++++++++++++++++++ log_config.json | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++ static/request.log | 1 + 6 files changed, 105 insertions(+), 31 deletions(-) create mode 100644 app/logging.py create mode 100644 app/utils.py create mode 100644 log_config.json create mode 100644 static/request.log diff --git a/.vscode/launch.json b/.vscode/launch.json index f85c840..a24f6a9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,7 +9,7 @@ "type": "debugpy", "request": "launch", "module": "uvicorn", - "args": ["app.main:app", "--host", "0.0.0.0"], + "args": ["app.main:app", "--host", "0.0.0.0", "--log-config", "./log_config.json"], "console": "integratedTerminal" } ] diff --git a/app/logging.py b/app/logging.py new file mode 100644 index 0000000..e24328d --- /dev/null +++ b/app/logging.py @@ -0,0 +1,9 @@ +import logging + + +class RequestFileHandler(logging.FileHandler): + def __init__(self) -> None: + super().__init__('./static/request.log') + + +logger = logging.getLogger('app.request') diff --git a/app/main.py b/app/main.py index 891adb1..d643447 100644 --- a/app/main.py +++ b/app/main.py @@ -1,10 +1,10 @@ -from pathlib import Path - from fastapi import FastAPI, Request from fastapi.responses import HTMLResponse from fastapi.staticfiles import StaticFiles from starlette.templating import Jinja2Templates -import httpx + +from app.utils import get_avatar_urls, get_client_geo, get_client_host +from app.logging import logger templates = Jinja2Templates(directory="templates") @@ -12,35 +12,11 @@ app = FastAPI() app.mount("/static", StaticFiles(directory="static"), name="static") -def get_avatar_urls(): - path = Path('./static') / 'avatars' - if not path.exists(): - path.mkdir() - - return sorted([ - str(jpg_avatar) - for jpg_avatar - in path.glob('*.jpg') - ]) - - -def get_client_host(request: Request): - return request.client.host - - -async def get_client_geo(client_host: str): - async with httpx.AsyncClient() as client: - response = await client.get( - # использование https платная опция сервиса, инфо тут https://members.ip-api.com/ - url='http://ip-api.com/json/{}'.format(client_host), - params={"lang": "ru"} - ) - data = response.json() - return data - - @app.get("/", response_class=HTMLResponse) async def index(request: Request): + + logger.info(str(dict(request.headers))) + return templates.TemplateResponse( "index.html", { diff --git a/app/utils.py b/app/utils.py new file mode 100644 index 0000000..08373e0 --- /dev/null +++ b/app/utils.py @@ -0,0 +1,31 @@ +from pathlib import Path +from fastapi import Request +import httpx + + +def get_avatar_urls(): + path = Path('./static') / 'avatars' + if not path.exists(): + path.mkdir() + + return sorted([ + str(jpg_avatar) + for jpg_avatar + in path.glob('*.jpg') + ]) + + +def get_client_host(request: Request): + return request.client.host + + +async def get_client_geo(client_host: str): + async with httpx.AsyncClient() as client: + response = await client.get( + # использование https платная опция сервиса, инфо тут https://members.ip-api.com/ + url='http://ip-api.com/json/{}'.format(client_host), + params={"lang": "ru"} + ) + data = response.json() + return data + diff --git a/log_config.json b/log_config.json new file mode 100644 index 0000000..e7b8f08 --- /dev/null +++ b/log_config.json @@ -0,0 +1,57 @@ +{ + "version": 1, + "disable_existing_loggers": false, + "formatters": { + "default": { + "()": "uvicorn.logging.DefaultFormatter", + "fmt": "%(levelprefix)s %(message)s", + "use_colors": null + }, + "access": { + "()": "uvicorn.logging.AccessFormatter", + "fmt": "%(levelprefix)s %(client_addr)s - \"%(request_line)s\" %(status_code)s" + } + }, + "handlers": { + "default": { + "formatter": "default", + "class": "logging.StreamHandler", + "stream": "ext://sys.stderr" + }, + "access": { + "formatter": "access", + "class": "logging.StreamHandler", + "stream": "ext://sys.stdout" + }, + "request": { + "formatter": "default", + "class": "app.logging.RequestFileHandler" + } + }, + "loggers": { + "uvicorn": { + "handlers": [ + "default" + ], + "level": "INFO", + "propagate": false + }, + "uvicorn.error": { + "level": "INFO" + }, + "uvicorn.access": { + "handlers": [ + "access" + ], + "level": "INFO", + "propagate": false + }, + "app.request": { + "handlers": [ + "request" + ], + "level": "INFO", + "propagate": false + } + } +} \ No newline at end of file diff --git a/static/request.log b/static/request.log new file mode 100644 index 0000000..4169222 --- /dev/null +++ b/static/request.log @@ -0,0 +1 @@ +INFO: {'host': 'localhost:8000', 'connection': 'keep-alive', 'sec-ch-ua': '"Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"', 'sec-ch-ua-mobile': '?0', 'sec-ch-ua-platform': '"Linux"', 'upgrade-insecure-requests': '1', 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36', 'sec-purpose': 'prefetch;prerender', 'purpose': 'prefetch', 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7', 'sec-fetch-site': 'none', 'sec-fetch-mode': 'navigate', 'sec-fetch-user': '?1', 'sec-fetch-dest': 'document', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9'} -- cgit v1.2.3