Mimicking the logger protocol
Project description
emptylog: some tools for logging
This package ensures compatibility of any logger implementations with the built-in logging
library.
Table of contents
Installing
Install it from Pypi:
pip install emptylog
You can also quickly try out this and other packages without having to install using instld.
Universal Logger Protocol
Easily check whether an object is a logger using the protocol. The protocol contains 6 classic logger methods:
def debug(message: str, *args: Any, **kwargs: Any) -> None: pass
def info(message: str, *args: Any, **kwargs: Any) -> None: pass
def warning(message: str, *args: Any, **kwargs: Any) -> None: pass
def error(message: str, *args: Any, **kwargs: Any) -> None: pass
def exception(message: str, *args: Any, **kwargs: Any) -> None: pass
def critical(message: str, *args: Any, **kwargs: Any) -> None: pass
The protocol is verifiable in runtime by the isinstance
function. Let's check this on a regular logger from logging
:
import logging
from emptylog import LoggerProtocol
print(isinstance(logging.getLogger('some_name'), LoggerProtocol)) # True
This also works for third-party loggers with the same signature. Let's try it on loguru:
from loguru import logger
from emptylog import LoggerProtocol
print(isinstance(logger, LoggerProtocol)) # True
And of course, you can use the protocol for type hints:
def function(logger: LoggerProtocol):
logger.info('There was an earthquake in Japan, check the prices of hard drives!')
The protocol can be used for static checks by any tool you prefer, such as mypy
.
Empty Logger
EmptyLogger
is the simplest implementation of the logger protocol. When calling logging methods from an object of this class, nothing happens. You can use it as a stub, for example, when defining functions:
from emptylog import EmptyLogger, LoggerProtocol
def function(logger: LoggerProtocol = EmptyLogger()):
logger.error('Kittens have spilled milk, you need to pour more.')
Memory Logger
MemoryLogger
is a special class designed for tests. Its difference from EmptyLogger
is that it remembers all the times it was called.
The call history is stored in the data
attribute and sorted by logger method names:
from emptylog import MemoryLogger
logger = MemoryLogger()
logger.error('Joe Biden forgot his name again.')
logger.error('And again.')
logger.info("Joe, remember, you're Joe.")
print(logger.data)
# LoggerAccumulatedData(debug=[], info=[LoggerCallData(message="Joe, remember, you're Joe.", args=(), kwargs={})], warning=[], error=[LoggerCallData(message='Joe Biden forgot his name again.', args=(), kwargs={}), LoggerCallData(message='And again.', args=(), kwargs={})], exception=[], critical=[])
print(logger.data.info[0].message)
# Joe, remember, you're Joe.
print(logger.data.error[0].message)
# Joe Biden forgot his name again.
print(logger.data.info[0].args)
# ()
print(logger.data.info[0].kwargs)
# {}
You can find out the total number of logs saved by MemoryLogger
by applying the len()
function to the data
attribute:
logger = MemoryLogger()
logger.warning("Are you ready, kids?")
logger.info("Aye, aye, Captain!")
logger.error("I can't hear you!")
logger.info("Aye, aye, Captain!")
logger.debug("Oh!")
print(len(logger.data))
# 5
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.