Skip to content

Commit 2294cb9

Browse files
committed
add loggers headlers
1 parent 45e1b5d commit 2294cb9

8 files changed

Lines changed: 175 additions & 2 deletions

File tree

api_v1/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
from .routers import register_routers
2+
from exeptions import ValidationError
23

3-
__all__ = ('register_routers',)
4+
5+
__all__ = ('register_routers',
6+
'ValidationError',
7+
)

api_v1/exeptions.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from starlette.exceptions import HTTPException
2+
3+
4+
class ValidationError(HTTPException):
5+
"""
6+
Исключение вызванное проблемами с валидацией
7+
"""
8+
9+
pass

app_includes/__init__.py

Whitespace-only changes.

app_includes/logs_errors.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import json
2+
from fastapi import FastAPI, Request
3+
from fastapi.exceptions import HTTPException
4+
from starlette.exceptions import HTTPException as StarletteHTTPException
5+
6+
from http import HTTPStatus
7+
8+
from logs.logging import logger
9+
from api_v1 import ValidationError
10+
11+
12+
def register_errors(app: FastAPI) -> None:
13+
@app.exception_handler(ValidationError)
14+
async def validation_error_handler(
15+
request: Request,
16+
exc: ValidationError,
17+
):
18+
"""
19+
Логирование всех ValidationError
20+
"""
21+
logger.opt(exception=True).warning(exc)
22+
response = dict(
23+
status=False,
24+
error_code=422,
25+
message=exc.detail,
26+
)
27+
json_response = json.dumps(response).encode(encoding='utf-8')
28+
return json_response
29+
30+
@app.exception_handler(HTTPException)
31+
async def http_error_handler(
32+
request: Request,
33+
exc: HTTPException,
34+
):
35+
"""
36+
Логирование всех HTTPException
37+
"""
38+
logger.opt(exception=True).warning(exc)
39+
response = dict(
40+
status=False,
41+
error_code=exc.status_code,
42+
message=exc.detail,
43+
)
44+
json_response = json.dumps(response).encode(encoding='utf-8')
45+
return json_response
46+
47+
@app.exception_handler(Exception)
48+
async def error_handler(
49+
request: Request,
50+
exc: Exception,
51+
):
52+
"""
53+
Логирование всех StarletteHTTPException
54+
"""
55+
logger.exception(exc)
56+
response = dict(
57+
status=False,
58+
error_code=exc.status_code,
59+
message=exc.detail,
60+
)
61+
json_response = json.dumps(response).encode(encoding='utf-8')
62+
return json_response
63+
64+
@app.exception_handler(ValidationError)
65+
async def validation_error_handler(
66+
request: Request,
67+
exc: ValidationError,
68+
):
69+
"""
70+
Логирование всех ValidationError
71+
"""
72+
logger.opt(exception=True).warning(exc)
73+
response = dict(
74+
status=False,
75+
error_code=500,
76+
message=HTTPStatus(500).phrase,
77+
)
78+
json_response = json.dumps(response).encode(encoding='utf-8')
79+
return json_response

config/config.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1+
from pathlib import Path
12
from pydantic_settings import BaseSettings, SettingsConfigDict
23
from pydantic import BaseModel
34
from starlette.config import Config
45

56

7+
base_dir = Path(__file__).resolve().parent.parent.parent
8+
log_dir = base_dir.joinpath('logs')
9+
10+
611
config = Config('.env')
712

813

@@ -47,6 +52,8 @@ class Settings(BaseSettings):
4752
rabbit: RabbitSettings = RabbitSettings()
4853
debug: bool = bool(int(config('DEBUG')))
4954
API_PREFIX: str = '/api/v1'
55+
BASE_DIR: Path = base_dir
56+
LOG_DIR: Path = log_dir
5057

5158

5259
settings = Settings()

logs/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
from .logging import create_log_dirs
2+
3+
4+
__all__ = ('create_log_dirs',)

logs/logging.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import sys
2+
from loguru import logger
3+
4+
from config import settings
5+
6+
7+
log_dir = settings.LOG_DIR
8+
9+
10+
def create_log_dirs() -> None:
11+
"""
12+
Создание корневой папки для логов
13+
"""
14+
log_directory = settings.LOG_DIR
15+
log_directory.mkdir(parents=True, exist_ok=True)
16+
17+
18+
logger.remove()
19+
20+
logger.add(
21+
log_dir.joinpath('access.log'),
22+
rotation='15MB',
23+
format='{time:YYYY-MM-DD HH:mm:ss} - {level} - {message}',
24+
encoding='utf-8',
25+
enqueue=True,
26+
level='DEBUG',
27+
diagnose=False,
28+
backtrace=False,
29+
colorize=False,
30+
filter=lambda record: record['level'].no < 40,
31+
)
32+
33+
logger.add(
34+
log_dir.joinpath('error.log'),
35+
rotation='15MB',
36+
format='{time:YYYY-MM-DD HH:mm:ss} - {level} - {message}',
37+
encoding='utf-8',
38+
enqueue=True,
39+
level='ERROR',
40+
diagnose=False,
41+
backtrace=False,
42+
colorize=False,
43+
)
44+
45+
logger.add(
46+
sink=sys.stderr,
47+
format='{time:YYYY-MM-DD HH:mm:ss} - {level} - {message}',
48+
enqueue=True,
49+
level='ERROR',
50+
diagnose=False,
51+
backtrace=False,
52+
colorize=False,
53+
)
54+
55+
logger.add(
56+
sink=sys.stdout,
57+
format='{time:YYYY-MM-DD HH:mm:ss} - {level} - {message}',
58+
enqueue=True,
59+
level='DEBUG',
60+
diagnose=False,
61+
backtrace=False,
62+
colorize=False,
63+
filter=lambda record: record['level'].no < 40,
64+
)

main.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
from contextlib import asynccontextmanager
22
from fastapi import FastAPI
3-
from config import db_connection, BaseModel
43

4+
from config import db_connection, BaseModel
55
from api_v1 import register_routers
6+
from logs import create_log_dirs
7+
68

79

810
def start_app() -> FastAPI:
11+
"""
12+
Создание приложения со всеми настройками
13+
"""
14+
create_log_dirs()
915
app = FastAPI(lifespan=lifespan)
1016
register_routers(app=app)
1117
return app

0 commit comments

Comments
 (0)