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.
This is the recommended standard setup.
from ophyd.log 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.
If operations are “hanging,” running slowly, or repeatedly encountering an error, increasing the logging verbosity can help identify the underlying issue.
from ophyd.log 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.log import config_ophyd_logging config_ophyd_logging(file='/tmp/ophyd.log', level='DEBUG')
The flow of log event information in loggers and handlers is illustrated in the following diagram:
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.
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 : logging.getLevelName(logger.level) In : 'NOTSET'
and so it inherits the level of Python’s default
“handler of last resort,”
logging.lastResort, which is
In : logging.getLevelName(logger.getEffectiveLevel()) In : 'WARNING'
In this case we should set it to
'DEBUG', to match the most verbose level
of the handler we have added.
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