Pygogo
A Python logging library with superpowers
Install / Use
/learn @reubano/PygogoREADME
pygogo: a Python logger with superpowers
|travis| |versions| |pypi|
.. image:: https://raw.githubusercontent.com/reubano/pygogo/master/gogo.png :alt: sample pygogo usage :width: 800 :align: center
Index
Introduction_ | Requirements_ | Motivation_ | Usage_ | Installation_ |
Project Structure_ | Design Principles_ | Structured Logging_ |
Formatters_ | Handlers_ | Scripts_ | Contributing_ | License_
Introduction
pygogo is a Python logging library_ and command-line interface_ with super powers.
pygogo leverages the standard Python logging module_ under the hood, so there's
no need to learn yet-another logging library. The default implementation sends
all messages to stdout, and any messages at level WARNING or above also to stderr.
With pygogo, you can
- Log via different handlers depending on the event severity
- Format log messages as plain text, csv, json, and more..
- Send logs to stdout, stderr, file, email, sockets, and more..
- Inter-operate with the standard python logging module
- and much more...
Requirements
pygogo has been tested and is known to work on Python 3.7, 3.8, and 3.9; and PyPy3.7.
Motivation
The standard logging module is great, but requires a ton of boilerplate before
you can do anything really interesting with it. I designed pygogo to provide
many useful logging use-cases out of the box. A reimplementation of
Using LoggerAdapters to impart contextual information_ is shown below:
.. _Using LoggerAdapters to impart contextual information: https://docs.python.org/2/howto/logging-cookbook.html#using-loggeradapters-to-impart-contextual-information
.. code-block:: python
import pygogo as gogo
logger = gogo.Gogo(__name__).get_structured_logger(connid='1234')
logger.info('log message')
# Prints the following to stdout
{"message": "log message", "connid": "1234"}
Usage
pygogo is intended to be used either directly as a Python library_ or from
the terminal via the command-line interface_.
Library
Examples
^^^^^^^^
*Hello World*
.. code-block:: python
from pygogo import logger
logger.debug('hello world')
logger.error('hello error')
# Prints the following to `stdout`
hello world
hello error
# Prints the following to `stderr`
hello error
*Log based debugging*
.. code-block:: python
import pygogo as gogo
def main(verbose=False):
logger = gogo.Gogo(__name__, verbose=verbose).logger
logger.debug('I will log to `stdout` only if `verbose` is True')
logger.info('I will log to `stdout` always')
logger.warning('I will log to both `stdout` and `stderr` always')
*Disabled dual logging*
.. code-block:: python
import pygogo as gogo
logger = gogo.Gogo(monolog=True).logger
logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.error('error message')
logger.critical('critical message')
# Prints the following to `stdout.log` (all messages at level `INFO` or below):
debug message
info message
# Prints the following to `stderr` (messages at level `WARNING` or above):
warning message
error message
critical message
*Custom formatter* [1]_
.. code-block:: python
import logging
import pygogo as gogo
log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
formatter = logging.Formatter(log_format)
logger = gogo.Gogo(
'examples.fmt',
low_hdlr=gogo.handlers.file_hdlr('custom_fmt.log'),
low_formatter=formatter,
high_level='error',
high_formatter=formatter).logger
# Now let's log something!
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
# Prints the following to `custom_fmt.log` (all messages):
2015-12-18 18:51:30,416 - examples.fmt.base - DEBUG - debug message
2015-12-18 18:51:30,416 - examples.fmt.base - INFO - info message
2015-12-18 18:51:30,416 - examples.fmt.base - WARNING - warn message
2015-12-18 18:51:30,416 - examples.fmt.base - ERROR - error message
2015-12-18 18:51:30,416 - examples.fmt.base - CRITICAL - critical message
# Prints the following to `stderr` (messages at level `ERROR` or above):
2015-12-18 18:51:30,416 - examples.fmt.base - ERROR - error message
2015-12-18 18:51:30,416 - examples.fmt.base - CRITICAL - critical message
*Structured logging* [2]_
.. code-block:: python
import pygogo as gogo
formatter = gogo.formatters.structured_formatter
kwargs = {'low_level': 'info', 'low_formatter': formatter}
logger = gogo.Gogo('examples.structured', **kwargs).logger
extra = {'set_value': set([1, 2, 3]), 'snowman': '☃'}
logger.info('log message', extra=extra) # doctest: +ELLIPSIS
# Prints the following to `stdout`:
{"snowman": "\u2603", "name": "examples.structured.base", "level": "INFO", "message": "log message", "time": "2015-12-18 18:52:39", "msecs": 58.973073959350586, "set_value": [1, 2, 3]}
*Using Filters to impart contextual information* [3]_
.. code-block:: python
import logging
import pygogo as gogo
levels = ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL')
log_frmt = (
'%(asctime)-4s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: '
'%(user)-8s %(message)s')
formatter = logging.Formatter(log_frmt)
going = gogo.Gogo('a', low_formatter=formatter)
a1 = going.get_logger('b.c', ip='123.231.231.123', user='fred')
a2 = going.get_logger('e.f', ip='192.168.0.1', user='sheila')
# Now let's log something!
a1.debug('A debug message')
a1.info('An info %s', 'message')
for level in [getattr(logging, l) for l in levels]:
name = logging.getLevelName(level)
a2.log(level, 'A %s msg', name)
# Prints the following to `stdout` (all messages):
2015-12-19 10:12:24,479 a.b.c DEBUG IP: 123.231.231.123 User: fred A debug message
2015-12-19 10:12:24,479 a.b.c INFO IP: 123.231.231.123 User: fred An info message
2015-12-19 10:12:24,479 a.e.f DEBUG IP: 192.168.0.1 User: sheila A DEBUG msg
2015-12-19 10:12:24,479 a.e.f INFO IP: 192.168.0.1 User: sheila AN INFO msg
2015-12-19 10:12:24,479 a.e.f WARNING IP: 192.168.0.1 User: sheila A WARNING msg
2015-12-19 10:12:24,479 a.e.f ERROR IP: 192.168.0.1 User: sheila AN ERROR msg
2015-12-19 10:12:24,479 a.e.f CRITICAL IP: 192.168.0.1 User: sheila A CRITICAL msg
# Prints the following to `stderr` (messages at level `WARNING` or above):
2015-12-19 10:12:24,479 a.e.f WARNING IP: 192.168.0.1 User: sheila A WARNING msg
2015-12-19 10:12:24,479 a.e.f ERROR IP: 192.168.0.1 User: sheila AN ERROR msg
2015-12-19 10:12:24,479 a.e.f CRITICAL IP: 192.168.0.1 User: sheila A CRITICAL msg
*Multiple loggers* [4]_
.. code-block:: python
import pygogo as gogo
going = gogo.Gogo(
'examples.lggrs',
low_hdlr=gogo.handlers.file_hdlr('multi_lggrs.log'),
low_formatter=gogo.formatters.fixed_formatter,
high_level='info',
high_formatter=gogo.formatters.console_formatter)
root = going.logger
logger1 = going.get_logger('area1')
logger2 = going.get_logger('area2')
# Now let's log something!
root.info('Jackdaws love my big sphinx.')
logger1.debug('Quick zephyrs blow, daft Jim.')
logger1.info('How daft jumping zebras vex.')
logger2.warning('Jail zesty vixen who grabbed pay.')
logger2.error('The five boxing wizards jump.')
# Prints the following to `multi_lggrs.log` (all messages):
2015-12-18 17:21:37.417 examples.lggrs.base INFO Jackdaws love my big sphinx.
2015-12-18 17:21:37.417 examples.lggrs.area1 DEBUG Quick zephyrs blow, daft Jim.
2015-12-18 17:21:37.417 examples.lggrs.area1 INFO How daft jumping zebras vex.
2015-12-18 17:21:37.417 examples.lggrs.area2 WARNING Jail zesty vixen who grabbed pay.
2015-12-18 17:21:37.417 examples.lggrs.area2 ERROR The five boxing wizards jump.
# Prints the following to `stderr` (messages at level `INFO` or above):
examples.lggrs.base: INFO Jackdaws love my big sphinx.
examples.lggrs.area1: INFO How daft jumping zebras vex.
examples.lggrs.area2: WARNING Jail zesty vixen who grabbed pay.
examples.lggrs.area2: ERROR The five boxing wizards jump.
Notes
^^^^^
.. [1] https://docs.python.org/2/howto/logging-cookbook.html#multiple-handlers-and-formatters
.. [2] https://docs.python.org/2/howto/logging-cookbook.html#implementing-structured-logging
.. [3] https://docs.python.org/2/howto/logging-cookbook.html#using-filters-to-impart-contextual-information
.. [4] https://docs.python.org/2/howto/logging-cookbook.html#logging-to-multiple-destinations
Command-line Interface
Examples ^^^^^^^^
Basic Usage
.. code-block:: bash
gogo [options] <message>
show help
.. code-block:: bash
gogo -h
CLI usage
usage: gogo [options] <message>
description: Logs a given message
positional arguments:
message The message to log (defaults to reading from stdin).
optional arguments:
-h, --help show this help message and exit
-l LEVEL, --msg-level LEVEL
The level to log the message (default: info).
Must be one of: critical, error, warning, info, debug.
-n NAME, --name NAME The logger name (default: pygogo)
-D HANDLER, --high-hdlr HANDLER
The high pass log handler (default: stderr).
Must be one of: buffered, email, file, fileobj,
socket, s
Related Skills
node-connect
344.4kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
99.2kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
344.4kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
344.4kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
