diff --git a/README.md b/README.md index dfa364c..4fa7de4 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,27 @@ Data set is coming form https://github.com/catherinedevlin/opensourceshakespeare Next models were generated with https://github.com/agronholm/sqlacodegen And after some tweaking I got desired result +### Rainbow logs with rich :rainbow: + +To deliver better user(developer) experience when watching logs with tons of information +from few emitters (which are really needy on development stage) project is using [rich](https://github.com/Textualize/rich) library. +Event with [rich](https://github.com/Textualize/rich) superpowers reading logs is not easy. +Found [rich](https://github.com/Textualize/rich) really nice - +but it took time to learn how to integrate it as logger object properly and keep it as singleton. + +To address below needs: +- it is hard to find what I am looking for even with glasses on. +- don’t want to hire ELK to be able to use logs. +- want to move fast enough with debugging. + +Below steps were done to integrate [rich](https://github.com/Textualize/rich) into project. +1. Configure emitters with [config.ini](https://github.com/grillazz/fastapi-sqlalchemy-asyncpg/blob/main/config.ini) +2. Eliminate duplicates i.e. sqlalchemy echo by separate handlers +3. Keep logger as singleton pattern to avoid multiple instances +4. add uvicorn parameter --log-config config.ini + +![sample-logs-with-rich](/static/logz.jpg) + Hope you enjoy it. ### Change Log diff --git a/config.ini b/config.ini index cae41bc..103ebaa 100644 --- a/config.ini +++ b/config.ini @@ -1,55 +1,48 @@ [loggers] -keys = root, sqlalchemy +keys = root, sqlalchemy.engine.Engine, uvicorn.access [handlers] -keys = console, console_rich, error_file, access_file +keys = stream, sqlalchemy, uvicorn [formatters] -keys = generic, generic_rich, access +keys = default [logger_root] -; Logging level for all loggers -level = NOTSET -handlers = console_rich, error_file +level = INFO +propagate = 0 +handlers = stream -[logger_sqlalchemy] -handlers = -qualname = sqlalchemy.engine +[logger_sqlalchemy.engine.Engine] +level = INFO +propagate = 0 +handlers = sqlalchemy +qualname = sqlalchemy.engine.Engine -[handler_console] -class = logging.StreamHandler -level = NOTSET -formatter = generic -stram = ext://sys.stdout +[logger_uvicorn.access] +level = INFO +propagate = 0 +handlers = uvicorn +qualname = uvicorn.access -[handler_error_file] -class = logging.FileHandler -formatter = generic -level = WARNING -args = ('/tmp/error.log','w') - -[handler_access_file] -class = logging.FileHandler -formatter = access -args = ('/tmp/access.log',) - -[formatter_generic] -format = [%(process)d|%(name)-12s|%(filename)s:%(lineno)d] %(levelname)-7s %(message)s -datefmt = %H:%M:%S -class = logging.Formatter - -[formatter_access] -format = %(message)s -class = logging.Formatter - - -[formatter_generic_rich] -format = [%(process)d %(name)s] %(message)s -datefmt = %H:%M:%S -class = logging.Formatter - -[handler_console_rich] +[handler_stream] class = app.logging.RichConsoleHandler -args = (100, "blue") -kwargs = {"omit_repeated_times":False, "show_time": False, "enable_link_path": True, "tracebacks_show_locals": True} -level = NOTSET +kwargs = {"omit_repeated_times":True, "show_time": False, "enable_link_path": False, "tracebacks_show_locals": True} +args = (100, "white") +formatter = default +stream = ext://sys.stdout + +[handler_sqlalchemy] +class = app.logging.RichConsoleHandler +kwargs = {"omit_repeated_times":True, "show_time": False, "enable_link_path": False, "tracebacks_show_locals": True} +args = (100, "magenta") +formatter = default + +[handler_uvicorn] +class = app.logging.RichConsoleHandler +kwargs = {"omit_repeated_times":True, "show_time": False, "enable_link_path": False, "tracebacks_show_locals": True} +args = (100, "yellow") +formatter = default + +[formatter_default] +format = [%(process)d|%(name)-12s] %(message)s +class = logging.Formatter \ No newline at end of file diff --git a/static/logz.png b/static/logz.png new file mode 100644 index 0000000..8af8129 Binary files /dev/null and b/static/logz.png differ