Logging

Early debug messages

Default logging level is set to INFO. While debugging actions happening early in pipeline workflow, like module discovery and loading, it may be useful to enable more verbose logging. Unfortunatelly, this feature is controlled by a debug option, and this option will be taken into account too late to shed light on your problem. For that case, it is possible to tell gluetool to enable debug logging right from its beginning, by setting an environment variable GLUETOOL_DEBUG to any value:

export GLUETOOL_DEBUG=does-not-matter
gluetool -l

As you can see, gluetool dumps much more verbose logging messages - about processing of options, config files and other stuff - on terminal with the variable set.

Note

You can set the variable in any way supported by your shell, session or environment in general. The only important thing is that such variable must exist when gluetool starts.

Logging of structured data

To format structured data, like lists, tuples and dictionaries, for output, use gluetool.log.format_dict()

Example:

import gluetool

print gluetool.log.format_dict([1, 2, (3, 4)])

Output:

[
    1,
    2,
    [
        3,
        4,
    ]
]

To actually log structured data, the gluetool.log.log_dict() helper is a nice shortcut.

Example:

import gluetool

logger = gluetool.log.Logging.create_logger()

gluetool.log.log_dict(logger.info, 'logging structured data', [1, 2, (3, 4)])

Output:

[14:43:03] [+] logging structured data:
[
    1,
    2,
    [
        3,
        4
    ]
]

The first parameter of log_dict expects a callback which is given the formatted data to actually log them. It is therefore easy to use log_dict on every level of your code, e.g. in methods of your module, just give it proper callback, like self.info.

Todo

  • seealso:
    • logging helpers
    • connecting loggers

See also

Logging of unstructured blobs of text
to find out how to log text blobs.
gluetool.log.format_dict(), gluetool.log.log_dict()
for developer documentation.

Logging of unstructured blobs of text

To format a “blob” of text, without any apparent structure other than new-lines and similar markings, use gluetool.log.format_blob():

It will preserve text formatting over multiple lines, and it will add borders to allow easy separation of the blob from neighbouring text.

To actually log a blob of text, gluetool.log.log_blob() is a shortcut:

The first parameter of log_blob expects a callback which is given the formatted data to actually log them. It is therefore easy to use log_blob on every level of your code, e.g. in methods of your module, just give it proper callback, like self.info.

Todo

  • seealso:
    • logging helpers
    • connecting loggers

See also

Logging of structured data
to find out how to log structured data.
gluetool.log.format_blob(), gluetool.log.log_blob()
for developer documentation.

Logging of XML elements

To format an XML element, use gluetool.log.format_xml():

It will indent nested elements, presenting the tree in a more readable form.

To actually log an XML element, gluetool.log.log_xml() is a shortcut:

The first parameter of log_xml expects a callback which is given the formatted data to actually log them. It is therefore easy to use log_xml on every level of your code, e.g. in methods of your module, just give it proper callback, like self.info.

Todo

  • seealso:
    • logging helpers
    • connecting loggers

See also

Logging of structured data
to find out how to log structured data.
gluetool.log.format_blob(), gluetool.log.log_blob()
for developer documentation.

Object logging helpers

Note

When we talk about logger, we mean it as a description - an object that has logging methods we can use. It’s not necessarilly the instance of logging.Logger - in fact, given how logging part of gluetool works, it is most likely it’s an instance of gluetool.logging.ContextAdapter. But that is not important, the API - logging methods like info or error are available in such “logger” object, no matter what its class is.

Python’s logging system provides a log function for each major log level, usually named by its corresponding level in lowercase, e.g. debug or info. These are reachable as methods of a logger (or logging context adapter) instance. If you have a class which is given a logger, to ease access to these methods, it is possible to “connect” the logger and your class, making logger’s debug & co. direct members of your objects, allowing you to call self.debug, for example.

Example:

from gluetool.log import Logging, ContextAdapter

logger = ContextAdapter(Logging.create_logger())

class Foo(object):
    def __init__(self, logger):
        logger.connect(self)

Foo(logger).info('a message')

Output:

[10:01:15] [+] a message

All standard logging method debug, info, warn, error and exception are made available after connecting a logger.

Todo

  • seealso:
    • context adapter

See also

logging.Logger.debug()
for logging methods.

Todo

Features yet to describe:

  • clear separation of logging records, making it visible where each of them starts and what is a log message and what a logged blob of command output
  • default log level controlled by env var
  • warn(sentry=True)
  • verbose, readable, formatted traceback logging
  • using context adapters to add “structure” to loged messages
  • colorized messages based on their level
  • optional “log everything” dump in a file
  • correct and readable logging of exception chains