Logging

It is often useful to record a log of the operations that you perform. Being a basic building block, scipp is generally quiet and does not produce any output except for warnings and errors. It does however define and configure its own logger which allows customizing how those warnings and errors are reported.

The logger is an instance of logging.Logger and can be configured using the logging module of the standard library.

[1]:
import scipp as sc
logger = sc.get_logger()

By default, scipp’s logger outputs messages of level ‘warning’ and higher to sys.stderr. Log files can be set up by adding appropriate handlers to the logger.

[2]:
logger.info('Some general information')
[3]:
logger.warning('Be careful!')
[2021-11-10T14:27:49] WARNING  : Be careful!

When running in Jupyter notebooks, scipp also registers a special handler with its logger which sends all messages of level ‘info’ and above to a widget. The widget can be displayed using the following. (Click and drag the bottom right corner to increase the size of the widget and see all messages.)

[4]:
sc.display_logs()
[5]:
logger.info('Some more text that only shows up in the widget')
logger.error('Something went wrong!')
[2021-11-10T14:27:49] ERROR    : Something went wrong!

Note how both logs from before and after the call to scipp.display_logs are shown in the widget.

Tip: In Jupyter lab, you can show the widget in a separate tab and keep it visible. To do so, right-click the widget and select ‘Create New View for Output’.

Formatting scipp Objects

The widget can display the HTML representation of scipp containers (Variable, DataArray, Dataset):

[6]:
logger.warning(sc.arange('x', 0, 5))
[2021-11-10T14:27:49] WARNING  : <scipp.Variable> (x: 5)      int64  [dimensionless]  [0, 1, ..., 3, 4]

It is also possible to embed scipp containers in strings using %-formatting:

[7]:
logger.warning('The HTML representation of a Variable: %s', sc.arange('h', 10, 100))
[2021-11-10T14:27:49] WARNING  : The HTML representation of a Variable: <scipp.Variable> (h: 90)      int64  [dimensionless]  [10, 11, ..., 98, 99]

Or use %r to display a plain string representation:

[8]:
logger.warning('A Variable converted to string: %r', sc.arange('r', 100, 110))
[2021-11-10T14:27:49] WARNING  : A Variable converted to string: <scipp.Variable> (r: 10)      int64  [dimensionless]  [100, 101, ..., 108, 109]

The stream handler and all user defined handlers behave as normal and produce the string representation of scipp objects unless endowed with a custom formatter.

Advanced Configuration

Utilities for managing the logger and log widget can be found in scipp.logging.

It is possible to connect other loggers to the same widget by adding a scipp.logging.WidgetHandler:

[9]:
import logging
my_logger = logging.getLogger('my_logger')
my_logger.setLevel(logging.INFO)
my_logger.addHandler(sc.logging.WidgetHandler(logging.INFO,
                                              sc.logging.get_log_widget()))
[10]:
my_logger.info('My own logger can also send messages to the widget.')