Sending Metrics#
See also
For the basic concepts behind telemetry in Constellation and the available metric types check the chapter in the operator’s guide.
Metrics have to be registered before use. For satellite this can be done via:
register_metric("NAME", "unit", MetricsValue::LAST_VALUE);
A metric can then be send using the STAT
macros:
STAT("NAME", get_metric_value());
See also
There are also macros available to only send metrics every nth iteration or at most every t seconds. These macros are described in detail in the framework reference.
Metrics that are evaluated regularly from a lambda can also be registered:
register_timed_metric("NAME", "unit", MetricsValue::LAST_VALUE, 10s,
[this]() -> std::optional<double> {
return allowed_to_get_metric() ? std::optional(get_metric_value()) : std::nullopt;
});
The lambda can return either the value directly, or an optional, where the empty value means that the metric can currently
not be sent. To check if the satellite is in a given state the getState()
method can be used, or the following helper:
register_timed_metric("NAME", "unit", MetricsValue::LAST_VALUE, 10s,
{CSCP::State::ORBIT, CSCP::State::RUN},
[this]() { return get_metric_value(); }
);
Note that timed metrics can still be triggered manually if desired.
To send metrics (e.g. readings from a sensor), the schedule_metric
method can be used. The method takes a metric name,
the unit, a polling interval, a metric type and a callable function as arguments. The name of the metric will always be
converted to full caps.
Metric type: can be
LAST_VALUE
,ACCUMULATE
,AVERAGE
, orRATE
.Polling interval: a float value in seconds, indicating how often the metric is transmitted.
Callable function: Should return a single value (of any type), and take no arguments. If you have a callable that requires arguments, consider using
functools.partial
to fill in the necessary information at scheduling time. If the callback returnsNone
, no metric will be published.
An example call is shown below:
self.schedule_metric("Current", "A", MetricsType.LAST_VALUE, 10, self.device.get_current)
In this example, the callable self.device.get_current
fetches the current from a power supply every 10 seconds, and returns
the value return current
. The same can also be achieved with a function decorator:
@schedule_metric("A", MetricsType.LAST_VALUE, 10)
def Current(self) -> Any:
if self.device.can_read_current():
return self.device.get_current()
return None
Note that in this case, if None
is returned, no metric is sent. The name of the metric is taken from the function name.
Attention
Metrics registered with the function decorator are evaluated even if the satellite is not initialized yet. This means that it
might be necessary to check the existence of a variable using hasattr(self, "device")
first.