ProfilerStorage.cpp
Go to the documentation of this file.
1/*
2 * This file is part of ArmarX.
3 *
4 * Copyright (C) 2012-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 MemoryX::component::ProfilerStorage
19 * @author haass ( tobias dot haass at student dot kit dot edu )
20 * @author Manfred Kroehnert ( manfred dot kroehnert at kit dot edu )
21 * @date 2013, 2015
22 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
23 * GNU General Public License
24 */
25
26
27#include "ProfilerStorage.h"
28
29#include <IceUtil/Time.h>
30
33
40#include <mongo/client/dbclient.h>
41
42namespace memoryx
43{
44 std::string
46 {
47 return "ProfilerStorage";
48 }
49
50 std::string
52 {
53 return "ProfilerStorage";
54 }
55
56 void
58 {
59 setTag("ProfilerStorage");
60
64
65 enabled = getProperty<bool>("enabled").getValue();
66
67 if (enabled)
68 {
69 usingTopic(armarx::Profiler::PROFILER_TOPIC_NAME);
70 }
71
72 saveTimeout = getProperty<int>("SaveTimeout").getValue();
73 saveToLongtermMemoryTask =
74 new armarx::RunningTask<ProfilerStorage>(this, &ProfilerStorage::saveToLongtermMemory);
75 saveTransitionsToLongtermMemoryTask = new armarx::RunningTask<ProfilerStorage>(
76 this, &ProfilerStorage::saveTransitionsToLongtermMemory);
77
78 // the initial transition does not have a source state, thus the name of the initial transition is empty
79 memorySnapshot = CreateProfilerMemorySnapshot("", workingMemoryPrx);
80 }
81
82 void
84 {
85 getProxy(commonStoragePrx, getCommonStorageName());
86 getProxy(workingMemoryPrx, getWorkingMemoryName());
87 getProxy(longtermMemoryPrx, getLongtermMemoryName());
88 profilerDataSegmentPrx = longtermMemoryPrx->getProfilerDataSegment();
89
90 saveToLongtermMemoryTask->start();
91 saveTransitionsToLongtermMemoryTask->start();
92 }
93
94 void
98
99 void
101 {
102 enabled = false;
103 saveToLongtermMemoryTask->stop();
104 saveTransitionsToLongtermMemoryTask->stop();
105 }
106
107 void
108 ProfilerStorage::saveToLongtermMemory()
109 {
110 IceUtil::Time t = IceUtil::Time::now();
111
112 while (enabled)
113 {
114 size_t logSize = entityLog.size();
115
116 if (logSize == 0)
117 {
118 continue;
119 }
120
121 if ((logSize < 1000) && ((IceUtil::Time::now() - t).toMilliSeconds() < saveTimeout))
122 {
123 continue;
124 }
125
126 EntityBaseList entityLogCopy;
127 {
128 std::scoped_lock lock(entityLogMutex);
129 entityLog.swap(entityLogCopy);
130 }
131 t = IceUtil::Time::now();
132 profilerDataSegmentPrx->addEntityList(entityLogCopy);
133 ARMARX_WARNING_S << "Took " << (IceUtil::Time::now() - t).toMilliSeconds()
134 << " [ms] to add " << entityLogCopy.size() << " Entities";
135 t = IceUtil::Time::now();
136 }
137 }
138
139 void
140 ProfilerStorage::saveTransitionsToLongtermMemory()
141 {
142 IceUtil::Time t = IceUtil::Time::now();
143
144 while (enabled)
145 {
146 size_t logSize = transitionSnapshotList.size();
147
148 if (logSize == 0)
149 {
150 continue;
151 }
152
153 if ((logSize < 1000) && ((IceUtil::Time::now() - t).toMilliSeconds() < saveTimeout))
154 {
155 continue;
156 }
157
158 TransitionSnapshotList transitionSnapshotListCopy;
159 {
160 std::scoped_lock lock(transitionSnapshotListMutex);
161 transitionSnapshotList.swap(transitionSnapshotListCopy);
162 }
163 t = IceUtil::Time::now();
164
165 for (TransitionSnapshot& snapshot : transitionSnapshotListCopy)
166 {
167 std::string sourceSnapshot = profilerDataSegmentPrx->saveUniqueMemorySnapshot(
168 snapshot.sourceStateMemorySnapshot);
169 std::string targetSnapshot = profilerDataSegmentPrx->saveUniqueMemorySnapshot(
170 snapshot.targetStateMemorySnapshot);
171 EntityRefBasePtr sourceSnapshotRef =
172 profilerDataSegmentPrx->getEntityRefById(sourceSnapshot);
173 EntityRefBasePtr targetSnapshotRef =
174 profilerDataSegmentPrx->getEntityRefById(targetSnapshot);
175 ProfilerTransitionPtr profilerTransition =
176 new memoryx::ProfilerTransition(snapshot.transition.parentStateIdentifier,
177 snapshot.transition.sourceStateIdentifier,
178 snapshot.transition.targetStateIdentifier,
179 sourceSnapshotRef,
180 targetSnapshotRef,
181 1);
182 std::string entityId =
183 profilerDataSegmentPrx->saveOrUpdateTransition(profilerTransition);
184 }
185 ARMARX_WARNING_S << "Took " << (IceUtil::Time::now() - t).toMilliSeconds()
186 << " [ms] to add " << transitionSnapshotListCopy.size()
187 << " Transitions";
188 t = IceUtil::Time::now();
189 }
190 }
191
192 void
194 const std::string&,
195 Ice::Int,
196 Ice::Int,
197 const Ice::Current&)
198 {
199 // ignore network traffic for now
200 }
201
202 void
203 ProfilerStorage::reportEvent(const armarx::ProfilerEvent& profilerEvent, const Ice::Current&)
204 {
205 std::scoped_lock lock(entityLogMutex);
206 entityLog.push_back(new memoryx::ProfilerEvent(profilerEvent));
207 }
208
209 void
211 const armarx::ProfilerStatechartTransition& transition,
212 const ::Ice::Current& context)
213 {
214 std::scoped_lock lock(transitionSnapshotListMutex);
215 TransitionSnapshot transitionSnapshot;
216 transitionSnapshot.transition = transition;
217 transitionSnapshot.sourceStateMemorySnapshot = memorySnapshot;
218 memorySnapshot =
219 CreateProfilerMemorySnapshot(transition.targetStateIdentifier, workingMemoryPrx);
220 transitionSnapshot.targetStateMemorySnapshot = memorySnapshot;
221 transitionSnapshotList.push_back(transitionSnapshot);
222 }
223
224 void
226 const armarx::ProfilerStatechartParameters& inputParameters,
227 const Ice::Current&)
228 {
229 }
230
231 void
233 const armarx::ProfilerStatechartParameters& localParameters,
234 const Ice::Current&)
235 {
236 }
237
238 void
240 const armarx::ProfilerStatechartParameters& outputParameters,
241 const Ice::Current&)
242 {
243 }
244
245 void
246 ProfilerStorage::reportProcessCpuUsage(const armarx::ProfilerProcessCpuUsage& process,
247 const Ice::Current& context)
248 {
249 std::scoped_lock lock(entityLogMutex);
250 entityLog.push_back(new memoryx::ProfilerProcess(process));
251 }
252
253 void
254 ProfilerStorage::reportProcessMemoryUsage(const armarx::ProfilerProcessMemoryUsage& memoryUsage,
255 const Ice::Current& context)
256 {
257 std::scoped_lock lock(entityLogMutex);
258 entityLog.push_back(new memoryx::ProfilerMemoryUsage(memoryUsage));
259 }
260
261 void
262 ProfilerStorage::reportEventList(const armarx::ProfilerEventList& events, const Ice::Current&)
263 {
264 memoryx::EntityBaseList eventEntities(events.size());
265 std::transform(events.begin(),
266 events.end(),
267 eventEntities.begin(),
268 [](const armarx::ProfilerEvent& event)
269 { return new memoryx::ProfilerEvent(event); });
270
271 {
272 std::scoped_lock lock(entityLogMutex);
273 entityLog.insert(entityLog.end(), eventEntities.begin(), eventEntities.end());
274 }
275 }
276
277 void
279 const armarx::ProfilerStatechartTransitionList& transitions,
280 const Ice::Current&)
281 {
282 if (transitions.empty())
283 {
284 return;
285 }
286
287 TransitionSnapshotList transitionSnapshots(transitions.size());
288
289 ProfilerMemorySnapshotPtr sourceMemorySnapshot = memorySnapshot->clone();
290
291 std::transform(transitions.begin(),
292 transitions.end(),
293 transitionSnapshots.begin(),
294 [](const armarx::ProfilerStatechartTransition& transition)
295 {
296 TransitionSnapshot transitionSnapshot = {transition,
297 new ProfilerMemorySnapshot(),
298 new ProfilerMemorySnapshot()};
299 return transitionSnapshot;
300 });
301
302 transitionSnapshots.front().sourceStateMemorySnapshot = sourceMemorySnapshot;
304 transitionSnapshots.back().transition.targetStateIdentifier, workingMemoryPrx);
305 if (memorySnapshot)
306 {
307 transitionSnapshots.back().targetStateMemorySnapshot = memorySnapshot;
308 }
309 {
310 std::scoped_lock lock(transitionSnapshotListMutex);
311 transitionSnapshotList.insert(transitionSnapshotList.end(),
312 transitionSnapshots.begin(),
313 transitionSnapshots.end());
314 }
315 }
316
317 void
319 const armarx::ProfilerStatechartParametersList& inputParametersList,
320 const Ice::Current&)
321 {
322 }
323
324 void
326 const armarx::ProfilerStatechartParametersList& localParametesList,
327 const Ice::Current&)
328 {
329 }
330
331 void
333 const armarx::ProfilerStatechartParametersList& outputParametersList,
334 const Ice::Current&)
335 {
336 }
337
338 void
339 ProfilerStorage::reportProcessCpuUsageList(const armarx::ProfilerProcessCpuUsageList& processes,
340 const Ice::Current&)
341 {
342 memoryx::EntityBaseList eventEntities(processes.size());
343 std::transform(processes.begin(),
344 processes.end(),
345 eventEntities.begin(),
346 [](const armarx::ProfilerProcessCpuUsage& process)
347 { return new memoryx::ProfilerProcess(process); });
348
349 {
350 std::scoped_lock lock(entityLogMutex);
351 entityLog.insert(entityLog.end(), eventEntities.begin(), eventEntities.end());
352 }
353 }
354
355 void
357 const armarx::ProfilerProcessMemoryUsageList& memoryUsages,
358 const Ice::Current&)
359 {
360 memoryx::EntityBaseList eventEntities(memoryUsages.size());
361 std::transform(memoryUsages.begin(),
362 memoryUsages.end(),
363 eventEntities.begin(),
364 [](const armarx::ProfilerProcessMemoryUsage& memoryUsage)
365 { return new memoryx::ProfilerMemoryUsage(memoryUsage); });
366
367 {
368 std::scoped_lock lock(entityLogMutex);
369 entityLog.insert(entityLog.end(), eventEntities.begin(), eventEntities.end());
370 }
371 }
372
375 const std::string& stateName,
376 const WorkingMemoryInterfacePrx& workingMemoryProxy)
377 {
378 if (!workingMemoryProxy)
379 {
380 return new ProfilerMemorySnapshot(stateName, Ice::Context());
381 }
382
383 Ice::Context snapshot;
384
385 memoryx::ObjectInstancePtr humanInstance = memoryx::ObjectInstancePtr::dynamicCast(
386 workingMemoryProxy->getObjectInstancesSegment()->getObjectInstanceByName("human"));
387 if (humanInstance)
388 {
389 snapshot["human"] = humanInstance->getAttribute("name")->getValue()->getString();
390 if (humanInstance->hasAttribute("humanObject"))
391 {
392 snapshot["humanObject"] =
393 humanInstance->getAttribute("humanObject")->getValue()->getString();
394 }
395
396 if (humanInstance->hasAttribute("intention"))
397 {
398 snapshot["intention"] =
399 humanInstance->getAttribute("intention")->getValue()->getString();
400 }
401 }
402
403 memoryx::ObjectInstancePtr objectInstance = memoryx::ObjectInstancePtr::dynamicCast(
404 workingMemoryProxy->getObjectInstancesSegment()->getObjectInstanceByName("taskObject"));
405 if (objectInstance)
406 {
407 snapshot["taskObject"] = objectInstance->getAttribute("name")->getValue()->getString();
408
409 bool inHand = objectInstance->getAttribute("inHand")->getValue()->getBool();
410 snapshot["objectInHand"] = inHand ? "true" : "false";
411 }
412
413 return new ProfilerMemorySnapshot(stateName, snapshot);
414 }
415
416 std::string
418 {
419 return getProperty<std::string>("CommonStorageName").getValue();
420 }
421
422 std::string
424 {
425 return getProperty<std::string>("WorkingMemoryName").getValue();
426 }
427
428 std::string
430 {
431 return getProperty<std::string>("LongtermMemoryName").getValue();
432 }
433
440
441 void
443 const armarx::ProfilerStatechartTransitionWithParameters& transition,
444 const Ice::Current& context)
445 {
446 }
447
448 void
450 const armarx::ProfilerStatechartTransitionWithParametersList& transitions,
451 const Ice::Current&)
452 {
453 }
454
457 {
459 "SaveTimeout", 500, "How often should the statistics be saved (ms)");
461 "CommonStorageName", "CommonStorage", "Name of the CommonStorage proxy to use");
463 "WorkingMemoryName", "WorkingMemory", "Name of the WorkingMemory proxy to use");
465 "LongtermMemoryName", "LongtermMemory", "Name of the LongtermMemory proxy to use");
466 defineOptionalProperty<bool>("enabled", true, "disable/enable saver");
467 }
468} // namespace memoryx
469
#define ARMARX_REGISTER_COMPONENT_EXECUTABLE(ComponentT, applicationName)
Definition Decoupled.h:29
ComponentPropertyDefinitions(std::string prefix, bool hasObjectNameParameter=true)
Definition Component.cpp:46
std::string getConfigIdentifier()
Retrieve config identifier for this component as set in constructor.
Definition Component.cpp:90
Property< PropertyType > getProperty(const std::string &name)
void setTag(const LogTag &tag)
Definition Logging.cpp:54
bool usingProxy(const std::string &name, const std::string &endpoints="")
Registers a proxy for retrieval after initialization and adds it to the dependency list.
void usingTopic(const std::string &name, bool orderedPublishing=false)
Registers a proxy for subscription after initialization.
Ice::ObjectPrx getProxy(long timeoutMs=0, bool waitForScheduler=true) const
Returns the proxy of this object (optionally it waits for the proxy)
std::string prefix
Prefix of the properties such as namespace, domain, component name, etc.
PropertyDefinition< PropertyType > & defineOptionalProperty(const std::string &name, PropertyType defaultValue, const std::string &description="", PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
A brief description.
void reportProcessCpuUsage(const armarx::ProfilerProcessCpuUsage &process, const Ice::Current &context=Ice::emptyCurrent) override
void reportStatechartOutputParametersList(const armarx::ProfilerStatechartParametersList &outputParametersList, const Ice::Current &=Ice::emptyCurrent) override
void onInitComponent() override
void reportStatechartTransitionWithParameters(const armarx::ProfilerStatechartTransitionWithParameters &transition, const ::Ice::Current &context=Ice::emptyCurrent) override
void reportProcessMemoryUsage(const armarx::ProfilerProcessMemoryUsage &memoryUsage, const Ice::Current &context=Ice::emptyCurrent) override
void reportStatechartTransitionWithParametersList(const armarx::ProfilerStatechartTransitionWithParametersList &transitions, const Ice::Current &=Ice::emptyCurrent) override
void onDisconnectComponent() override
void reportStatechartInputParametersList(const armarx::ProfilerStatechartParametersList &inputParametersList, const Ice::Current &=Ice::emptyCurrent) override
armarx::PropertyDefinitionsPtr createPropertyDefinitions() override
void reportStatechartOutputParameters(const armarx::ProfilerStatechartParameters &outputParameters, const Ice::Current &=Ice::emptyCurrent) override
void reportStatechartTransitionList(const armarx::ProfilerStatechartTransitionList &transitions, const Ice::Current &=Ice::emptyCurrent) override
void reportStatechartLocalParametersList(const armarx::ProfilerStatechartParametersList &localParametesList, const Ice::Current &=Ice::emptyCurrent) override
void reportStatechartTransition(const armarx::ProfilerStatechartTransition &transition, const ::Ice::Current &context=Ice::emptyCurrent) override
void reportNetworkTraffic(const std::string &, const std::string &, Ice::Int, Ice::Int, const Ice::Current &context=Ice::emptyCurrent) override
reportNetworkTraffic
void reportEventList(const armarx::ProfilerEventList &events, const Ice::Current &=Ice::emptyCurrent) override
void onConnectComponent() override
static std::string GetDefaultName()
static ProfilerMemorySnapshotPtr CreateProfilerMemorySnapshot(const std::string &stateName, const WorkingMemoryInterfacePrx &workingMemoryProxy)
void reportProcessMemoryUsageList(const armarx::ProfilerProcessMemoryUsageList &memoryUsages, const Ice::Current &=Ice::emptyCurrent) override
void reportEvent(const armarx::ProfilerEvent &profilerEvent, const Ice::Current &context=Ice::emptyCurrent) override
void reportStatechartInputParameters(const armarx::ProfilerStatechartParameters &inputParameters, const Ice::Current &=Ice::emptyCurrent) override
void reportStatechartLocalParameters(const armarx::ProfilerStatechartParameters &localParameters, const Ice::Current &=Ice::emptyCurrent) override
void reportProcessCpuUsageList(const armarx::ProfilerProcessCpuUsageList &processes, const Ice::Current &=Ice::emptyCurrent) override
std::string getDefaultName() const override
#define ARMARX_WARNING_S
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:213
IceUtil::Handle< class PropertyDefinitionContainer > PropertyDefinitionsPtr
PropertyDefinitions smart pointer type.
VirtualRobot headers.
IceInternal::Handle< ProfilerMemorySnapshot > ProfilerMemorySnapshotPtr
IceInternal::Handle< ProfilerTransition > ProfilerTransitionPtr
IceInternal::Handle< ObjectInstance > ObjectInstancePtr