Skip to main content

Refreshingly simple declarative logging that utilizes arbitrary tag sinks instead of traditional level handling

Project description

chipper
======

Refreshingly simple declarative logging that utilizes arbitrary tag sinks instead of traditional level handling

chipper uses `Deconfigurable` configurations provided by the [deconf library](https://github.com/dustinlacewell/deconf). You should look it over to learn more about how chipper's log configuration works.

Introduction:
-------------

`chipper` is a module that provides a logging system that attempts to make logging as easy as possible. The main aspects unique to it are:

* Multi-tag logging handlers
* Declarative logging configuration

To get started immediately, you can simply use the default logger. This logger will route all emissions to stdout:

>>> from chipper import log
>>> log('Hello World')
[DEFAULT] : Hello World

You can pass in your own tags with Log.log:

>>> from chipper import log
>>> log.log("Here's some general info", 'general', 'info')
>>> [GENERAL, INFO] : Here's some general info

In addition to the main Log.log(message, *tags) form, some convenience magic is provided. Calling any attribute on the Log instance that is not used by the class itself will invoke the base Log.log method. The passed tags will be derrived by splitting the attribute name by underscore. The following call is equivalent:

>>> log.general_info("Here's some general info')
[GENERAL, INFO] : Here's some general info


Multi-tag Handlers:
-------------------

In a traditional logging system, each log emission specifies one of a number of possible logging levels. Traditional logging systems typically include levels such as `debug`, `warn`, `info`, and `error`.

In `chipper` log emissions can include any number of arbitrary *single-word* tags. Logging handlers are setup to listen for one or more tags. Any log messages that have tags that match will be routed to such handlers.

>>> from chipper import Log, Handler, Target, Formatter
>>> log = Log(
... handlers=(
... Handler(
... name='templog',
... tags=('debug', ),
...
... target=Target(
... filename='/tmp/templog.txt'
... ),
...
... formatter=Formatter(
... template="{datetime}{tags} : "
... ),
... ),
... ),
... )
>>> log('This should show in stdout')
[DEFAULT] : This should show in stdout
>>> log.debug('This should show in templog.txt')
$ cat /tmp/templog.txt
[2012-09-28 11:53:56][DEBUG] : This should show in templog.txt

With this system, you can log different views of activity within your application. For example, you may have a handler that routes all "sql" emissions to `logs/sql.txt`, a handler that routes all "blog" emissions to `logs/apps/blog.txt` and a third handler that routes all "warning" emissions to `stdout`. With this setup, the following call is routed to all three logging targets:

>>> log.blog_sql_warning("Unusual query generated here. Query: '{0}'".format(new_query))
[2012-09-28 11:59:28][BLOG, SQL, WARNING] : Unusual query generated here. Query: 'select * from 48.000f where'

Traced Emissions:
-----------------

If you'd like to include information in your emission about where the emission came from or any related exception information a special `trace` tag is handled:

>>> log.trace("Use the source, Luke!")
[<stdin>:1][TRACE]:Use the source, Luke!

You can capture handled exceptions and include their tracebacks in your log too:

>>> def error():
... raise SystemExit("Fatal Error!")
...
>>> try: error()
... except: log.trace("Something bad happened.")
...
[<stdin>:2][TRACE]:Something bad happened.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in error
SystemExit: Fatal Error!


Tagged Loggers:
---------------

The magical attribute access has another nice aspect in that you can store log objects that always emit with the same tags. Simply store a reference to any log attribute:

>>> bloginfo = log.blog_info
>>> bloginfo("Updating comment cache...")
[BLOG, INFO]:Updating comment cache...


chipper.Handler:
----------------

The `Handler` object is for specifying where log emissions with specific tags should be written to and how they should be formatted.

**name** `str`: The textual name of the handler

**tags** `tuple(str,)`: The tags to capture

**target** `chipper.Target`: The file object to write to

**formatter** `chipper.Formatter`: The object that will
format the emissions


chipper.Target:
---------------

The `Target` object represents where the `Handler` will write captured emissions. It can write to any of the following that are configured.

**filename** `str`: The path of a file to write to

**stdout** `bool`: Whether to write to sys.stdout or not (default:`false`)

**stderr** `bool`: Whether to write to sys.stderr or not (default:`false`)


chipper.Formatter:
------------------

The `Formatter` is responsible for constructing the log prefix that is prepended to each log emission. It does this in a very configurable way that should be satisfactory for most needs.

There are essentially three "*item groups" that are processed. `Date and Time`, `Tags` and `Trace` information. The entire formatting process follows these steps:

* Format each item (the date, the time, each tag, etc)
* Format each item-group (date/time, tags, etc)
* Format the entire log emission line


Item format options:
--------------------

**tag_template** `str`: Individual tag render template (default:`"{tag}"`)

**tag_formatter** `lambda`: Individual tag formatter lambda (default:`lambda tag: tag.upper().strip()`)

**tag_delimiter** `str`: Delimiter with which to join the tags (default:`,`)

**date_template** `str`: Date render template (default:`"{date}"`)

**date_format** `str`: Strftime format pattern (default:`"%Y-%m-%d"`)

**time_template** `str`: Time render template (default:`"{time}"`)

**time_format** `str`: Strftime format pattern (default:`"%Y-%m-%d"`)

**file_template** `str`: Filename render template (default:`"{file}"`)

**line_template** `str`: Line number render template (default:`":{line}"`)

**module_template** `str`: Module name render template (default:`":{module}"`)


Item-group format options:
--------------------------

**tags_template** `str`: Joined tags item-group template (default:`"[{tags}]"`)

**datetime_template** `str`: Datetime item-group render template (default:`"[{date} {time}]"`)

**trace_template** `str`: Collective trace info item-group template (default:`"{file}{line}"`)


Final emission format option:
-----------------------------

**template** `str`: The final render template incorporating all of the item-groups. Note that the `{trace}` format variable is only provided if the emission includes a trace tag. (default:`"{datetime}{trace}{tags} : "`)

Project details


Release history Release notifications | RSS feed

This version

0.1

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

chipper-0.1.tar.gz (7.3 kB view details)

Uploaded Source

File details

Details for the file chipper-0.1.tar.gz.

File metadata

  • Download URL: chipper-0.1.tar.gz
  • Upload date:
  • Size: 7.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for chipper-0.1.tar.gz
Algorithm Hash digest
SHA256 ba396b76de3801e7b589e47db05d38f131b753a991b5a3a5e4cb2a8d139b5781
MD5 e1d16eefd02ae267811518182047d079
BLAKE2b-256 6c416833b24896418d1f85b25fb85ee30e521bb8a2980788c5ae263c3b92d956

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page