Debugging and Logging

Changed in version 1.4.0: Ophyd’s use of Python’s logging framework has been completely reworked to follow Python’s documented best practices for libraries.

Ophyd uses Python’s logging framework, which enables sophisticated log management. For common simple cases, including viewing logs in the terminal or writing them to a file, the next section illustrates streamlined, copy/paste-able examples. Users who are familiar with that framework or who need to route logs to multiple destinations may wish to skip ahead to Ophyd’s Logging-Related API.

Useful Snippets

Log warnings

This is the recommended standard setup.

from ophyd import config_ophyd_logging
config_ophyd_logging()

It will display 'ophyd' log records of WARNING level or higher in the terminal (standard out) with a format tailored to ophyd.

Maximum verbosity

If operations are “hanging,” running slowly, or repeatedly encountering an error, increasing the logging verbosity can help identify the underlying issue.

from ophyd import config_ophyd_logging
config_ophyd_logging(level='DEBUG')

Log to a file

This will direct all log messages to a file instead of the terminal (standard out).

from ophyd import config_ophyd_logging
config_ophyd_logging(file='/tmp/ophyd.log', level='DEBUG')

Advanced Example

The flow of log event information in loggers and handlers is illustrated in the following diagram:

https://docs.python.org/3/_images/logging_flow.png

For further reference, see the Python 3 logging howto: https://docs.python.org/3/howto/logging.html#logging-flow

As an illustrative example, we will set up two handlers using the Python logging framework directly, ignoring ophyd’s convenience function.

Suppose we set up a handler aimed at a file:

import logging
file_handler = logging.FileHandler('ophyd.log')

And another aimed at Logstash:

import logstash  # requires python-logstash package
logstash_handler = logstash.TCPLogstashHandler(<host>, <port>, version=1)

We can attach the handlers to the ophyd logger, to which all log records created by ophyd propagate:

logger = logging.getLogger('ophyd')
logger.addHandler(logstash_handler)
logger.addHandler(file_filter)

We can set the verbosity of each handler. Suppose want maximum verbosity in the file but only medium verbosity in logstash.

logstash_handler.setLevel('INFO')
file_handler.setLevel('DEBUG')

Finally, ensure that “effective level” of logger is at least as verbose as the most verbose handler—in this case, 'DEBUG'. By default, at import, its level is not set

In [1]: logging.getLevelName(logger.level)

In [2]: 'NOTSET'

and so it inherits the level of Python’s default “handler of last resort,” logging.lastResort, which is 'WARNING'.

In [3]: logging.getLevelName(logger.getEffectiveLevel())

In [4]: 'WARNING'

In this case we should set it to 'DEBUG', to match the most verbose level of the handler we have added.

logger.setLevel('DEBUG')

This makes DEBUG-level records available to all handlers. Our logstash handler, set to 'INFO', will filter out DEBUG-level records.

To globally disable the generation of any log records at or below a certain verbosity, which may be helpful for optimizing performance, Python provides logging.disable().