YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
NetworkProfiler.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
7
8#include <yarp/os/Network.h>
9#include <yarp/os/LogStream.h>
11#include <yarp/os/Port.h>
13#include <yarp/os/Carrier.h>
14#include <yarp/companion/impl/Companion.h>
15#include <algorithm>
16
17using namespace yarp::os;
18using namespace yarp::profiler;
19using namespace yarp::profiler::graph;
20
21
22
23NetworkProfiler::ProgressCallback* NetworkProfiler::progCallback = nullptr;
24
26
27 // adding the ports and processor nodes
28 if (NetworkProfiler::progCallback) {
29 NetworkProfiler::progCallback->onProgress(0);
30 }
31
33 unsigned int itr_count = 0;
34 for(itr = details_set.begin(); itr!= details_set.end(); itr++) {
35 PortDetails details = (*itr);
36
37 // port node
38 PortVertex* port = new PortVertex(details.info.name);
39 if (!details.inputs.size() && !details.outputs.size()) {
40 port->property.put("orphan", true);
41 }
42 graph.insert(*port);
43
44 //process node (owner)
46 //prop.clear();
47 process->property.put("name", details.owner_process.process_name);
48 process->property.put("arguments", details.owner_process.arguments);
49 process->property.put("hostname", details.owner_process.owner_machine.hostname);
50 process->property.put("priority", details.owner_process.priority);
51 process->property.put("policy", details.owner_process.policy);
52 process->property.put("os", details.owner_process.owner_machine.os);
53 process->property.put("hidden", false);
54 auto itrVert=graph.insert(*process);
55 // create connection between ports and its process
56 if (dynamic_cast<ProcessVertex*>(*itrVert)) {
57 port->setOwner((ProcessVertex*)(*itrVert));
58 }
59
60
61 //machine node (owner of the process)
63 graph.insert(*machine);
64 //todo do the same done for the process.
65 process->setOwner(machine);
66
67 if (!details.inputs.size() && !details.outputs.size()) {
68 graph.insertEdge(*process, *port, Property("(type ownership) (dir unknown)"));
69 }
70
71 // calculate progress
72 if(NetworkProfiler::progCallback) {
73 NetworkProfiler::progCallback->onProgress((unsigned int) (++itr_count/((float)(details_set.size()*2)) * 100.0) );
74 }
75 }
76
77
78 // create connection between ports
79 for(itr = details_set.begin(); itr!= details_set.end(); itr++) {
80 PortDetails details = (*itr);
81 // find the current port vertex in the graph
82 pvertex_iterator vi1 = graph.find(PortVertex(details.info.name));
83 yAssert(vi1 != graph.vertices().end());
84 for(auto cnn : details.outputs) {
85 pvertex_iterator vi2 = graph.find(PortVertex(cnn.port_name));
86 if(vi2 != graph.vertices().end()) {
87 //yInfo()<<"connecting "<<(*vi1)->property.find("name").asString()<<"->"<<(*vi2)->property.find("name").asString();
88 Property edge_prop("(type connection)");
89 edge_prop.put("carrier", cnn.carrier);
90 graph.insertEdge(vi1, vi2, edge_prop);
91 } else {
92 yWarning() << "Found a nonexistent port (" << cnn.port_name << ")"
93 << "in the output list of" << (*vi1)->property.find("name").asString();
94 }
95 }
96 // calculate progress
97 if(NetworkProfiler::progCallback) {
98 NetworkProfiler::progCallback->onProgress((unsigned int) (++itr_count/((float)(details_set.size()*2)) * 100.0) );
99 }
100 }
101 if (NetworkProfiler::progCallback) {
102 NetworkProfiler::progCallback->onProgress(100); // is it really needed? :p
103 }
104 return true;
105}
106
108 subgraph.clear();
110 const pvertex_set& vertices = graph.vertices();
111 //insert machines
112 for(itr = vertices.begin(); itr!=vertices.end(); itr++) {
113
114 if (!dynamic_cast<MachineVertex*>(*itr)) {
115 continue;
116 } else {
117 auto* mv1 = dynamic_cast<MachineVertex*>(*itr);
118 if (mv1)
119 {
120 MachineVertex* mv2 = new MachineVertex(mv1->property.find("os").asString(),
121 mv1->property.find("hostname").asString());
122 mv2->property = mv1->property;
123 subgraph.insert(*mv2);
124 }
125 }
126 }
127
128 for(itr = vertices.begin(); itr!=vertices.end(); itr++) {
129 if (!dynamic_cast<ProcessVertex*>(*itr)) {
130 continue;
131 }
132 auto* pv1 = dynamic_cast<ProcessVertex*>(*itr);
133 if (pv1)
134 {
135 ProcessVertex* pv2 = new ProcessVertex(pv1->property.find("pid").asInt32(),
136 pv1->property.find("hostname").asString());
137 pv2->property = pv1->property;
138 subgraph.insert(*pv2);
139 }
140 }
141 // insert edges
142 for(itr = vertices.begin(); itr!=vertices.end(); itr++) {
143 if (!dynamic_cast<ProcessVertex*>(*itr)) {
144 continue;
145 }
146 Vertex* v1 = (*itr);
147 const edge_set& outs = v1->outEdges();
149 for(eitr = outs.begin(); eitr!=outs.end(); eitr++) {
150 const Edge& e = (*eitr);
151 const Vertex& p1 = e.second();
152
153 const edge_set& pouts = p1.outEdges();
155 for(peitr = pouts.begin(); peitr!=pouts.end(); peitr++) {
156 const Vertex& p2 = (*peitr).second();
157 Property prop((*peitr).property);
158 std::string label = p1.property.find("name").asString();
159 label.append(" - ").append(p2.property.find("name").asString());
160 prop.put("label", label);
161 subgraph.insertEdge(*v1, p2.outEdges()[0].second(), prop);
162 }
163 }
164 }
165 return true;
166}
167
169 std::string name;
170 switch(level) {
172 name = "NORMAL";
173 break;
174 }
176 name = "LOW";
177 break;
178 }
180 name = "HIGH";
181 break;
182 }
184 name = "CRITIC";
185 break;
186 }
188 name = "INVALID";
189 break;
190 }
191 default: {
192 name = "UNDEFINED";
193 }
194 };
195 return name;
196}
197
199 if (level == "NORMAL") {
201 }
202 if (level == "LOW") {
204 }
205 if (level == "HIGH") {
207 }
208 if (level == "CRITIC") {
210 }
211 if (level == "INVALID") {
213 }
215}
216
218 // adding all process nodes and subgraphs
220 const pvertex_set& vertices = graph.vertices();
221
222 for(itr = vertices.begin(); itr!=vertices.end(); itr++) {
223 const Vertex &v1 = (**itr);
224 for(const auto& i : v1.outEdges()) {
225 Edge& edge = (Edge&) i;
226 const Vertex &v2 = edge.second();
227 if(!v1.property.check("hidden") && !v2.property.check("hidden")) {
228 if(edge.property.find("type").asString() == "connection") {
229 //yInfo()<<v1.property.find("name").asString()<<"->"<<v2.property.find("name").asString()<<label;
231 if(yarp::os::NetworkBase::getConnectionQos(v1.property.find("name").asString(),
232 v2.property.find("name").asString(), fromStyle, toStyle)) {
233 // source
234 edge.property.put("FromThreadPriority", fromStyle.getThreadPriority());
235 edge.property.put("FromThreadPolicy", fromStyle.getThreadPolicy());
236 edge.property.put("FromPacketPriority", fromStyle.getPacketPriorityAsLevel());
237 edge.property.put("ToThreadPriority", toStyle.getThreadPriority());
238 edge.property.put("ToThreadPolicy", toStyle.getThreadPolicy());
239 edge.property.put("ToPacketPriority", toStyle.getPacketPriorityAsLevel());
240 } else {
241 yWarning() << "Cannot retrieve Qos property of" << v1.property.find("name").asString() << "->" << v2.property.find("name").asString();
242 }
243 }
244 }
245 }
246 }
247 return true;
248}
249
251
252 //e.g., atch in "(context yarpviz) (file portrate)"
253 yarp::os::Bottle cmd, reply;
254 cmd.addString("atch");
255 cmd.addString("in");
256 cmd.addString(pluginProp.toString());
257 //Property& prop = cmd.addDict();
258 //prop.fromString(pluginProp.toString());
259 //yInfo()<<cmd.toString();
261 bool ret = yarp::os::NetworkBase::write(srcCon, cmd, reply, true, true, 2.0);
262 if(!ret) {
263 yError()<<"Cannot write to"<<portName;
264 return false;
265 }
266 if(reply.get(0).asString() != "ok") {
267 yError()<<reply.toString();
268 return false;
269 }
270
271 return true;
272
273}
274
276 //e.g., dtch in
277 yarp::os::Bottle cmd, reply;
278 cmd.addString("dtch");
279 cmd.addString("in");
281 bool ret = yarp::os::NetworkBase::write(srcCon, cmd, reply, true, true, 2.0);
282 if(!ret) {
283 yError()<<"Cannot write to"<<portName;
284 return false;
285 }
286 if(reply.get(0).asString() != "ok") {
287 yError()<<reply.toString();
288 return false;
289 }
290 return true;
291}
292
294 //e.g., set in "/view" (log_raw 1)"
295 yarp::os::Bottle cmd, reply;
296 cmd.addString("set");
297 cmd.addString("in");
298 cmd.addString(portName.c_str());
299 Bottle tmp;
300 tmp.fromString(param.toString());
301 cmd.add(tmp.get(0));
303 bool ret = yarp::os::NetworkBase::write(srcCon, cmd, reply, true, true, 2.0);
304 if(!ret) {
305 yError()<<"Cannot write to"<<portName;
306 return false;
307 }
308 if(reply.size() > 1) {
309 if(reply.get(0).isString() && reply.get(0).asString() == "fail") {
310 yError()<<reply.toString();
311 return false;
312 }
313 else if(reply.get(0).isInt32() && reply.get(0).asInt32() == -1) {
314 yError()<<reply.toString();
315 return false;
316 }
317 }
318 return true;
319}
320
321bool NetworkProfiler::getPortmonitorParams(std::string portName, yarp::os::Bottle& param) {
322 //e.g., get in /portname"
324 cmd.addString("get");
325 cmd.addString("in");
326 cmd.addString(portName.c_str());
328 bool ret = yarp::os::NetworkBase::write(srcCon, cmd, param, true, true, 2.0);
329 if(!ret) {
330 yError()<<"Cannot write to"<<portName;
331 return false;
332 }
333 if(param.size() > 1) {
334 if(param.get(0).isString() && param.get(0).asString() == "fail") {
335 yError()<<param.toString();
336 return false;
337 }
338 else if(param.get(0).isInt32() && param.get(0).asInt32() == -1) {
339 yError()<<param.toString();
340 return false;
341 }
342 }
343 return true;
344}
edge_set::const_iterator edge_const_iterator
Definition Graph.h:31
pvertex_set::const_iterator pvertex_const_iterator
Definition Graph.h:35
std::vector< yarp::profiler::graph::Vertex * > pvertex_set
Definition Graph.h:33
pvertex_set::iterator pvertex_iterator
Definition Graph.h:34
std::vector< yarp::profiler::graph::Edge > edge_set
Definition Graph.h:29
bool ret
#define yError(...)
Definition Log.h:361
#define yAssert(x)
Definition Log.h:388
#define yWarning(...)
Definition Log.h:340
A simple collection of objects that can be described and transmitted in a portable way.
Definition Bottle.h:64
void add(const Value &value)
Add a Value to the bottle, at the end of the list.
Definition Bottle.cpp:309
size_type size() const
Gets the number of elements in the bottle.
Definition Bottle.cpp:251
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition Bottle.cpp:246
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition Bottle.cpp:170
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Definition Bottle.cpp:211
A mini-server for performing network communication in the background.
Represents how to reach a part of a YARP network.
Definition Contact.h:33
static Contact fromString(const std::string &txt)
Factory method.
Definition Contact.cpp:139
static bool getConnectionQos(const std::string &src, const std::string &dest, QosStyle &srcStyle, QosStyle &destStyle, bool quiet=true)
Gets the Qos preferences of a connection.
Definition Network.cpp:1182
static bool write(const Contact &contact, PortWriter &cmd, PortReader &reply, bool admin=false, bool quiet=false, double timeout=-1)
Send a single command to a port and await a single response.
Definition Network.cpp:1219
A class for storing options and configuration information.
Definition Property.h:33
std::string toString() const override
Return a standard text representation of the content of the object.
void put(const std::string &key, const std::string &value)
Associate the given key with the given string.
Definition Property.cpp:987
Preferences for the port's Quality of Service.
Definition QosStyle.h:23
PacketPriorityLevel
The PacketPriorityLevel defines the packets quality of service (priority) levels.
Definition QosStyle.h:30
virtual bool isString() const
Checks if value is a string.
Definition Value.cpp:156
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition Value.cpp:204
virtual bool isInt32() const
Checks if value is a 32-bit integer.
Definition Value.cpp:132
virtual std::string asString() const
Get string value.
Definition Value.cpp:234
ports_detail_set::iterator ports_detail_iterator
std::vector< PortDetails > ports_detail_set
virtual void onProgress(unsigned int percentage)
static bool getPortmonitorParams(std::string portName, yarp::os::Bottle &param)
static std::string packetPrioToString(yarp::os::QosStyle::PacketPriorityLevel level)
static bool attachPortmonitorPlugin(std::string portName, yarp::os::Property pluginProp)
static bool updateConnectionQosStatus(yarp::profiler::graph::Graph &graph)
static bool setPortmonitorParams(std::string portName, yarp::os::Property &param)
static yarp::os::QosStyle::PacketPriorityLevel packetStringToPrio(std::string level)
static bool creatNetworkGraph(ports_detail_set details, yarp::profiler::graph::Graph &graph)
creatNetworkGraph
static bool creatSimpleModuleGraph(yarp::profiler::graph::Graph &graph, yarp::profiler::graph::Graph &subgraph)
static bool detachPortmonitorPlugin(std::string portName)
The yarp::profiler::graph::Edge class.
Definition Graph.h:45
The yarp::profiler::graph::Graph class.
Definition Graph.h:104
void insertEdge(const Vertex &v1, const Vertex &v2, const yarp::os::Property &property="")
Definition Graph.cpp:144
const pvertex_set & vertices()
Definition Graph.h:126
const pvertex_iterator find(const Vertex &v1)
Definition Graph.cpp:160
pvertex_iterator insert(const Vertex &vertex)
Definition Graph.cpp:120
bool setOwner(yarp::profiler::graph::Vertex *_owner)
Definition Graph.h:166
The yarp::profiler::graph::Vertex class.
Definition Graph.h:72
yarp::os::Property property
Definition Graph.h:89
An interface to the operating system, including Port based communication.