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
32
39#include <mongo/client/dbclient.h>
40
41namespace memoryx
42{
43 std::string
45 {
46 return "ProfilerStorage";
47 }
48
49 void
51 {
52 setTag("ProfilerStorage");
53
57
58 enabled = getProperty<bool>("enabled").getValue();
59
60 if (enabled)
61 {
62 usingTopic(armarx::Profiler::PROFILER_TOPIC_NAME);
63 }
64
65 saveTimeout = getProperty<int>("SaveTimeout").getValue();
66 saveToLongtermMemoryTask =
67 new armarx::RunningTask<ProfilerStorage>(this, &ProfilerStorage::saveToLongtermMemory);
68 saveTransitionsToLongtermMemoryTask = new armarx::RunningTask<ProfilerStorage>(
69 this, &ProfilerStorage::saveTransitionsToLongtermMemory);
70
71 // the initial transition does not have a source state, thus the name of the initial transition is empty
72 memorySnapshot = CreateProfilerMemorySnapshot("", workingMemoryPrx);
73 }
74
75 void
77 {
78 getProxy(commonStoragePrx, getCommonStorageName());
79 getProxy(workingMemoryPrx, getWorkingMemoryName());
80 getProxy(longtermMemoryPrx, getLongtermMemoryName());
81 profilerDataSegmentPrx = longtermMemoryPrx->getProfilerDataSegment();
82
83 saveToLongtermMemoryTask->start();
84 saveTransitionsToLongtermMemoryTask->start();
85 }
86
87 void
91
92 void
94 {
95 enabled = false;
96 saveToLongtermMemoryTask->stop();
97 saveTransitionsToLongtermMemoryTask->stop();
98 }
99
100 void
101 ProfilerStorage::saveToLongtermMemory()
102 {
103 IceUtil::Time t = IceUtil::Time::now();
104
105 while (enabled)
106 {
107 size_t logSize = entityLog.size();
108
109 if (logSize == 0)
110 {
111 continue;
112 }
113
114 if ((logSize < 1000) && ((IceUtil::Time::now() - t).toMilliSeconds() < saveTimeout))
115 {
116 continue;
117 }
118
119 EntityBaseList entityLogCopy;
120 {
121 std::scoped_lock lock(entityLogMutex);
122 entityLog.swap(entityLogCopy);
123 }
124 t = IceUtil::Time::now();
125 profilerDataSegmentPrx->addEntityList(entityLogCopy);
126 ARMARX_WARNING_S << "Took " << (IceUtil::Time::now() - t).toMilliSeconds()
127 << " [ms] to add " << entityLogCopy.size() << " Entities";
128 t = IceUtil::Time::now();
129 }
130 }
131
132 void
133 ProfilerStorage::saveTransitionsToLongtermMemory()
134 {
135 IceUtil::Time t = IceUtil::Time::now();
136
137 while (enabled)
138 {
139 size_t logSize = transitionSnapshotList.size();
140
141 if (logSize == 0)
142 {
143 continue;
144 }
145
146 if ((logSize < 1000) && ((IceUtil::Time::now() - t).toMilliSeconds() < saveTimeout))
147 {
148 continue;
149 }
150
151 TransitionSnapshotList transitionSnapshotListCopy;
152 {
153 std::scoped_lock lock(transitionSnapshotListMutex);
154 transitionSnapshotList.swap(transitionSnapshotListCopy);
155 }
156 t = IceUtil::Time::now();
157
158 for (TransitionSnapshot& snapshot : transitionSnapshotListCopy)
159 {
160 std::string sourceSnapshot = profilerDataSegmentPrx->saveUniqueMemorySnapshot(
161 snapshot.sourceStateMemorySnapshot);
162 std::string targetSnapshot = profilerDataSegmentPrx->saveUniqueMemorySnapshot(
163 snapshot.targetStateMemorySnapshot);
164 EntityRefBasePtr sourceSnapshotRef =
165 profilerDataSegmentPrx->getEntityRefById(sourceSnapshot);
166 EntityRefBasePtr targetSnapshotRef =
167 profilerDataSegmentPrx->getEntityRefById(targetSnapshot);
168 ProfilerTransitionPtr profilerTransition =
169 new memoryx::ProfilerTransition(snapshot.transition.parentStateIdentifier,
170 snapshot.transition.sourceStateIdentifier,
171 snapshot.transition.targetStateIdentifier,
172 sourceSnapshotRef,
173 targetSnapshotRef,
174 1);
175 std::string entityId =
176 profilerDataSegmentPrx->saveOrUpdateTransition(profilerTransition);
177 }
178 ARMARX_WARNING_S << "Took " << (IceUtil::Time::now() - t).toMilliSeconds()
179 << " [ms] to add " << transitionSnapshotListCopy.size()
180 << " Transitions";
181 t = IceUtil::Time::now();
182 }
183 }
184
185 void
187 const std::string&,
188 Ice::Int,
189 Ice::Int,
190 const Ice::Current&)
191 {
192 // ignore network traffic for now
193 }
194
195 void
196 ProfilerStorage::reportEvent(const armarx::ProfilerEvent& profilerEvent, const Ice::Current&)
197 {
198 std::scoped_lock lock(entityLogMutex);
199 entityLog.push_back(new memoryx::ProfilerEvent(profilerEvent));
200 }
201
202 void
204 const armarx::ProfilerStatechartTransition& transition,
205 const ::Ice::Current& context)
206 {
207 std::scoped_lock lock(transitionSnapshotListMutex);
208 TransitionSnapshot transitionSnapshot;
209 transitionSnapshot.transition = transition;
210 transitionSnapshot.sourceStateMemorySnapshot = memorySnapshot;
211 memorySnapshot =
212 CreateProfilerMemorySnapshot(transition.targetStateIdentifier, workingMemoryPrx);
213 transitionSnapshot.targetStateMemorySnapshot = memorySnapshot;
214 transitionSnapshotList.push_back(transitionSnapshot);
215 }
216
217 void
219 const armarx::ProfilerStatechartParameters& inputParameters,
220 const Ice::Current&)
221 {
222 }
223
224 void
226 const armarx::ProfilerStatechartParameters& localParameters,
227 const Ice::Current&)
228 {
229 }
230
231 void
233 const armarx::ProfilerStatechartParameters& outputParameters,
234 const Ice::Current&)
235 {
236 }
237
238 void
239 ProfilerStorage::reportProcessCpuUsage(const armarx::ProfilerProcessCpuUsage& process,
240 const Ice::Current& context)
241 {
242 std::scoped_lock lock(entityLogMutex);
243 entityLog.push_back(new memoryx::ProfilerProcess(process));
244 }
245
246 void
247 ProfilerStorage::reportProcessMemoryUsage(const armarx::ProfilerProcessMemoryUsage& memoryUsage,
248 const Ice::Current& context)
249 {
250 std::scoped_lock lock(entityLogMutex);
251 entityLog.push_back(new memoryx::ProfilerMemoryUsage(memoryUsage));
252 }
253
254 void
255 ProfilerStorage::reportEventList(const armarx::ProfilerEventList& events, const Ice::Current&)
256 {
257 memoryx::EntityBaseList eventEntities(events.size());
258 std::transform(events.begin(),
259 events.end(),
260 eventEntities.begin(),
261 [](const armarx::ProfilerEvent& event)
262 { return new memoryx::ProfilerEvent(event); });
263
264 {
265 std::scoped_lock lock(entityLogMutex);
266 entityLog.insert(entityLog.end(), eventEntities.begin(), eventEntities.end());
267 }
268 }
269
270 void
272 const armarx::ProfilerStatechartTransitionList& transitions,
273 const Ice::Current&)
274 {
275 if (transitions.empty())
276 {
277 return;
278 }
279
280 TransitionSnapshotList transitionSnapshots(transitions.size());
281
282 ProfilerMemorySnapshotPtr sourceMemorySnapshot = memorySnapshot->clone();
283
284 std::transform(transitions.begin(),
285 transitions.end(),
286 transitionSnapshots.begin(),
287 [](const armarx::ProfilerStatechartTransition& transition)
288 {
289 TransitionSnapshot transitionSnapshot = {transition,
290 new ProfilerMemorySnapshot(),
291 new ProfilerMemorySnapshot()};
292 return transitionSnapshot;
293 });
294
295 transitionSnapshots.front().sourceStateMemorySnapshot = sourceMemorySnapshot;
297 transitionSnapshots.back().transition.targetStateIdentifier, workingMemoryPrx);
298 if (memorySnapshot)
299 {
300 transitionSnapshots.back().targetStateMemorySnapshot = memorySnapshot;
301 }
302 {
303 std::scoped_lock lock(transitionSnapshotListMutex);
304 transitionSnapshotList.insert(transitionSnapshotList.end(),
305 transitionSnapshots.begin(),
306 transitionSnapshots.end());
307 }
308 }
309
310 void
312 const armarx::ProfilerStatechartParametersList& inputParametersList,
313 const Ice::Current&)
314 {
315 }
316
317 void
319 const armarx::ProfilerStatechartParametersList& localParametesList,
320 const Ice::Current&)
321 {
322 }
323
324 void
326 const armarx::ProfilerStatechartParametersList& outputParametersList,
327 const Ice::Current&)
328 {
329 }
330
331 void
332 ProfilerStorage::reportProcessCpuUsageList(const armarx::ProfilerProcessCpuUsageList& processes,
333 const Ice::Current&)
334 {
335 memoryx::EntityBaseList eventEntities(processes.size());
336 std::transform(processes.begin(),
337 processes.end(),
338 eventEntities.begin(),
339 [](const armarx::ProfilerProcessCpuUsage& process)
340 { return new memoryx::ProfilerProcess(process); });
341
342 {
343 std::scoped_lock lock(entityLogMutex);
344 entityLog.insert(entityLog.end(), eventEntities.begin(), eventEntities.end());
345 }
346 }
347
348 void
350 const armarx::ProfilerProcessMemoryUsageList& memoryUsages,
351 const Ice::Current&)
352 {
353 memoryx::EntityBaseList eventEntities(memoryUsages.size());
354 std::transform(memoryUsages.begin(),
355 memoryUsages.end(),
356 eventEntities.begin(),
357 [](const armarx::ProfilerProcessMemoryUsage& memoryUsage)
358 { return new memoryx::ProfilerMemoryUsage(memoryUsage); });
359
360 {
361 std::scoped_lock lock(entityLogMutex);
362 entityLog.insert(entityLog.end(), eventEntities.begin(), eventEntities.end());
363 }
364 }
365
368 const std::string& stateName,
369 const WorkingMemoryInterfacePrx& workingMemoryProxy)
370 {
371 if (!workingMemoryProxy)
372 {
373 return new ProfilerMemorySnapshot(stateName, Ice::Context());
374 }
375
376 Ice::Context snapshot;
377
378 memoryx::ObjectInstancePtr humanInstance = memoryx::ObjectInstancePtr::dynamicCast(
379 workingMemoryProxy->getObjectInstancesSegment()->getObjectInstanceByName("human"));
380 if (humanInstance)
381 {
382 snapshot["human"] = humanInstance->getAttribute("name")->getValue()->getString();
383 if (humanInstance->hasAttribute("humanObject"))
384 {
385 snapshot["humanObject"] =
386 humanInstance->getAttribute("humanObject")->getValue()->getString();
387 }
388
389 if (humanInstance->hasAttribute("intention"))
390 {
391 snapshot["intention"] =
392 humanInstance->getAttribute("intention")->getValue()->getString();
393 }
394 }
395
396 memoryx::ObjectInstancePtr objectInstance = memoryx::ObjectInstancePtr::dynamicCast(
397 workingMemoryProxy->getObjectInstancesSegment()->getObjectInstanceByName("taskObject"));
398 if (objectInstance)
399 {
400 snapshot["taskObject"] = objectInstance->getAttribute("name")->getValue()->getString();
401
402 bool inHand = objectInstance->getAttribute("inHand")->getValue()->getBool();
403 snapshot["objectInHand"] = inHand ? "true" : "false";
404 }
405
406 return new ProfilerMemorySnapshot(stateName, snapshot);
407 }
408
409 std::string
411 {
412 return getProperty<std::string>("CommonStorageName").getValue();
413 }
414
415 std::string
417 {
418 return getProperty<std::string>("WorkingMemoryName").getValue();
419 }
420
421 std::string
423 {
424 return getProperty<std::string>("LongtermMemoryName").getValue();
425 }
426
433
434 void
436 const armarx::ProfilerStatechartTransitionWithParameters& transition,
437 const Ice::Current& context)
438 {
439 }
440
441 void
443 const armarx::ProfilerStatechartTransitionWithParametersList& transitions,
444 const Ice::Current&)
445 {
446 }
447
450 {
452 "SaveTimeout", 500, "How often should the statistics be saved (ms)");
454 "CommonStorageName", "CommonStorage", "Name of the CommonStorage proxy to use");
456 "WorkingMemoryName", "WorkingMemory", "Name of the WorkingMemory proxy to use");
458 "LongtermMemoryName", "LongtermMemory", "Name of the LongtermMemory proxy to use");
459 defineOptionalProperty<bool>("enabled", true, "disable/enable saver");
460 }
461} // namespace memoryx
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)
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 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 onExitComponent() 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