Skip to content

Commit 1d98c7e

Browse files
committed
add rainbow logging with rich
1 parent 63014e1 commit 1d98c7e

File tree

3 files changed

+61
-47
lines changed

3 files changed

+61
-47
lines changed

README.md

+21
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,27 @@ Data set is coming form https://github.com/catherinedevlin/opensourceshakespeare
5050
Next models were generated with https://github.com/agronholm/sqlacodegen
5151
And after some tweaking I got desired result
5252

53+
### Rainbow logs with rich :rainbow:
54+
55+
To deliver better user(developer) experience when watching logs with tons of information
56+
from few emitters (which are really needy on development stage) project is using [rich](https://github.com/Textualize/rich) library.
57+
Event with [rich](https://github.com/Textualize/rich) superpowers reading logs is not easy.
58+
Found [rich](https://github.com/Textualize/rich) really nice -
59+
but it took time to learn how to integrate it as logger object properly and keep it as singleton.
60+
61+
To address below needs:
62+
- it is hard to find what I am looking for even with glasses on.
63+
- don’t want to hire ELK to be able to use logs.
64+
- want to move fast enough with debugging.
65+
66+
Below steps were done to integrate [rich](https://github.com/Textualize/rich) into project.
67+
1. Configure emitters with [config.ini](https://github.com/grillazz/fastapi-sqlalchemy-asyncpg/blob/main/config.ini)
68+
2. Eliminate duplicates i.e. sqlalchemy echo by separate handlers
69+
3. Keep logger as singleton pattern to avoid multiple instances
70+
4. add uvicorn parameter --log-config config.ini
71+
72+
![sample-logs-with-rich](/static/logz.jpg)
73+
5374
Hope you enjoy it.
5475

5576
### Change Log

config.ini

+40-47
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,48 @@
11
[loggers]
2-
keys = root, sqlalchemy
2+
keys = root, sqlalchemy.engine.Engine, uvicorn.access
33

44
[handlers]
5-
keys = console, console_rich, error_file, access_file
5+
keys = stream, sqlalchemy, uvicorn
66

77
[formatters]
8-
keys = generic, generic_rich, access
8+
keys = default
99

1010
[logger_root]
11-
; Logging level for all loggers
12-
level = NOTSET
13-
handlers = console_rich, error_file
14-
15-
[logger_sqlalchemy]
16-
handlers =
17-
qualname = sqlalchemy.engine
18-
19-
[handler_console]
20-
class = logging.StreamHandler
21-
level = NOTSET
22-
formatter = generic
23-
stram = ext://sys.stdout
24-
25-
[handler_error_file]
26-
class = logging.FileHandler
27-
formatter = generic
28-
level = WARNING
29-
args = ('/tmp/error.log','w')
30-
31-
[handler_access_file]
32-
class = logging.FileHandler
33-
formatter = access
34-
args = ('/tmp/access.log',)
35-
36-
[formatter_generic]
37-
format = [%(process)d|%(name)-12s|%(filename)s:%(lineno)d] %(levelname)-7s %(message)s
38-
datefmt = %H:%M:%S
39-
class = logging.Formatter
40-
41-
[formatter_access]
42-
format = %(message)s
43-
class = logging.Formatter
44-
45-
46-
[formatter_generic_rich]
47-
format = [%(process)d %(name)s] %(message)s
48-
datefmt = %H:%M:%S
49-
class = logging.Formatter
50-
51-
[handler_console_rich]
11+
level = INFO
12+
propagate = 0
13+
handlers = stream
14+
15+
[logger_sqlalchemy.engine.Engine]
16+
level = INFO
17+
propagate = 0
18+
handlers = sqlalchemy
19+
qualname = sqlalchemy.engine.Engine
20+
21+
[logger_uvicorn.access]
22+
level = INFO
23+
propagate = 0
24+
handlers = uvicorn
25+
qualname = uvicorn.access
26+
27+
[handler_stream]
5228
class = app.logging.RichConsoleHandler
53-
args = (100, "blue")
54-
kwargs = {"omit_repeated_times":False, "show_time": False, "enable_link_path": True, "tracebacks_show_locals": True}
55-
level = NOTSET
29+
kwargs = {"omit_repeated_times":True, "show_time": False, "enable_link_path": False, "tracebacks_show_locals": True}
30+
args = (100, "white")
31+
formatter = default
32+
stream = ext://sys.stdout
33+
34+
[handler_sqlalchemy]
35+
class = app.logging.RichConsoleHandler
36+
kwargs = {"omit_repeated_times":True, "show_time": False, "enable_link_path": False, "tracebacks_show_locals": True}
37+
args = (100, "magenta")
38+
formatter = default
39+
40+
[handler_uvicorn]
41+
class = app.logging.RichConsoleHandler
42+
kwargs = {"omit_repeated_times":True, "show_time": False, "enable_link_path": False, "tracebacks_show_locals": True}
43+
args = (100, "yellow")
44+
formatter = default
45+
46+
[formatter_default]
47+
format = [%(process)d|%(name)-12s] %(message)s
48+
class = logging.Formatter

static/logz.png

273 KB
Loading

0 commit comments

Comments
 (0)