wip: uvicorn logging conf to json

This commit is contained in:
Jakub Miazek 2024-08-17 10:45:51 +02:00
parent a58e98c4b1
commit 6f0b097d2d
9 changed files with 166 additions and 57 deletions

View File

@ -21,6 +21,7 @@ async def create_multi_stuff(
db_session.add_all(stuff_instances) db_session.add_all(stuff_instances)
await db_session.commit() await db_session.commit()
except SQLAlchemyError as ex: except SQLAlchemyError as ex:
logger.error(f"Error inserting instances of Stuff: {repr(ex)}")
raise HTTPException( raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=repr(ex) status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=repr(ex)
) from ex ) from ex

View File

@ -5,6 +5,9 @@ from fastapi import HTTPException, status
from sqlalchemy.exc import SQLAlchemyError, IntegrityError from sqlalchemy.exc import SQLAlchemyError, IntegrityError
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import declared_attr, DeclarativeBase from sqlalchemy.orm import declared_attr, DeclarativeBase
from app.utils.logging import AppLogger
logger = AppLogger().get_logger()
class Base(DeclarativeBase): class Base(DeclarativeBase):
@ -26,6 +29,7 @@ class Base(DeclarativeBase):
db_session.add(self) db_session.add(self)
return await db_session.commit() return await db_session.commit()
except SQLAlchemyError as ex: except SQLAlchemyError as ex:
logger.error(f"Error inserting instance of {self}: {repr(ex)}")
raise HTTPException( raise HTTPException(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=repr(ex) status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail=repr(ex)
) from ex ) from ex

View File

@ -20,5 +20,5 @@ class AppLogger(metaclass=SingletonMeta):
class RichConsoleHandler(RichHandler): class RichConsoleHandler(RichHandler):
def __init__(self, width=200, style=None, **kwargs): def __init__(self, width=200, style=None, **kwargs):
super().__init__( super().__init__(
console=Console(color_system="256", width=width, style=style), **kwargs console=Console(color_system="256", width=width, style=style, stderr=True), **kwargs
) )

View File

@ -7,7 +7,7 @@ services:
- .secrets - .secrets
command: bash -c " command: bash -c "
uvicorn app.main:app uvicorn app.main:app
--log-config ./config.ini --log-config ./uvicorn-logging.json
--host 0.0.0.0 --port 8080 --host 0.0.0.0 --port 8080
--lifespan=on --use-colors --loop uvloop --http httptools --lifespan=on --use-colors --loop uvloop --http httptools
--reload --log-level debug --reload --log-level debug

View File

@ -27,20 +27,20 @@ qualname = uvicorn.access
[handler_stream] [handler_stream]
class = app.utils.logging.RichConsoleHandler class = app.utils.logging.RichConsoleHandler
kwargs = {"omit_repeated_times":True, "show_time": False, "enable_link_path": False, "tracebacks_show_locals": True, "rich_tracebacks": True} kwargs = {"omit_repeated_times":True, "show_time": False, "enable_link_path": False, "tracebacks_show_locals": True, "rich_tracebacks": True}
args = (100, "white") args = (140, "white")
formatter = default formatter = default
stream = ext://sys.stdout stream = ext://sys.stdout
[handler_sqlalchemy] [handler_sqlalchemy]
class = app.utils.logging.RichConsoleHandler class = app.utils.logging.RichConsoleHandler
kwargs = {"omit_repeated_times":True, "show_time": False, "enable_link_path": False, "tracebacks_show_locals": True, "rich_tracebacks": True} kwargs = {"omit_repeated_times":True, "show_time": False, "enable_link_path": False, "tracebacks_show_locals": True, "rich_tracebacks": True}
args = (100, "magenta") args = (140, "magenta")
formatter = default formatter = default
[handler_uvicorn] [handler_uvicorn]
class = app.utils.logging.RichConsoleHandler class = app.utils.logging.RichConsoleHandler
kwargs = {"omit_repeated_times":True, "show_time": False, "enable_link_path": False, "tracebacks_show_locals": True, "rich_tracebacks": True} kwargs = {"omit_repeated_times":True, "show_time": False, "enable_link_path": False, "tracebacks_show_locals": True, "rich_tracebacks": True}
args = (100, "yellow") args = (140, "yellow")
formatter = default formatter = default
[formatter_default] [formatter_default]

View File

@ -5,7 +5,7 @@ services:
env_file: env_file:
- .env - .env
- .secrets - .secrets
command: granian --interface asgi --host 0.0.0.0 --port 8080 --loop uvloop app.main:app --log-level debug command: granian --interface asgi --host 0.0.0.0 --port 8080 --loop uvloop app.main:app --log-level debug --log-config ./logging-config.json
volumes: volumes:
- .:/home/code - .:/home/code
ports: ports:

View File

@ -2,54 +2,55 @@
"version": 1, "version": 1,
"disable_existing_loggers": false, "disable_existing_loggers": false,
"formatters": { "formatters": {
"default": { "generic": {
"format": "[%(process)d|%(name)-12s] %(message)s", "()": "logging.Formatter",
"class": "logging.Formatter" "fmt": "[%(process)d|%(name)-12s] %(message)s",
"datefmt": "[%Y-%m-%d %H:%M:%S %z]"
},
"access": {
"()": "logging.Formatter",
"fmt": "[%(process)d|%(name)-12s] %(message)s",
"datefmt": "[%Y-%m-%d %H:%M:%S %z]"
} }
}, },
"handlers": { "handlers": {
"console": { "console": {
"class": "app.utils.logging.RichConsoleHandler", "formatter": "generic",
"level": "DEBUG", "class": "logging.StreamHandler",
"formatter": "default", "stream": "ext://sys.stdout"
"stream": "ext://sys.stdout", },
"kwargs": {"omit_repeated_times": "True", "show_time": "False", "enable_link_path": "False", "tracebacks_show_locals": "True", "rich_tracebacks": "True"}, "access": {
"args": "(100, 'white')" "formatter": "access",
"class": "logging.StreamHandler",
"stream": "ext://sys.stdout"
}, },
"sqlalchemy": { "sqlalchemy": {
// "class": "logging.handlers.TimedRotatingFileHandler", "class": "app.utils.logging.RichConsoleHandler",
// "level": "DEBUG", "formatter": "generic"
// "formatter": "verbose",
// "when": "D",
// "backupCount": 0,
// "filename": "./logs/training-stats.log"
},
"granian": {
// "class": "logging.handlers.TimedRotatingFileHandler",
// "level": "DEBUG",
// "formatter": "verbose",
// "when": "D",
// "backupCount": 0,
// "filename": "./logs/uvicorn.log"
} }
}, },
"loggers": { "loggers": {
"root": { "_granian": {
// "level": "DEBUG", "handlers": [
// "handlers": ["console"] "console"
}, ],
"sqlalchemy.engine.Engine": { "level": "INFO",
// "level": "DEBUG", "propagate": false
// "handlers": ["file"],
// "propagate": true,
// "qualname": "app"
}, },
"granian.access": { "granian.access": {
// "level": "DEBUG", "handlers": [
// "handlers": ["uvicorn"], "access"
// "propagate": true, ],
// "qualname": "uvicorn" "level": "INFO",
"propagate": false
},
"sqlalchemy.engine.Engine": {
"handlers": [
"sqlalchemy"
],
"level": "ERROR",
"propagate": true,
"qualname": "sqlalchemy.engine.Engine"
} }
} }
} }

52
uvicorn-logging-old.json Normal file
View File

@ -0,0 +1,52 @@
{
"version": 1,
"disable_existing_loggers": false,
"formatters": {
"default": {
"()": "logging.Formatter",
"fmt": "[%(process)d|%(name)-12s] %(message)s"
}
},
"handlers": {
"stream": {
"formatter": "default",
"class": "app.utils.logging.RichConsoleHandler",
"stream": "ext://sys.stdout"
},
"uvicorn": {
"formatter": "default",
"class": "app.utils.logging.RichConsoleHandler",
"stream": "ext://sys.stdout"
},
"sqlalchemy": {
"formatter": "default",
"class": "app.utils.logging.RichConsoleHandler"
}
},
"loggers": {
"root": {
"handlers": [
"stream"
],
"level": "INFO",
"propagate": false
},
"uvicorn.access": {
"handlers": [
"uvicorn"
],
"level": "INFO",
"propagate": false
},
"sqlalchemy.engine.Engine": {
"handlers": [
"sqlalchemy"
],
"level": "ERROR",
"propagate": true,
"qualname": "sqlalchemy.engine.Engine"
}
}
}

51
uvicorn-logging.json Normal file
View File

@ -0,0 +1,51 @@
{
"version": 1,
"disable_existing_loggers": false,
"formatters": {
"default": {
"()": "logging.Formatter",
"fmt": "[%(process)d|%(name)-12s] %(message)s"
}
},
"handlers": {
"uvicorn": {
"class": "app.utils.logging.RichConsoleHandler",
"omit_repeated_times": true,
"show_time": false,
"enable_link_path": false,
"tracebacks_show_locals": true,
"rich_tracebacks": true,
"formatter": "default",
"width": 140,
"style": "yellow"
},
"sqlalchemy": {
"class": "app.utils.logging.RichConsoleHandler",
"omit_repeated_times": true,
"show_time": false,
"enable_link_path": false,
"tracebacks_show_locals": true,
"rich_tracebacks": true,
"formatter": "default",
"width": 140,
"style": "magenta"
}
},
"loggers": {
"root": {
"handlers": [
"uvicorn"
],
"propagate": false,
"level": "TRACE"
},
"sqlalchemy.engine.Engine": {
"handlers": [
"sqlalchemy"
],
"level": "ERROR",
"propagate": false,
"qualname": "sqlalchemy.engine.Engine"
}
}
}