Telemetry Recorder
Overview
The Telemetry Recorder is a reusable component that reads telemetry data from a specific shared memory queue and stores it into FITS files. In addition, the component can also read related data from other sources and store them into supporting FITS files or human-readable CSV files.
A Telemetry Recorder instance only supports one recording session at a time, therefore instrument RTC developers should foresee multiple recorder instances if the need for multiple, concurrent recording sessions arises.
A Telemetry Recorder hosts a user-defined set of recording units, where each unit ingests data from a specific source and writes it into a corresponding FITS file. This allows recording different data streams concurrently in a single recording session.
Commands
A Telemetry Recorder component can be steered by sending commands to its provided MAL interface. The set of commands that is currently available is indicated in the following table together with the expected behaviour:
Command |
Behaviour |
|---|---|
Init |
Initialises the component:
|
Exit |
Terminates the process. |
Stop |
Stops an ongoing initialisation procedure started by the Init command. |
Reset |
Resets the state of the component to the state before Init was received. |
Enable |
No particular actions are performed here. |
Disable |
No particular actions are performed here. |
Update |
Reloads dynamic component configuration. |
Run |
Starts a new recording session:
|
Idle |
Stops an ongoing recording session:
|
Recover |
recovers from a failed recording session:
|
After receiving the Init and Enable commands, a new recording session can be started with command Run and stopped with command Idle.
Once a recording session is started and the component is in state On::Operational::Running, it ingests data from various sources and writes it to a set of output files located in folder $DATAROOT/component_id/session_id/.
In case the recorder is configured to stop recording on its own, it will automatically transition to state On::Operational::Idle once a configurable stop-condition is met. In this case, it is not necessary to send the Idle command.
In case a recording session fails, the component transitions to state On::Operational::Error. Error recovery can be requested by sending the command Recover.
Customisation
Instrument RTC developers customise the Telemetry Recorder by selecting and adding recording units as required. Recording unit objects of different types are constructed with specific arguments and then passed to the component via dependency injection. This means, coarse component customisation happens already at compile-time where different recording units are composed together. For fine-grained customisation, recording units can also be configured at run-time using dedicated configuration parameters that are explained later.
Note
A tutorial on how to create a custom Telemetry Recorder is provided in the Telemetry Recorder Tutorial.
To facilitate fast and uniform component development, the RTC Toolkit provides an initial set of recording unit types that can be instantiated and added to a Telemetry Recorder:
IpcqRecordingUnit: Listens to an IPCQ shared memory topic and writes data samples into FITS binary tables. For customisation, the unit is parametrised with a RecordingInfo trait class.
DataPointRecordingUnit: Records datapoints from the Runtime Repository or OLDB into FITS binary tables. For customisation, the unit is parametrised with the Datapoint Type and the Datapoint Path.
DynamicDataPointRecordingUnit: Records datapoints from the Runtime Repository or OLDB into FITS binary tables. Datapoints are read from the Runtime Repo. For customisation, a custom RecorderFactory can be supplied, otherwise recording will be done to FITS files.
EventRecordingUnit: Records arbitrary JSON events into JSON lines (.jsonl) text files. For customisation, the unit can be parametrised an optional FilterFunction to filter out unwanted samples.
To provide sufficient degrees of freedom, multiple instances of the same recording unit type can be created and added to the recorder component.
If necessary, it is possible to implement and add totally custom recording units to cover specific needs. This can be achieved by creating a new recording unit class that inherits from the base class RecordingUnit, which defines a common interface and provides basic functionality. When implementing the custom unit, the toolkit-provided FitsDataRecorder class can be used to store ingested data as FITS binary tables. Alternatively, a CsvDataRecorder class can be used to store ingested data as CSV files. The main drawback of the FitsDataRecorder is that it requires all data to be fixed length for a recording session. This is done to prevent performance issues in the recording stemming from the way dynamically-sized types are stored in FITS binary tables. To still be able to crop fixed-sized data, a dedicated method SetColumnLength can be used. Note that the CsvDataRecorder does not have this restriction.
Configuration
The configuration of a Telemetry Recorder can be divided into recording session configuration and recording unit configuration.
Recording Session Configuration
Currently the following recording session configuration options are supported:
Parameter |
Nature |
Type |
Description |
|---|---|---|---|
session_id |
dynamic |
string |
unique identifier of the current/last recording session. |
The session_id needs to be updated from sequencer scripts or custom recorder GUIs before starting a new recording session.
Recording Unit Configuration
The following recording unit configuration options are common to all recording unit types:
Parameter |
Nature |
Type |
Description |
|---|---|---|---|
leader_list |
static |
vector_string |
[optional] list of recording units that can trigger and stop the recording of this unit. |
If the leader_list parameter is present and non-empty, the leader/follower functionality is enabled for this particular recording unit. The follower unit starts recording after the first leader has started and it will stop recording after the last leader has finished. With this feature, recording units can be chained together such that e.g. interesting datapoints are being recorded when a leading shared memory recording unit starts or stops.
IPCQ Recording Unit
The following configuration options are specific to IPCQ recording units:
Parameter |
Nature |
Type |
Description |
|---|---|---|---|
shm_queue_name |
static |
string |
name of the ipcq. |
cpu_affinity |
static |
int32 |
[optional] CPU affinity setting for the thread that reads from the IPCQ and writes to disk. |
telemetry_subset |
dynamic |
vector_string |
[optional] Only record the given parts of the topic. |
subsample_factor |
dynamic |
int64 |
Defines how many samples shall be skipped after each read sample. To record every sample, set it to 1, to record every 10th, set it to 10. |
start_at_sample_id |
dynamic |
int64 |
Have the recording unit wait for a minimum sample_id, before starting the recording and triggering of its followers. To start immediately, set it to 0. |
stop_after_num_samples |
dynamic |
int64 |
This lets the recording unit stop automatically after having recorded the given amount of samples. To not stop automatically, set it to 0. |
If present, the optional telemetry_subset parameter allows to specify a subset of telemetry data columns that should be recorded, this means that only a subset of data that is read from SHM is actually written to file.
A subsample_factor larger than 1 changes the reading pattern of the recording unit to subsampled mode, where 1 sample is read and then N-1 samples are skipped (note that N is the value for the subsample_factor).
If start_at_sample_id is set to zero, the unit will start recording immediatly. A value N (larger than zero) will cause the unit to defer recording to file until the received sample id matches N.
If stop_after_num_samples is set to zero, the unit keeps on recording until it is explicitly stopped. A value N (larger than zero) will cause the unit to stop automatically after N samples have been recorded.
DataPoint Recording Unit
The following configuration options are specific to DataPoint recording units:
Parameter |
Nature |
Type |
Description |
|---|---|---|---|
capture_mask |
static |
int32 |
bit mask to configure wheter data should be captured on_start, on_stop or on_change. |
The binary capture mask can be set as follows:
capture on_start: Bit 1
capture on_stop: Bit 2
capture on_change: Bit 3
As an example, capture_mask value 3 means to capture on_start and on_stop.
Dynamic DataPoint Recording Unit
The following configuration options are specific to Dynamic DataPoint recording units:
Parameter |
Nature |
Type |
Description |
|---|---|---|---|
datapoint_list |
static |
vector_string |
List of Datapoints to record. Requires prefix: “rtr:” for runtime repo or “oldb:” for OLDB DataPoints. |
The Dynmic Datapoint Recording Unit creates internal DataPoint Recording Units, which can be configured by changing the settings for the recording unit with the same unit_id, but suffixed with “_nn”, where nn is the two digit numbered entry in the datapoint_list.
Event Recording Unit
The following configuration options are specific to this type of unit:
Parameter |
Nature |
Type |
Description |
|---|---|---|---|
topic_name |
static |
string |
event channel topic name. |
Configuration Example
The following example configuration shows a Telemetry Recorder with a leading IPCQ recording unit and a following DataPoint recording unit:
static:
rec_units:
ipcq_unit:
shm_queue_name: !cfg.type:string exampleTelRecQueue
cpu_affinity: !cfg.type:int32 0
dp_unit:
leader_list: !cfg.type:vector_string [ipcq_unit]
capture_mask: !cfg.type:int32 3
dynamic:
session_id: !cfg.type:string session_42
rec_units:
ipcq_unit:
telemetry_subset: !cfg.type:vector_string [intensities, slopes]
subsample_factor: !cfg.type:int64 10
start_at_sample_id: !cfg.type:int64 0
stop_after_num_samples: !cfg.type:int64 10
The IPCQ recording unit is configured to record 10 samples from exampleTelRecQueue, starting immediately when the first sample arrives (from sample id 0) with a subsample_factor of 10. The unit is pinned to core 0 and the telemetry_subset is configured such that only the two columns intensities and slopes are recorded.
The following DataPoint recording unit records a runtime repository datapoint both at the start and at the end of the recording session.
Monitoring
For each Telemetry Recorder instance the following monitoring data points are published to OLDB:
Parameter |
Type |
Description |
|---|---|---|
state |
string |
current component state (retrieved from state machine engine). |
Recording Session Monitoring
In addition, the following recording session information is published to OLDB:
Parameter |
Type |
Description |
|---|---|---|
session_info/session_id |
string |
unique identifier of the current/last recording session. |
session_info/files_produced |
vector_string |
list of FITS files produced. |
session_info/files_size |
vector_string |
sizes of produced FITS files in bytes. |
session_info/total_size |
string |
total size of FITS files produced in bytes. |
session_info/space_info/capacity |
string |
storage capacity in bytes. |
session_info/space_info/free |
string |
free storage in bytes. |
session_info/space_info/available |
string |
available storage in bytes. |
This can be used to get detailed information about the ongoing recording session. Note that this information can also be integrated into custom Recorder GUIs.
Recording Unit Monitoring
For more fine-grained monitoring, individual recording units also publish monitoring information to OLDB. Since the composition of recording units is user defined, the overall set of available monitoring datapoints depends on the user customisation.
The following monitoring attributes are common to all types of recording units:
Note that UNIT_ID is only a placeholder for the user-defined recording unit identifier.
Parameter |
Type |
Description |
|---|---|---|
rec_units/UNIT_ID/state |
string |
current state (Stopped, Preparing, Idle, Waiting, Running, Finished, Failed). |
rec_units/UNIT_ID/type |
string |
type of the recording unit (IPCQ, DataPoint, TypedEvent, JsonEvent). |
The following table describes each recording unit state closer:
Unit State |
Description |
|---|---|
Stopped |
The unit was just constructed.
This usually happens when the component receives the command |
Preparing |
The unit is preparing for operation (spawn threads, load configuration)
This usually happens when the component receives the command |
Idle |
The unit is ready to receive a start signal. |
Waiting |
The unit got a start signal but is waiting for an additional condition.
The condition can be |
Running |
The unit is currently recording. |
Finished |
The unit sucessfully finished its recording.
This happens when the component receives the command |
Failed |
The unit aborted recording due to some error. |
IPCQ Recording Unit
The following monitoring data points are specific to IPCQ recording units:
Parameter |
Type |
Description |
|---|---|---|
rec_units/UNIT_ID/queue_name |
string |
name of the shared memory queue. |
metrics/counter/UNIT_ID/samples_written |
int64 |
performance counter: number of samples written in this session. |
metrics/counter/UNIT_ID/last_sample_id_written |
int64 |
performance counter: id of last sample written to file. |
metrics/counter/UNIT_ID/frequency_estimate |
double |
performance counter: Estimated frequency of the data writer [Hz]. |
metrics/counter/UNIT_ID/duration_estimate |
int64 |
performance counter: Duration of writing data to file [us]. |
metrics/counter/UNIT_ID/buffer_occupancy |
double |
performance counter: SHM read buffer occupancy [%]. |
Data Point Recording Unit
The following monitoring data points are specific to Datapoint recording units:
Parameter |
Type |
Description |
|---|---|---|
rec_units/UNIT_ID/dp_name |
string |
path name of the datapoint to record. |
metrics/counter/UNIT_ID/samples_written |
int64 |
performance counter: number of samples written in this session. |
Typed Event and JSON Event Recording Unit
The following monitoring data points are specific to Typed Event and JSON Event recording units:
Parameter |
Type |
Description |
|---|---|---|
rec_units/UNIT_ID/topic_name |
string |
name of the DDS event topic to record. |
metrics/counter/UNIT_ID/samples_written |
int64 |
performance counter: number of samples written in this session. |
Errors
Not Operational
The main errors that can occur during component initialisation are caused by wrong or missing mandatory configuration parameters.
Operational
While the Telemetry Recorder is running the main sources of errors are:
Problems while opening, resetting or reading from the shared memory queue.
Problems while opening, writing or closing the FITS file.
Limitations and Known Issues
At this point, not all toolkit-provided recording units are optimised for performance.
Only FITS binary tables and human readable JSON lines files are supported as output formats. Recording units that can produce FITS keywords will be added in a sub-sequent release.
Currently, recording units based on the FitsDataWriter do not support the following data types:
std::complex,MatrixSpan.The capture mask for
DynamicDataPointRecordingUnitis not applied to sub-units (RTCTK-1371).