ProfilerObserver.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5 *
6 * ArmarX is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ArmarX is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * @package Core::observers::ProfilerObserver
19 * @author Manfred Kroehnert (manfred dot kroehnert at kit dot edu)
20 * @date 2015
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24
25#include "ProfilerObserver.h"
26
27#include <algorithm>
28#include <set>
29
30#include <ArmarXCore/core/services/profiler/Profiler.h> // for ProfilerPtr
31
37
41
42std::string
44{
45 return "ProfilerObserver";
46}
47
48void
50{
51 usingTopic(armarx::Profiler::PROFILER_TOPIC_NAME);
52}
53
54void
56{
57 offerChannel("activeStateChanged",
58 "Channel reporting the currently active state of statecharts with EnableProfiling "
59 "property set");
60 offerDataField("activeStateChanged",
61 "activeState",
63 "Name of the currently active state");
64 offerConditionCheck(checks::equals, new ConditionCheckEquals());
65 offerConditionCheck(checks::updated, new ConditionCheckUpdated());
66 offerConditionCheck(checks::changed, new ConditionCheckChanged());
67 offerConditionCheck(checks::valid, new ConditionCheckValid());
68
69 setDataField("activeStateChanged", "activeState", "");
70}
71
72void
74 const std::string& protocol,
75 Ice::Int inBytes,
76 Ice::Int outBytes,
77 const Ice::Current&)
78{
79 try
80 {
81 if (!existsChannel(id))
82 {
83 offerChannel(id, "Network traffic");
84 }
85
87 id, protocol + "_inBytes", Variant(inBytes), "Incoming network traffic");
89 id, protocol + "_outBytes", Variant(outBytes), "Outgoing network traffic");
90 updateChannel(id);
91 }
92 catch (...)
93 {
95 }
96}
97
98void
99armarx::ProfilerObserver::reportEvent(const armarx::ProfilerEvent& event, const Ice::Current&)
100{
101 std::string stateIdentifier = event.parentName;
102 try
103 {
104 createStateChannelIfRequired(stateIdentifier);
105
106 int microsecondsModifier = 0;
107 if (event.timestampUnit == "ms")
108 {
109 microsecondsModifier = 1000;
110 }
111 else if (event.timestampUnit == "us")
112 {
113 microsecondsModifier = 1;
114 }
115
116 TimestampVariant timestamp(event.timestamp * microsecondsModifier);
117 if (event.functionName ==
119 {
120 setDataField(stateIdentifier, "lastEnterTimestamp", timestamp);
121 }
122 else
123 {
124 VariantPtr lastActiveState = VariantPtr::dynamicCast(getDataField(
125 new DataFieldIdentifier(getName(), stateIdentifier, "activeSubstate")));
126 setDataField(stateIdentifier, "lastExitTimestamp", timestamp);
127 setDataField(stateIdentifier, "activeSubstate", Variant(""));
128 if (lastActiveState)
129 {
130 setDataFieldFlatCopy(stateIdentifier, "previousSubstate", lastActiveState);
131 }
132 }
133 updateChannel(stateIdentifier);
134 ARMARX_INFO << "Updating function info channel " << stateIdentifier;
135 }
136 catch (...)
137 {
139 }
140}
141
142void
143armarx::ProfilerObserver::reportProcessCpuUsage(const ProfilerProcessCpuUsage& process,
144 const Ice::Current&)
145{
146 std::string id = process.processName + std::to_string(process.processId);
147
148 try
149 {
150 createResourceChannelIfRequired(id);
151
152 setDataField(id, "cpuUsage", Variant(process.cpuUsage));
153 updateChannel(id);
154 }
155 catch (...)
156 {
158 }
159}
160
161void
162armarx::ProfilerObserver::reportProcessMemoryUsage(const ProfilerProcessMemoryUsage& memoryUsage,
163 const Ice::Current&)
164{
165 std::string id = memoryUsage.processName + std::to_string(memoryUsage.processId);
166
167 try
168 {
169 createResourceChannelIfRequired(id);
170
171 setDataField(id, "memoryUsage", Variant(memoryUsage.memoryUsage));
172 updateChannel(id);
173 }
174 catch (...)
175 {
177 }
178}
179
180void
181armarx::ProfilerObserver::reportStatechartTransition(const ProfilerStatechartTransition& transition,
182 const Ice::Current&)
183{
184 try
185 {
186 Variant activeSubstate(transition.targetStateIdentifier);
187 setDataField("activeStateChanged", "activeState", activeSubstate);
188 updateChannel("activeStateChanged");
189
190 std::string stateIdentifier = transition.parentStateIdentifier;
191 createStateChannelIfRequired(stateIdentifier);
192
193 setDataField(stateIdentifier, "activeSubstate", activeSubstate);
195 stateIdentifier, "previousSubstate", Variant(transition.sourceStateIdentifier));
196 setDataField(stateIdentifier, "lastEventName", Variant(transition.eventName));
197 updateChannel(stateIdentifier);
198 ARMARX_INFO << "Updating Transition info channel " << stateIdentifier;
199 }
200 catch (...)
201 {
203 }
204}
205
206void
207armarx::ProfilerObserver::StateParameterToVariantMap(const armarx::StateParameterMap& parameterMap,
208 armarx::StringValueMap& variantMap)
209{
210 for (auto& entry : parameterMap)
211 {
212 variantMap.addElement(entry.first, entry.second->value);
213 }
214}
215
216void
218 const ProfilerStatechartParameters& inputParameters,
219 const Ice::Current&)
220{
221 try
222 {
223 createStateChannelIfRequired(inputParameters.stateIdentifier);
224
225 StringValueMap parameters(false);
226 StateParameterToVariantMap(inputParameters.parameterMap, parameters);
227 setDataField(inputParameters.stateIdentifier, "inputParameters", parameters);
228
229 updateChannel(inputParameters.stateIdentifier);
230 }
231 catch (...)
232 {
234 }
235}
236
237void
239 const ProfilerStatechartParameters& localParameters,
240 const Ice::Current&)
241{
242 try
243 {
244 createStateChannelIfRequired(localParameters.stateIdentifier);
245
246 StringValueMap parameters(false);
247 StateParameterToVariantMap(localParameters.parameterMap, parameters);
248 setDataField(localParameters.stateIdentifier, "localParameters", parameters);
249
250 updateChannel(localParameters.stateIdentifier);
251 }
252 catch (...)
253 {
255 }
256}
257
258void
260 const ProfilerStatechartParameters& outputParameters,
261 const Ice::Current&)
262{
263 try
264 {
265 createStateChannelIfRequired(outputParameters.stateIdentifier);
266
267 StringValueMap parameters(false);
268 StateParameterToVariantMap(outputParameters.parameterMap, parameters);
269 setDataField(outputParameters.stateIdentifier, "outputParameters", parameters);
270 updateChannel(outputParameters.stateIdentifier);
271 }
272 catch (...)
273 {
275 }
276}
277
278void
280 const armarx::ProfilerStatechartTransitionWithParameters& outputParameters,
281 const Ice::Current&)
282{
283 // ignore this in the observer
284}
285
286void
287armarx::ProfilerObserver::createStateChannelIfRequired(const std::string& channelName)
288{
289 std::unique_lock lock(channelCheckMutex);
290 if (existsChannel(channelName))
291 {
292 return;
293 }
294
295 offerChannel(channelName, "Statechart State Channel");
296
297 offerDataField(channelName, "activeSubstate", VariantType::String, "Currently Active Substate");
298 offerDataField(channelName, "previousSubstate", VariantType::String, "Last Active Substate");
299 offerDataField(channelName, "lastEventName", VariantType::String, "Last Event/Transition Name");
300 offerDataField(
301 channelName, "inputParameters", VariantType::VariantContainer, "State Input Parameters");
302 offerDataField(
303 channelName, "localParameters", VariantType::VariantContainer, "State Local Parameters");
304 offerDataField(
305 channelName, "outputParameters", VariantType::VariantContainer, "State Output Parameters");
306 offerDataField(channelName,
307 "lastEnterTimestamp",
309 "Timestamp of when onEnter() of the state was last called");
310 offerDataField(channelName,
311 "lastExitTimestamp",
313 "Timestamp of when onExit() or onBreak() of the state was last called");
314}
315
316void
317armarx::ProfilerObserver::createResourceChannelIfRequired(const std::string& channelName)
318{
319 std::unique_lock lock(channelCheckMutex);
320 if (existsChannel(channelName))
321 {
322 return;
323 }
324
325 offerChannel(channelName, "Resource Information");
326
327 offerDataField(channelName,
328 "cpuUsage",
330 "Cpu Usage of process specified by the channelname");
331 offerDataField(channelName,
332 "memoryUsage",
334 "Memory Usage of process specified by the channelname");
335}
336
337void
338armarx::ProfilerObserver::reportEventList(const armarx::ProfilerEventList& events,
339 const Ice::Current&)
340{
341 // ignore these events in the observer
342}
343
344void
346 const armarx::ProfilerStatechartTransitionList& transitions,
347 const Ice::Current&)
348{
349 armarx::ProfilerStatechartTransition lastTransition = transitions.back();
351 "activeStateChanged", "activeState", Variant(lastTransition.targetStateIdentifier));
352 updateChannel("activeStateChanged");
353}
354
355void
357 const ProfilerStatechartParametersList& inputParametersList,
358 const Ice::Current&)
359{
360 // remove all but the latest occurence of an entry in the list of profiler entries
361 auto compareFunction =
362 [](const ProfilerStatechartParameters& lhs, const ProfilerStatechartParameters& rhs)
363 { return lhs.stateIdentifier < rhs.stateIdentifier; };
364 std::set<ProfilerStatechartParameters, decltype(compareFunction)> latestElements(
365 inputParametersList.rbegin(), inputParametersList.rend(), compareFunction);
366
367 for (const auto& element : latestElements)
368 {
370 }
371}
372
373void
375 const ProfilerStatechartParametersList& localParametersList,
376 const Ice::Current&)
377{
378 // remove all but the latest occurence of an entry in the list of profiler entries
379 auto compareFunction =
380 [](const ProfilerStatechartParameters& lhs, const ProfilerStatechartParameters& rhs)
381 { return lhs.stateIdentifier < rhs.stateIdentifier; };
382 std::set<ProfilerStatechartParameters, decltype(compareFunction)> latestElements(
383 localParametersList.rbegin(), localParametersList.rend(), compareFunction);
384
385 for (const auto& element : latestElements)
386 {
388 }
389}
390
391void
393 const ProfilerStatechartParametersList& outputParametersList,
394 const Ice::Current&)
395{
396 // remove all but the latest occurence of an entry in the list of profiler entries
397 auto compareFunction =
398 [](const ProfilerStatechartParameters& lhs, const ProfilerStatechartParameters& rhs)
399 { return lhs.stateIdentifier < rhs.stateIdentifier; };
400 std::set<ProfilerStatechartParameters, decltype(compareFunction)> latestElements(
401 outputParametersList.rbegin(), outputParametersList.rend(), compareFunction);
402
403 for (const auto& element : latestElements)
404 {
406 }
407}
408
409void
411 const armarx::ProfilerStatechartTransitionWithParametersList& outputParameters,
412 const Ice::Current&)
413{
414 // ignore this in the observer
415}
416
417void
418armarx::ProfilerObserver::reportProcessCpuUsageList(const ProfilerProcessCpuUsageList& processes,
419 const Ice::Current&)
420{
421 // remove all but the latest occurence of an entry in the list of profiler entries
422 auto compareFunction =
423 [](const ProfilerProcessCpuUsage& lhs, const ProfilerProcessCpuUsage& rhs)
424 { return lhs.processId < rhs.processId; };
425 std::set<ProfilerProcessCpuUsage, decltype(compareFunction)> latestElements(
426 processes.rbegin(), processes.rend(), compareFunction);
427
428 for (const auto& element : latestElements)
429 {
430 reportProcessCpuUsage(element);
431 }
432}
433
434void
436 const ProfilerProcessMemoryUsageList& memoryUsages,
437 const Ice::Current&)
438{
439 // remove all but the latest occurence of an entry in the list of profiler entries
440 auto compareFunction =
441 [](const ProfilerProcessMemoryUsage& lhs, const ProfilerProcessMemoryUsage& rhs)
442 { return lhs.processId < rhs.processId; };
443 std::set<ProfilerProcessMemoryUsage, decltype(compareFunction)> latestElements(
444 memoryUsages.rbegin(), memoryUsages.rend(), compareFunction);
445
446 for (const auto& element : latestElements)
447 {
449 }
450}
std::string timestamp()
Checks if the relevant data fields have been updated since the installation of this condition.
Checks if the numbers published in the relevant data fields equal a reference value.
Checks if the relevant data fields have been updated since the installation of this condition.
Checks if the relevant data fields contain valid values.
DataFieldIdentifier provide the basis to identify data field within a distributed ArmarX scenario.
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
std::string getName() const
Retrieve name of object.
bool existsChannel(const std::string &channelName) const
void offerChannel(std::string channelName, std::string description)
Offer a channel.
Definition Observer.cpp:131
void offerDataField(std::string channelName, std::string datafieldName, VariantTypeId type, std::string description)
Offer a datafield without default value.
Definition Observer.cpp:201
void offerConditionCheck(std::string checkName, ConditionCheck *conditionCheck)
Offer a condition check.
Definition Observer.cpp:301
void updateChannel(const std::string &channelName, const std::set< std::string > &updatedDatafields=std::set< std::string >())
Update all conditions for a channel.
Definition Observer.cpp:788
TimedVariantBasePtr getDataField(const DataFieldIdentifierBasePtr &identifier, const Ice::Current &c=Ice::emptyCurrent) const
Retrieve data field from observer.
void setDataField(const std::string &channelName, const std::string &datafieldName, const Variant &value, bool triggerFilterUpdate=true)
set datafield with datafieldName and in channel channelName
Definition Observer.cpp:508
void setDataFieldFlatCopy(const std::string &channelName, const std::string &datafieldName, const VariantPtr &value, bool triggerFilterUpdate=true)
Definition Observer.cpp:548
bool offerOrUpdateDataField(std::string channelName, std::string datafieldName, const Variant &value, const std::string &description)
Definition Observer.cpp:242
void reportStatechartInputParametersList(const ProfilerStatechartParametersList &inputParametersList, const ::Ice::Current &=Ice::emptyCurrent) override
void onConnectObserver() override
Framework hook.
void reportNetworkTraffic(const std::string &id, const std::string &protocol, Ice::Int inBytes, Ice::Int outBytes, const Ice::Current &=Ice::emptyCurrent) override
void reportStatechartTransition(const ProfilerStatechartTransition &transition, const Ice::Current &=Ice::emptyCurrent) override
void reportEventList(const ProfilerEventList &events, const Ice::Current &=Ice::emptyCurrent) override
void reportProcessMemoryUsage(const ProfilerProcessMemoryUsage &memoryUsage, const Ice::Current &=Ice::emptyCurrent) override
void reportStatechartTransitionList(const ProfilerStatechartTransitionList &transitions, const Ice::Current &=Ice::emptyCurrent) override
void reportProcessCpuUsageList(const ProfilerProcessCpuUsageList &processes, const Ice::Current &=Ice::emptyCurrent) override
void reportStatechartTransitionWithParametersList(const ProfilerStatechartTransitionWithParametersList &outputParameters, const Ice::Current &=Ice::emptyCurrent) override
void reportProcessCpuUsage(const ProfilerProcessCpuUsage &process, const Ice::Current &=Ice::emptyCurrent) override
void reportEvent(const ProfilerEvent &event, const Ice::Current &=Ice::emptyCurrent) override
void reportStatechartLocalParametersList(const ProfilerStatechartParametersList &localParametersList, const Ice::Current &=Ice::emptyCurrent) override
void reportStatechartOutputParametersList(const ProfilerStatechartParametersList &outputParametersList, const Ice::Current &=Ice::emptyCurrent) override
void reportStatechartInputParameters(const ProfilerStatechartParameters &inputParametes, const Ice::Current &=Ice::emptyCurrent) override
void onInitObserver() override
Framework hook.
void reportStatechartTransitionWithParameters(const ProfilerStatechartTransitionWithParameters &outputParameters, const Ice::Current &=Ice::emptyCurrent) override
void reportProcessMemoryUsageList(const ProfilerProcessMemoryUsageList &memoryUsages, const Ice::Current &=Ice::emptyCurrent) override
void reportStatechartLocalParameters(const ProfilerStatechartParameters &localParameters, const Ice::Current &=Ice::emptyCurrent) override
void reportStatechartOutputParameters(const ProfilerStatechartParameters &outputParameters, const Ice::Current &=Ice::emptyCurrent) override
std::string getDefaultName() const override
Retrieve default name of component.
static std::string GetEventName(Profiler::EventType eventType)
getEventName maps enum values from armarx::Profiler::Profiler::EventType to strings
Definition Profiler.cpp:33
The StringValueMap class is a subclass of VariantContainer and is comparable to a std::map<std::strin...
void addElement(const std::string &key, const VariantContainerBasePtr &variantContainer, const Ice::Current &c=Ice::emptyCurrent) override
Implements a Variant type for timestamps.
The Variant class is described here: Variants.
Definition Variant.h:224
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
const VariantTypeId Timestamp
const VariantTypeId VariantContainer
const VariantTypeId String
Definition Variant.h:921
const VariantTypeId Int
Definition Variant.h:917
const VariantTypeId Float
Definition Variant.h:919
void handleExceptions()
IceInternal::Handle< Variant > VariantPtr
Definition Variant.h:41