Async friendly logging classes for Python 3
Features:
- logging classes using
async/awaitfor logs - handling of six logging levels, like in built-in logging module
- built-in support for flushing of log records (e.g. making a web request, or writing to a database, every n records)
- flushing supports max retries, configurable delays, number of attempts, and fallback target in case of failure
- support for several targets per logger
- can be used to asynchronously log to different destinations (for example, web api integration, DBMS, etc.)
- logged records support any kind of desired arguments and data structures
- completely abstracted from destination of log entries
- can be used with built-in
loggingmodule, for sync logging and to use built-in logging classes - integrated with rodi dependency injection library, to support injection of loggers by activated class name
Installation
pip install rolog
Classes and log levels
| Class | Description |
|---|---|
| LogLevel | Int enum: NONE, DEBUG, INFORMATION, WARNING, ERROR, CRITICAL |
| LogTarget | base for classes that are able to send log records to a certain destination |
| Logger | class responsible for creating log records and sending them to appropriate targets, by level |
| LoggerFactory | configuration class, responsible for holding configuration of targets and providing instances of loggers |
| LogRecord | log record created by loggers, sent to configured targets by a logger |
| ExceptionLogRecord | log record created by loggers, including exception information |
| FlushLogTarget | abstract class, derived of LogTarget, handling records in groups, storing them in memory |
Basic use
As with the built-in logging module, Logger class is not meant to be instantiated directly, but rather obtained using a configured LoggerFactory.
Example:
import asyncio
from rolog import LoggerFactory, Logger, LogTarget
class PrintTarget(LogTarget):
async def log(self, record):
await asyncio.sleep(.1)
print(record.message, record.args, record.data)
factory = LoggerFactory()
factory.add_target(PrintTarget())
logger = factory.get_logger(__name__)
loop = asyncio.get_event_loop()
async def example():
await logger.info('Lorem ipsum')
# log methods support any argument and keyword argument:
# these are stored in the instances of LogRecord, it is responsibility of LogTarget(s)
# to handle these extra parameters as desired
await logger.info('Hello, World!', 1, 2, 3, cool=True)
loop.run_until_complete(example())
Flushing targets
rolog has built-in support for log targets that flush messages in groups, this is necessary to optimize for example
reducing the number of web requests when sending log records to a web api, or enabling bulk-insert inside a database.
Below is an example of flush target class that sends log records to some web api, in groups of 500:
from typing import List
from rolog import FlushLogTarget, LogRecord
class SomeLogApiFlushLogTarget(FlushLogTarget):
def __init__(self, http_client):
super().__init__()
self.http_client = http_client
async def log_records(self, records: List[LogRecord]):
# NB: implement here your own logic to make web requests to send log records
# to a web api, such as Azure Application Insights
# (see for example https://pypi.org/project/asynapplicationinsights/)
pass
Flush targets handle retries with configurable and progressive delays, when logging a group of records fails.
By default, in case of failure a flush target tries to log records 3 times, using a progressive delay of 0.6 seconds * attempt number,
finally falling back to a configurable fallback target if logging always failed. Warning messages are issued, using built-in
Warnings module to notify of these failures.
These parameters are configurable using constructor parameters fallback_target, max_size, retry_delay, progressive_delay.
class FlushLogTarget(LogTarget, ABC):
"""Base class for flushing log targets: targets that send the log records
(created by loggers) to the appropriate destination in groups."""
def __init__(self,
queue: Optional[Queue]=None,
max_length: int=500,
fallback_target: Optional[LogTarget]=None,
max_retries: int=3,
retry_delay: float=0.6,
progressive_delay: bool=True):
Flushing when application stops
Since flushing targets hold log records in memory before flushing them, it's necessary to flush when an application stops.
Assuming that a single LoggerFactory is configured in the configuration root of an application, this
can be done conveniently, by calling the dispose method of the logger factory.
# on application shutdown:
await logger_factory.dispose()
Dependency injection
rolog is integrated with rodi dependency injection library, to support injection of loggers per activated class name.
When a class that expects a parameter of rolog.Logger type is activated, it receives a logger for the category of the class name itself.
For more information, please refer to the dedicated page in project wiki.
Documentation
Please refer to documentation in the project wiki: https://github.com/RobertoPrevato/rolog/wiki.
Develop and run tests locally
pip install -r dev_requirements.txt
# run tests using automatic discovery:
pytest
Metadata
Release files for rolog 1.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rolog-1.0.2.tar.gz | 7.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rolog-1.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 15.5 kB
Release files / rolog-1.0.2.tar.gz
| Download URL | rolog-1.0.2.tar.gz |
|---|---|
| Size | 7.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9a20de4a5f14e43a2a65dbe9fde7a3a3c4e82d03eed2b18eac4ad594aebe4cc1
|
|
BLAKE2b-256 checksum How to use checksums |
59b8f1552b868fb922a2ddfb039c0352f7ea5330c7784543d5e210617f815219
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/40.6.2 requests-toolbelt/0.9.1 tqdm/4.32.1 CPython/3.7.2
|
Release files / rolog-1.0.2-py3-none-any.whl
| Download URL | rolog-1.0.2-py3-none-any.whl |
|---|---|
| Size | 8.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2aea11141cd89e9405b704df6a5e834a51bee4d1029fb6824173a25db3f505fc
|
|
BLAKE2b-256 checksum How to use checksums |
648637f365c603b4adea6789b4c030e809625408a134ee5f994cb9838ef26fc8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/40.6.2 requests-toolbelt/0.9.1 tqdm/4.32.1 CPython/3.7.2
|