1.6. Get entities’ graph

Warning

This feature is currently not supported. It will be implemented on a future release of Fast DDS Statistics Backend. Furthermore, the graph structure may change.

Fast DDS Statistics Backend allows to retrieve the entire graph of entities for which the singleton holds statistics data. The result of this query is a Graph tree structure that contains the EntityId and names of each entity. To be able to understand and interpret this tree, it is required to know about all the available entities and the inner relations between them. Following, there is a diagram of the relation between the Fast DDS Statistics Backend entities, and how are they divided into physical and domain related. For more information about the different EntityKind please refer to EntityKind.

../../_images/internal_db.svg

Fast DDS Statistics Backend entity relations and their division into physical and domain related.

For the following example, a simple scenario is considered, where there is one process running two participants on the same domain; one with a data reader and the other one with a data writer (both in the same topic). This means that there is only one USER within a single HOST. The application can retrieve the network graph by:

Graph graph = StatisticsBackend::get_graph();

In this example, the previous call would return a Graph object similar to the following:

{
    "hosts":
    [
        {
            "entity_id": "1",
            "name": "example_host",
            "alias": "example_host_alias",
            "alive": true,
            "users":
            [
                {
                    "entity_id": "2",
                    "name": "example_user",
                    "alias": "example_user_alias",
                    "alive": true,
                    "processes":
                    [
                        {
                            "entity_id": "3",
                            "name": "example_process_1",
                            "alias": "example_process_1_alias",
                            "alive": true,
                            "pid": "9564",
                            "participants":
                            [
                                "4"
                            ]
                        },
                        {
                            "entity_id": "8",
                            "name": "example_process_2",
                            "alias": "example_process_2_alias",
                            "alive": true,
                            "pid": "9565",
                            "participants":
                            [
                                "9"
                            ]
                        }
                    ]
                }
            ]
        }
    ],
    "locators":
    [
        {
            "entity_id": "7",
            "name": "127.0.0.1:7412",
            "alias": "localhost_1",
            "alive": true,
            "datareaders":
            [
            ],
            "datawriters":
            [
                "6"
            ]
        },
        {
            "entity_id": "11",
            "name": "127.0.0.1:7414",
            "alias": "localhost_2",
            "alive": true,
            "datareaders":
            [
                "10"
            ],
            "datawriters":
            [
            ]
        }
    ],
    "domains":
    [
        {
            "entity_id": "0",
            "name": "0",
            "alias": "domain_0_alias",
            "alive": true,
            "participants":
            [
                {
                    "entity_id": "4",
                    "name": "participant_1",
                    "alias": "participant_1_alias",
                    "alive": true,
                    "guid": "01.0f.22.cd.59.64.04.00.02.00.00.00|00.00.01.c1",
                    "process": "3",
                    "datareaders":
                    [
                    ],
                    "datawriters":
                    [
                        {
                            "entity_id": "6",
                            "name": "datawriter_1",
                            "alias": "datawriter_1_alias",
                            "alive": true,
                            "guid": "01.0f.22.cd.59.64.04.00.02.00.00.00|00.00.01.03",
                            "topic": "5",
                            "locators":
                            [
                                "7"
                            ]
                        }
                    ]
                },
                {
                    "entity_id": "9",
                    "name": "participant_2",
                    "alias": "participant_2_alias",
                    "alive": false,
                    "guid": "01.0f.22.cd.59.64.04.00.05.00.00.00|00.00.01.c1",
                    "process": "8",
                    "datareaders":
                    [
                        {
                            "entity_id": "10",
                            "name": "datareader_1",
                            "alias": "datareader_1_alias",
                            "alive": false,
                            "guid": "01.0f.22.cd.59.64.04.00.05.00.00.00|00.00.01.04",
                            "topic": "5",
                            "locators":
                            [
                                "11"
                            ]
                        }
                    ],
                    "datawriters":
                    [
                    ]
                }
            ],
            "topics":
            [
                {
                    "entity_id": "5",
                    "name": "example_topic",
                    "alias": "example_topic_alias",
                    "alive": true,
                    "data_type": "example_data_type",
                    "datareaders":
                    [
                        "10"
                    ],
                    "datawriters":
                    [
                        "6"
                    ]
                }
            ]
        }
    ]
}

Then, the application can extract information about the active entities from the graph as shown below:

// Iterate over hosts
for (const auto& host : graph["hosts"])
{
    if (host["alive"])
    {
        std::cout << "Host name: " << host["name"] << std::endl;
        std::cout << "Host alias: " << host["alias"] << std::endl;
        // Iterate over users
        for (const auto& user : host["users"])
        {
            if (user["alive"])
            {
                std::cout << "\tUser name: " << user["name"] << std::endl;
                std::cout << "\tUser alias: " << user["alias"] << std::endl;
                // Iterate over processes
                for (const auto& process : user["processes"])
                {
                    if (process["alive"])
                    {
                        std::cout << "\t\tProcess name: " << process["name"] << std::endl;
                        std::cout << "\t\tProcess alias: " << process["alias"] << std::endl;
                        std::cout << "\t\tProcess PID:  " << process["pid"] << std::endl;
                        // Iterate over the list of participant IDs
                        for (const auto& participant_id : process["participants"])
                        {
                            // Look for the actual participant in the domains
                            for (const auto& domain : graph["domains"])
                            {
                                for (const auto& participant : domain["participants"])
                                {
                                    // Check if the participant is the one that is being looked for
                                    if (participant["entity_id"] == participant_id && participant["alive"])
                                    {
                                        std::cout << "\t\t\tParticipant name: " << participant["name"] <<
                                            std::endl;
                                        std::cout << "\t\t\tParticipant alias: " << participant["alias"] <<
                                            std::endl;
                                        std::cout << "\t\t\tParticipant GUID: " << participant["guid"] <<
                                            std::endl;
                                        // Iterate over data writers
                                        for (const auto& datawriter : participant["datawriters"])
                                        {
                                            if (datawriter["alive"])
                                            {
                                                std::cout << "\t\t\t\tDatawriter name: " <<
                                                    datawriter["name"] << std::endl;
                                                std::cout << "\t\t\t\tDatawriter alias: " <<
                                                    datawriter["alias"] << std::endl;
                                                std::cout << "\t\t\t\tDatawriter GUID: " <<
                                                    datawriter["guid"] << std::endl;
                                                // Iterate over topics
                                                for (const auto& topic : domain["topics"])
                                                {
                                                    // Check if the topic is the one that is being looked for
                                                    if (topic["entity_id"] == datawriter["topic"])
                                                    {
                                                        std::cout << "\t\t\t\tDatawriter topic name: " <<
                                                            topic["name"] << std::endl;
                                                        std::cout << "\t\t\t\tDatareader topic alias: " <<
                                                            topic["alias"] << std::endl;
                                                        break;
                                                    }
                                                }
                                                // Iterate over the list of locator IDs
                                                for (const auto& locator_id : datawriter["locators"])
                                                {
                                                    for (const auto& locator : graph["locators"])
                                                    {
                                                        // Check if the locator is the one that is being looked for
                                                        if (locator["entity_id"] == locator_id)
                                                        {
                                                            std::cout << "\t\t\t\tDatawriter locator name: " <<
                                                                locator["name"] << std::endl;
                                                            std::cout << "\t\t\t\tDatawriter locator alias: " <<
                                                                locator["alias"] << std::endl;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                        // Iterate over data readers
                                        for (const auto& datareader : participant["datareaders"])
                                        {
                                            if (datareader["alive"])
                                            {
                                                std::cout << "\t\t\t\tDatareader name: " <<
                                                    datareader["name"] << std::endl;
                                                std::cout << "\t\t\t\tDatareader alias: " <<
                                                    datareader["alias"] << std::endl;
                                                std::cout << "\t\t\t\tDatareader GUID: " <<
                                                    datareader["guid"] << std::endl;
                                                // Iterate over topics
                                                for (const auto& topic : domain["topics"])
                                                {
                                                    // Check if the topic is the one that is being looked for
                                                    if (topic["entity_id"] == datareader["topic"])
                                                    {
                                                        std::cout << "\t\t\t\tDatareader topic name: " <<
                                                            topic["name"] << std::endl;
                                                        std::cout << "\t\t\t\tDatareader topic alias: " <<
                                                            topic["alias"] << std::endl;
                                                        break;
                                                    }
                                                }
                                                // Iterate over the list of locator IDs
                                                for (const auto& locator_id : datareader["locators"])
                                                {
                                                    for (const auto& locator : graph["locators"])
                                                    {
                                                        // Check if the locator is the one that is being looked for
                                                        if (locator["entity_id"] == locator_id)
                                                        {
                                                            std::cout << "\t\t\t\tDatareader locator name: " <<
                                                                locator["name"] << std::endl;
                                                            std::cout << "\t\t\t\tDatareader locator alias: " <<
                                                                locator["alias"] << std::endl;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

Running the previous snippet on the given example should output:

Host name: "example_host"
Host alias: "example_host_alias"
    User name: "example_user"
    User name: "example_user_alias"
        Process name: "example_process_1"
        Process alias: "example_process_1_alias"
        Process PID:  "9564"
            Participant name: "participant_1"
            Participant alias: "participant_1_alias"
            Participant GUID: "01.0f.22.cd.59.64.04.00.02.00.00.00|00.00.01.c1"
                Datawriter name: "datawriter_1"
                Datawriter alias: "datawriter_1_alias"
                Datawriter GUID: "01.0f.22.cd.59.64.04.00.02.00.00.00|00.00.01.03"
                Datawriter topic name: "example_topic"
                Datawriter topic alias: "example_topic_alias"
                Datawriter locator name: "127.0.0.1:7412"
                Datawriter locator alias: "localhost_1"
        Process name: "example_process_2"
        Process alias: "example_process_2_alias"
        Process PID:  "9565"

For more information about the operations available with Graph objects, please refer to Graph.