1.9. Get statistical data

Fast DDS Statistics Backend provides two overloads of get_data() to retrieve statistical data of a given DataKind within a time frame (for more information about all the reported DataKind, please refer to DataKind). This time interval is evenly divided into the specified number of bins, each one with size \((t_to - t_from)/(# of bins)\). For each of these bins, a new StatisticsData value is calculated applying the given StatisticKind to all the data points in it. The result is a collection of StatisticsData elements with size equal to the number of specified bins.

Important

If the number of bins is set to zero, then all data points are returned and no statistic is calculated for the series.

Depending on the DataKind, the data is related to one or two entities, e.g. FASTDDS_LATENCY measures the latency between a write operation on the data writer side and the notification to the user when the data is available on reader side, whereas HEARTBEAT_COUNT contains the amount of sent HEARTBEATs. Because of this difference, get_data() can take either one or two EntityId related to the DataKind in question. The following table illustrates the expected inputs depending on the query’s DataKind passed to get_data():

DataKind

Source collection EntityKind

Target collection EntityKind

FASTDDS_LATENCY

DATAWRITER

DATAREADER

NETWORK_LATENCY

PARTICIPANT

LOCATOR

PUBLICATION_THROUGHPUT

DATAWRITER

Not applicable

SUBSCRIPTION_THROUGHPUT

DATAREADER

Not applicable

RTPS_PACKETS_SENT

PARTICIPANT

LOCATOR

RTPS_BYTES_SENT

PARTICIPANT

LOCATOR

RTPS_PACKETS_LOST

PARTICIPANT

LOCATOR

RTPS_BYTES_LOST

PARTICIPANT

LOCATOR

RESENT_DATA

DATAWRITER

Not applicable

HEARTBEAT_COUNT

DATAWRITER

Not applicable

ACKNACK_COUNT

DATAREADER

Not applicable

NACKFRAG_COUNT

DATAREADER

Not applicable

GAP_COUNT

DATAWRITER

Not applicable

DATA_COUNT

DATAWRITER

Not applicable

PDP_PACKETS

PARTICIPANT

Not applicable

EDP_PACKETS

PARTICIPANT

Not applicable

DISCOVERY_TIME

PARTICIPANT

Not applicable

SAMPLE_DATAS

DATAWRITER

Not applicable

get_data() throws BadParameter if the calling parameters are not consistent.

get_data_supported_entity_kinds() can be used to get all the EntityKind pairs suitable for a given DataKind, according to this table.

  • For a DataKind that only relates to one Entity, the first element of the pair is the EntityKind of such Entity, while the second element is INVALID.

  • For a DataKind that relates to two Entities, the first element of the pair is the EntityKind of the source Entity, while the second element is the EntityKind of the target Entity.

The source and target pairs returned by this method are the source and target EntityKind accepted by get_data() for the given DataKind. This is convenient to prepare a call to get_data() from an EntityKind. First, call get_data_supported_entity_kinds() with the DataKind to get the EntityKind of the related entities. Then, call get_entities() to get the available entities of that kind. Finally, call get_data() with the pairs that get_entities() returns.

/* Get all the EntityKind pairs related to DISCOVERED_ENTITY. */
std::vector<std::pair<EntityKind, EntityKind>> types_list =
        StatisticsBackend::get_data_supported_entity_kinds(DataKind::DISCOVERY_TIME);

/* Iterate over all the valid pairs composing the final result */
std::vector<StatisticsData> discovery_times;
for (std::pair<EntityKind, EntityKind> type_pair : types_list)
{
    /* Take the data for this pair and append it to the existing data */
    std::vector<StatisticsData> tmp = StatisticsBackend::get_data(
        DataKind::DISCOVERY_TIME,
        StatisticsBackend::get_entities(type_pair.first, host1_id),
        StatisticsBackend::get_entities(type_pair.second, host2_id));

    discovery_times.insert(discovery_times.end(), tmp.begin(), tmp.end());
}

Warning

If for a given bin, the Fast DDS Statistics Backend has no data, the value returned will be the one supplied by std::numeric_limits<double>::quiet_NaN.

1.9.1. Examples

Following, some example queries are provided to serve a inspiration for applications using Fast DDS Statistics Backend.

1.9.1.1. DataWriter’s Fast DDS Latency median example

/* Get the DataReaders related to a given DataWriter */
std::vector<EntityId> datareaders = StatisticsBackend::get_entities(EntityKind::DATAREADER, datawriter_id);

/* Get the current time */
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();

/*
 * Get the median of the FASTDDS_LATENCY of the last 10 minutes, divided into ten bins,
 * between a given DataWriter and its related DataReaders. After the operation,
 * latency_data.size() is 10. Each of the elements of latency_data is a StatisticsData
 * element which represents the median of the FASTDDS_LATENCY of that minute.
 */
std::vector<StatisticsData> latency_data = StatisticsBackend::get_data(
    DataKind::FASTDDS_LATENCY,                                   // DataKind
    std::vector<EntityId>({datawriter_id}),                      // Source entities
    datareaders,                                                 // Target entities
    10,                                                          // Number of bins
    now - std::chrono::minutes(10),                              // t_from
    now,                                                         // t_to
    StatisticKind::MEDIAN);                                      // Statistic

1.9.1.2. Topic’s Fast DDS Latency mean example

/* Get the DataWriters and DataReaders in a Topic */
std::vector<EntityId> topic_datawriters = StatisticsBackend::get_entities(EntityKind::DATAWRITER, topic_id);
std::vector<EntityId> topic_datareaders = StatisticsBackend::get_entities(EntityKind::DATAREADER, topic_id);

/* Get the current time */
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();

/*
 * Get the median of the FASTDDS_LATENCY of the last 10 minutes, divided into ten bins,
 * between the DataWriters of Host 1 and the DataReaders of Host 2. After the operation,
 * latency_data.size() is 10. Each of the elements of latency_data is a StatisticsData
 * element which represents the median of the FASTDDS_LATENCY of that minute.
 */
std::vector<StatisticsData> latency_data = StatisticsBackend::get_data(
    DataKind::FASTDDS_LATENCY,                                   // DataKind
    topic_datawriters,                                           // Source entities
    topic_datareaders,                                           // Target entities
    10,                                                          // Number of bins
    now - std::chrono::minutes(10),                              // t_from
    now,                                                         // t_to
    StatisticKind::MEAN);                                        // Statistic

1.9.1.3. Topic’s Heartbeat count maximum example

std::vector<EntityId> participant_datawriters = StatisticsBackend::get_entities(EntityKind::DATAWRITER,
                participant_id);

/* Get the current time */
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();

/*
 * Get the maximum of the HEARTBEAT_COUNT of the last 10 minutes, divided into ten bins,
 * of the DataWriters of a given Participant. After the operation, heartbeat_data.size() is
 * 10. Each of the elements of heartbeat_data is a StatisticsData element which represents
 * the maximum of the HEARTBEAT_COUNT of that minute.
 */
std::vector<StatisticsData> heartbeat_data = StatisticsBackend::get_data(
    DataKind::HEARTBEAT_COUNT,                                   // DataKind
    participant_datawriters,                                     // Source entities
    10,                                                          // Number of bins
    now - std::chrono::minutes(10),                              // t_from
    now,                                                         // t_to
    StatisticKind::MAX);                                         // Statistic

1.9.1.4. Host to Host Fast DDS Latency all points example

It is also possible to retrieve all the data points of a given DataKind within the time frame. This is done by setting the number of bins to 0. In this case, the StatisticKind is ignored so it can be left to its default value.

std::vector<EntityId> host1_datawriters = StatisticsBackend::get_entities(EntityKind::DATAWRITER, host1_id);
std::vector<EntityId> host2_datareaders = StatisticsBackend::get_entities(EntityKind::DATAREADER, host2_id);

/* Get the current time */
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();

/*
 * Get all the FASTDDS_LATENCY data points of the last 10 minutes between the DataWriters
 * of Host 1 and the DataReaders of Host 2. data.size() == total number of data points
 * received. Since bins is 0, the statistic is left as default.
 */
std::vector<StatisticsData> data = StatisticsBackend::get_data(
    DataKind::FASTDDS_LATENCY,                                   // DataKind
    host1_datawriters,                                           // Source entities
    host2_datareaders,                                           // Target entities
    0,                                                           // Number of bins
    now - std::chrono::minutes(10),                              // t_from
    now);                                                        // t_to

For more information about the available DataKind and StatisticKind please refer to DataKind and StatisticKind respectively.