Metrics

Metrics provide a convenient mechanism for recording information about the system’s state. Metrics are declared and used similarly to all other reactor elements. A MetricDeclaration can be used to declare a metric as part of a reactor. Consider the following example, which extends the Motor reactor from above so that it has a metric _current, which is used to record the current measured on the motor.

class Motor(xronos.Reactor):
    angle = xronos.InputPortDeclaration()
    _timer = xronos.PeriodicTimerDeclaration(
        period=datetime.timedelta(microseconds=500)
    )
    _current = xronos.MetricDeclaration(description="Motor current", unit="mA")

    def __init__(self):
        super().__init__()
        self.add_attribute("motor", self.name)

    @xronos.reaction
    def control(self, interface):
        interface.add_trigger(self._timer)
        current_effect = interface.add_effect(self._current)

        def handler():
            current_effect.record(read_current())
            # do control

        return handler

When declaring a metric, a description needs to be provided and optionally a unit can be set. It is also possible to provide additional attributes via MetricDeclaration or by using add_attribute() or add_attributes() on the metric.

In the example above, the control reaction executes every 500 microseconds. It reads and records the measured current using record(). The control algorithm is omitted from the example.

See Telemetry for instructions on how to enable collection of telemetry data and Visualizing Metrics for instruction on how to visualize data recorded from metrics.