SkillAgentSearch skills...

Pygogo

A Python logging library with superpowers

Install / Use

/learn @reubano/Pygogo
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

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

View on GitHub
GitHub Stars283
CategoryDevelopment
Updated7mo ago
Forks20

Languages

Python

Security Score

92/100

Audited on Aug 27, 2025

No findings