Tree based logging for async python
Project description
lumberjack
Tree based logging for python.
Normal logging struggles in async python, since logs will often get mixed up,
and it may not be clear what happened in what order. lumberjack instead groups
logs into a tree like structure. This way, any result can be easily broken down
into its steps. The tree structure is to isolate different synchronous paths
through the async system, so that each log is ordered, and the logic can be
easily followed.
Basic Usage
Creating a Logger
Creating a logger is as easy as defining a backend, and then creating a
TreeLogger. Generally, it is advisable to use lumberjack loggers as context
managers.
import lumberjack
import lumberjack.backends
logging_backend = lumberjack.backends.FileWriter("some_folder_path")
with lumberjack.TreeLogger(logging_backend):
...
Logging
Once a logger has been created, you can begin logging. There are two ways to do
so: First, if you are in the context of a TreeLogger, you can simply log
directly.
with lumberjack.TreeLogger(logging_backend):
lumberjack.log(message="Some message to log")
If you do not wish to use TreeLogger as a context manager, you will instead
need to call the logging methods of your Treelogger's branches.
tree_logger = lumberjack.TreeLogger(logging_backend)
root_branch = tree_logger.root
another_branch = root_branch.branch("new branch")
another_branch.log(message="Some message to log")
Branching
The main feature of lumberjack is the ability to branch logs, so that logs are
separate between concurrently running functions. Once again, there is the
context approach, and the manual approach.
If you are using a context manager, then you can simply decorate any functions
that you wish to be branch points. Any time these functions are called,
lumberjack will automatically create a new branch for logging. For example:
@lumberjack.branch
async def async_fn():
lumberjack.log("some log message")
sync_fn()
@lumberjack.branch
def sync_fn():
lumberjack.log("another log message")
with lumberjack.TreeLogger(logging_backend):
asyncio.run(async_fn())
In the above example, the logs in each function will be kept separate, even
between runs of the same function. While this may not be useful for this toy
example, anytime your code includes asyncio.gather or similar, it can be
invaluable.
The manual branching approach can be easily demonstrated by this previous example:
tree_logger = lumberjack.TreeLogger(logging_backend)
root_branch = tree_logger.root
another_branch = root_branch.branch("new branch")
another_branch.log(message="Some message to log")
Anytime a logger branch is branched, a log entry will be added to parent branch at the appropriate location.
Demo File
For a more full example of lumberjack in use, please refer to
demo.py.
Installing
To install lumberjack, simply use pip
pip install lumberjack
However, if you want to use the built-in Streamlit UI to view the logs that you
create, you should install lumberjack with the ui extras.
pip install lumberjack[ui]
Some backends will also require extras, such as redis.
pip install lumberjack[redis]
UI
If you install lumberjack with the ui extras, lumberjack provides access to a
simple Streamlit UI which you can use to view the logs. If you have installed
lumberjack with the ui extras, simply use the command lumberjack-ui to run the
UI. Currently, you can choose to point the UI at either a file-based or redis
backend.
Usage: lumberjack-ui run [OPTIONS]
Launch the lumberjack UI to view logs.
Options:
--port INTEGER Port to run the Streamlit app on.
--backend [redis|files] Backend to use. [required]
--redis-host TEXT Redis host (if using redis backend).
--redis-port INTEGER Redis port (if using redis backend).
--filepath PATH Path to log file (if using files backend).
--help Show this message and exit.
Once you have launched the UI, you can access it on your local machine via the port that you provided, in a browser of your choice, where you will see the search screen. This screen will allow you to select from any branch that was saved to the currently running backend.
From there, you can open any branch that you wish to view, and you will enter the logs screen. This screen allows you to navigate the tree of the branch you selected, as well as return to the search screen.
Best Practices
Message Types
The flow logger has 3 message types: SYSTEM, USER, and ERROR. Each message
type is used to indicate a different kind of log message, and should be used in
accordance with the following guidelines:
SYSTEM
- Indicating when a branch has occurred (handled internally by the logger)
- Indicating the function arguments of a called function (handled by either the
user or the
@branchdecorator) - Indicating the return value of a called function (handled by either the user
or the
@branchdecorator)
ERROR
- Indicating an error which occurred during the function call (handled by the
user or the
@branchdecorator)
USER
- Logging potentially error-prone modifications/transformations of variables
- Logging calls to external services and the parameters of those calls
- Logging the results of external services and the parameters of those results
- Logging important control flow
Branching
Branching should be done whenever entering a new context, as mentioned above. Follow the following guidelines for branching:
- Fork whenever calling a new function
- Fork whenever the execution path becomes asynchronous
As a general guideline, do not have a logger associated with an object or class, instead log on the function level.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bramble-0.0.1.tar.gz.
File metadata
- Download URL: bramble-0.0.1.tar.gz
- Upload date:
- Size: 196.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b859b851aa2fb0d55830cdb841d465cab035fb9798bcdfc4e28d938bdb21268f
|
|
| MD5 |
5e0e4589c84311ebed662c0b95d0c2c7
|
|
| BLAKE2b-256 |
0994c68a8da01465a16155d037ec82bc4c9433516a78883545ef21eee38df81b
|
File details
Details for the file bramble-0.0.1-py3-none-any.whl.
File metadata
- Download URL: bramble-0.0.1-py3-none-any.whl
- Upload date:
- Size: 26.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.11.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ffee21cf7b722bb8b94d553e7791a47e3abd3e3265f7af0cc66a8995861dc9b
|
|
| MD5 |
11a916cba33f7bd2138fb8bb2c9475c9
|
|
| BLAKE2b-256 |
031676b305f35cee83d972dac84101cfa9c2e6a38b08cb7141a090af1d63f094
|