VirtualBox

source: vbox/trunk/src/VBox/Main/include/Performance.h@ 43908

Last change on this file since 43908 was 43908, checked in by vboxsync, 12 years ago

Main/Metrics: VM network rate metrics (#6345)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 31.2 KB
Line 
1/* $Id: Performance.h 43908 2012-11-19 05:36:43Z vboxsync $ */
2/** @file
3 * VirtualBox Main - Performance Classes declaration.
4 */
5
6/*
7 * Copyright (C) 2008 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17#ifndef ___performance_h
18#define ___performance_h
19
20#include <VBox/com/defs.h>
21#include <VBox/com/ptr.h>
22#include <VBox/com/string.h>
23#include <VBox/com/VirtualBox.h>
24
25#include <iprt/types.h>
26#include <iprt/err.h>
27#include <iprt/cpp/lock.h>
28
29#include <algorithm>
30#include <functional> /* For std::fun_ptr in testcase */
31#include <list>
32#include <vector>
33#include <queue>
34
35/* Forward decl. */
36class Machine;
37
38namespace pm
39{
40 /* CPU load is measured in 1/1000 of per cent. */
41 const uint64_t PM_CPU_LOAD_MULTIPLIER = UINT64_C(100000);
42 /* Network load is measured in 1/1000 of per cent. */
43 const uint64_t PM_NETWORK_LOAD_MULTIPLIER = UINT64_C(100000);
44 /* Disk load is measured in 1/1000 of per cent. */
45 const uint64_t PM_DISK_LOAD_MULTIPLIER = UINT64_C(100000);
46 /* Sampler precision in milliseconds. */
47 const uint64_t PM_SAMPLER_PRECISION_MS = 50;
48
49 /* Sub Metrics **********************************************************/
50 class CircularBuffer
51 {
52 public:
53 CircularBuffer() : mData(0), mLength(0), mEnd(0), mWrapped(false) {};
54 ~CircularBuffer() { if (mData) RTMemFree(mData); };
55 void init(ULONG length);
56 ULONG length();
57 ULONG getSequenceNumber() { return mSequenceNumber; }
58 void put(ULONG value);
59 void copyTo(ULONG *data);
60 private:
61 ULONG *mData;
62 ULONG mLength;
63 ULONG mEnd;
64 ULONG mSequenceNumber;
65 bool mWrapped;
66 };
67
68 class SubMetric : public CircularBuffer
69 {
70 public:
71 SubMetric(com::Utf8Str name, const char *description)
72 : mName(name), mDescription(description) {};
73 void query(ULONG *data);
74 const char *getName() { return mName.c_str(); };
75 const char *getDescription() { return mDescription; };
76 private:
77 const com::Utf8Str mName;
78 const char *mDescription;
79 };
80
81
82 enum {
83 COLLECT_NONE = 0x0,
84 COLLECT_CPU_LOAD = 0x1,
85 COLLECT_RAM_USAGE = 0x2,
86 COLLECT_GUEST_STATS = 0x4
87 };
88 typedef int HintFlags;
89 typedef std::pair<RTPROCESS, HintFlags> ProcessFlagsPair;
90
91 class CollectorHints
92 {
93 public:
94 typedef std::list<ProcessFlagsPair> ProcessList;
95
96 CollectorHints() : mHostFlags(COLLECT_NONE) {}
97 void collectHostCpuLoad()
98 { mHostFlags |= COLLECT_CPU_LOAD; }
99 void collectHostRamUsage()
100 { mHostFlags |= COLLECT_RAM_USAGE; }
101 void collectHostRamVmm()
102 { mHostFlags |= COLLECT_GUEST_STATS; }
103 void collectProcessCpuLoad(RTPROCESS process)
104 { findProcess(process).second |= COLLECT_CPU_LOAD; }
105 void collectProcessRamUsage(RTPROCESS process)
106 { findProcess(process).second |= COLLECT_RAM_USAGE; }
107 void collectGuestStats(RTPROCESS process)
108 { findProcess(process).second |= COLLECT_GUEST_STATS; }
109 bool isHostCpuLoadCollected() const
110 { return (mHostFlags & COLLECT_CPU_LOAD) != 0; }
111 bool isHostRamUsageCollected() const
112 { return (mHostFlags & COLLECT_RAM_USAGE) != 0; }
113 bool isHostRamVmmCollected() const
114 { return (mHostFlags & COLLECT_GUEST_STATS) != 0; }
115 bool isProcessCpuLoadCollected(RTPROCESS process)
116 { return (findProcess(process).second & COLLECT_CPU_LOAD) != 0; }
117 bool isProcessRamUsageCollected(RTPROCESS process)
118 { return (findProcess(process).second & COLLECT_RAM_USAGE) != 0; }
119 bool isGuestStatsCollected(RTPROCESS process)
120 { return (findProcess(process).second & COLLECT_GUEST_STATS) != 0; }
121 void getProcesses(std::vector<RTPROCESS>& processes) const
122 {
123 processes.clear();
124 processes.reserve(mProcesses.size());
125 for (ProcessList::const_iterator it = mProcesses.begin(); it != mProcesses.end(); it++)
126 processes.push_back(it->first);
127 }
128 const ProcessList& getProcessFlags() const
129 {
130 return mProcesses;
131 }
132 private:
133 HintFlags mHostFlags;
134 ProcessList mProcesses;
135
136 ProcessFlagsPair& findProcess(RTPROCESS process)
137 {
138 ProcessList::iterator it;
139 for (it = mProcesses.begin(); it != mProcesses.end(); it++)
140 if (it->first == process)
141 return *it;
142
143 /* Not found -- add new */
144 mProcesses.push_back(ProcessFlagsPair(process, COLLECT_NONE));
145 return mProcesses.back();
146 }
147 };
148
149 /* Guest Collector Classes *********************************/
150 /*
151 * WARNING! The bits in the following masks must correspond to parameters
152 * of CollectorGuest::updateStats().
153 */
154 typedef enum
155 {
156 VMSTATMASK_NONE = 0x00000000,
157 VMSTATMASK_GUEST_CPUUSER = 0x00000001,
158 VMSTATMASK_GUEST_CPUKERNEL = 0x00000002,
159 VMSTATMASK_GUEST_CPUIDLE = 0x00000004,
160 VMSTATMASK_GUEST_MEMTOTAL = 0x00000008,
161 VMSTATMASK_GUEST_MEMFREE = 0x00000010,
162 VMSTATMASK_GUEST_MEMBALLOON = 0x00000020,
163 VMSTATMASK_GUEST_MEMSHARED = 0x00000040,
164 VMSTATMASK_GUEST_MEMCACHE = 0x00000080,
165 VMSTATMASK_GUEST_PAGETOTAL = 0x00000100,
166 VMSTATMASK_VMM_ALLOC = 0x00010000,
167 VMSTATMASK_VMM_FREE = 0x00020000,
168 VMSTATMASK_VMM_BALOON = 0x00040000,
169 VMSTATMASK_VMM_SHARED = 0x00080000,
170 VMSTATMASK_NET_RX = 0x01000000,
171 VMSTATMASK_NET_TX = 0x02000000
172 } VMSTATMASK;
173
174 const ULONG VMSTATS_GUEST_CPULOAD =
175 VMSTATMASK_GUEST_CPUUSER | VMSTATMASK_GUEST_CPUKERNEL |
176 VMSTATMASK_GUEST_CPUIDLE;
177 const ULONG VMSTATS_GUEST_RAMUSAGE =
178 VMSTATMASK_GUEST_MEMTOTAL | VMSTATMASK_GUEST_MEMFREE |
179 VMSTATMASK_GUEST_MEMBALLOON | VMSTATMASK_GUEST_MEMSHARED |
180 VMSTATMASK_GUEST_MEMCACHE | VMSTATMASK_GUEST_PAGETOTAL;
181 const ULONG VMSTATS_VMM_RAM =
182 VMSTATMASK_VMM_ALLOC | VMSTATMASK_VMM_FREE|
183 VMSTATMASK_VMM_BALOON | VMSTATMASK_VMM_SHARED;
184 const ULONG VMSTATS_NET_RATE =
185 VMSTATMASK_NET_RX | VMSTATMASK_NET_TX;
186 const ULONG VMSTATS_ALL =
187 VMSTATS_GUEST_CPULOAD | VMSTATS_GUEST_RAMUSAGE |
188 VMSTATS_VMM_RAM | VMSTATS_NET_RATE;
189 class CollectorGuest;
190
191 class CollectorGuestRequest
192 {
193 public:
194 CollectorGuestRequest()
195 : mCGuest(0) {};
196 virtual ~CollectorGuestRequest() {};
197 void setGuest(CollectorGuest *aGuest) { mCGuest = aGuest; };
198 CollectorGuest *getGuest() { return mCGuest; };
199 virtual int execute() = 0;
200
201 virtual void debugPrint(void *aObject, const char *aFunction, const char *aText) = 0;
202 protected:
203 CollectorGuest *mCGuest;
204 const char *mDebugName;
205 };
206
207 class CGRQEnable : public CollectorGuestRequest
208 {
209 public:
210 CGRQEnable(ULONG aMask)
211 : mMask(aMask) {};
212 int execute();
213
214 void debugPrint(void *aObject, const char *aFunction, const char *aText);
215 private:
216 ULONG mMask;
217 };
218
219 class CGRQDisable : public CollectorGuestRequest
220 {
221 public:
222 CGRQDisable(ULONG aMask)
223 : mMask(aMask) {};
224 int execute();
225
226 void debugPrint(void *aObject, const char *aFunction, const char *aText);
227 private:
228 ULONG mMask;
229 };
230
231 class CGRQAbort : public CollectorGuestRequest
232 {
233 public:
234 CGRQAbort() {};
235 int execute();
236
237 void debugPrint(void *aObject, const char *aFunction, const char *aText);
238 };
239
240 class CollectorGuestQueue
241 {
242 public:
243 CollectorGuestQueue();
244 ~CollectorGuestQueue();
245 void push(CollectorGuestRequest* rq);
246 CollectorGuestRequest* pop();
247 private:
248 RTCLockMtx mLockMtx;
249 RTSEMEVENT mEvent;
250 std::queue<CollectorGuestRequest*> mQueue;
251 };
252
253 class CollectorGuestManager;
254
255 class CollectorGuest
256 {
257 public:
258 CollectorGuest(Machine *machine, RTPROCESS process);
259 ~CollectorGuest();
260
261 void setManager(CollectorGuestManager *aManager)
262 { mManager = aManager; };
263 bool isUnregistered() { return mUnregistered; };
264 bool isEnabled() { return mEnabled != 0; };
265 bool isValid(ULONG mask) { return (mValid & mask) == mask; };
266 void invalidate(ULONG mask) { mValid &= ~mask; };
267 void unregister() { mUnregistered = true; };
268 void updateStats(ULONG aValidStats, ULONG aCpuUser,
269 ULONG aCpuKernel, ULONG aCpuIdle,
270 ULONG aMemTotal, ULONG aMemFree,
271 ULONG aMemBalloon, ULONG aMemShared,
272 ULONG aMemCache, ULONG aPageTotal,
273 ULONG aAllocVMM, ULONG aFreeVMM,
274 ULONG aBalloonedVMM, ULONG aSharedVMM,
275 ULONG aVmNetRx, ULONG aVmNetTx);
276 int enable(ULONG mask);
277 int disable(ULONG mask);
278
279 int enqueueRequest(CollectorGuestRequest *aRequest);
280 int enableInternal(ULONG mask);
281 int disableInternal(ULONG mask);
282
283 const com::Utf8Str& getVMName() const { return mMachineName; };
284
285 RTPROCESS getProcess() { return mProcess; };
286 ULONG getCpuUser() { return mCpuUser; };
287 ULONG getCpuKernel() { return mCpuKernel; };
288 ULONG getCpuIdle() { return mCpuIdle; };
289 ULONG getMemTotal() { return mMemTotal; };
290 ULONG getMemFree() { return mMemFree; };
291 ULONG getMemBalloon() { return mMemBalloon; };
292 ULONG getMemShared() { return mMemShared; };
293 ULONG getMemCache() { return mMemCache; };
294 ULONG getPageTotal() { return mPageTotal; };
295 ULONG getAllocVMM() { return mAllocVMM; };
296 ULONG getFreeVMM() { return mFreeVMM; };
297 ULONG getBalloonedVMM() { return mBalloonedVMM; };
298 ULONG getSharedVMM() { return mSharedVMM; };
299 ULONG getVmNetRx() { return mVmNetRx; };
300 ULONG getVmNetTx() { return mVmNetTx; };
301
302 private:
303 int enableVMMStats(bool mCollectVMMStats);
304
305 CollectorGuestManager *mManager;
306
307 bool mUnregistered;
308 ULONG mEnabled;
309 ULONG mValid;
310 Machine *mMachine;
311 com::Utf8Str mMachineName;
312 RTPROCESS mProcess;
313 ComPtr<IConsole> mConsole;
314 ComPtr<IGuest> mGuest;
315 ULONG mCpuUser;
316 ULONG mCpuKernel;
317 ULONG mCpuIdle;
318 ULONG mMemTotal;
319 ULONG mMemFree;
320 ULONG mMemBalloon;
321 ULONG mMemShared;
322 ULONG mMemCache;
323 ULONG mPageTotal;
324 ULONG mAllocVMM;
325 ULONG mFreeVMM;
326 ULONG mBalloonedVMM;
327 ULONG mSharedVMM;
328 ULONG mVmNetRx;
329 ULONG mVmNetTx;
330 };
331
332 typedef std::list<CollectorGuest*> CollectorGuestList;
333 class CollectorGuestManager
334 {
335 public:
336 CollectorGuestManager();
337 ~CollectorGuestManager();
338 void registerGuest(CollectorGuest* pGuest);
339 void unregisterGuest(CollectorGuest* pGuest);
340 CollectorGuest *getVMMStatsProvider() { return mVMMStatsProvider; };
341 void preCollect(CollectorHints& hints, uint64_t iTick);
342 void destroyUnregistered();
343 int enqueueRequest(CollectorGuestRequest *aRequest);
344
345 CollectorGuest *getBlockedGuest() { return mGuestBeingCalled; };
346
347 static DECLCALLBACK(int) requestProcessingThread(RTTHREAD aThread, void *pvUser);
348 private:
349 RTTHREAD mThread;
350 CollectorGuestList mGuests;
351 CollectorGuest *mVMMStatsProvider;
352 CollectorGuestQueue mQueue;
353 CollectorGuest *mGuestBeingCalled;
354 };
355
356 /* Collector Hardware Abstraction Layer *********************************/
357 typedef std::list<RTCString> DiskList;
358
359 class CollectorHAL
360 {
361 public:
362 CollectorHAL() {};
363 virtual ~CollectorHAL() { };
364 virtual int preCollect(const CollectorHints& /* hints */, uint64_t /* iTick */) { return VINF_SUCCESS; }
365 /** Returns averaged CPU usage in 1/1000th per cent across all host's CPUs. */
366 virtual int getHostCpuLoad(ULONG *user, ULONG *kernel, ULONG *idle);
367 /** Returns the average frequency in MHz across all host's CPUs. */
368 virtual int getHostCpuMHz(ULONG *mhz);
369 /** Returns the amount of physical memory in kilobytes. */
370 virtual int getHostMemoryUsage(ULONG *total, ULONG *used, ULONG *available);
371 /** Returns file system counters in megabytes. */
372 virtual int getHostFilesystemUsage(const char *name, ULONG *total, ULONG *used, ULONG *available);
373 /** Returns CPU usage in 1/1000th per cent by a particular process. */
374 virtual int getProcessCpuLoad(RTPROCESS process, ULONG *user, ULONG *kernel);
375 /** Returns the amount of memory used by a process in kilobytes. */
376 virtual int getProcessMemoryUsage(RTPROCESS process, ULONG *used);
377
378 /** Returns CPU usage counters in platform-specific units. */
379 virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
380 /** Returns received and transmitted bytes. */
381 virtual int getRawHostNetworkLoad(const char *name, uint64_t *rx, uint64_t *tx);
382 /** Returns disk usage counters in platform-specific units. */
383 virtual int getRawHostDiskLoad(const char *name, uint64_t *disk_ms, uint64_t *total_ms);
384 /** Returns process' CPU usage counter in platform-specific units. */
385 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
386
387 /** Returns the list of disks used by the specified file system. */
388 virtual int getDiskListByFs(const char *name, DiskList& list);
389 };
390
391 extern CollectorHAL *createHAL();
392
393 /* Base Metrics *********************************************************/
394 class BaseMetric
395 {
396 public:
397 BaseMetric(CollectorHAL *hal, const com::Utf8Str name, ComPtr<IUnknown> object)
398 : mPeriod(0), mLength(0), mHAL(hal), mName(name), mObject(object),
399 mLastSampleTaken(0), mEnabled(false), mUnregistered(false) {};
400 virtual ~BaseMetric() {};
401
402 virtual void init(ULONG period, ULONG length) = 0;
403 virtual void preCollect(CollectorHints& hints, uint64_t iTick) = 0;
404 virtual void collect() = 0;
405 virtual const char *getUnit() = 0;
406 virtual ULONG getMinValue() = 0;
407 virtual ULONG getMaxValue() = 0;
408 virtual ULONG getScale() = 0;
409
410 bool collectorBeat(uint64_t nowAt);
411
412 virtual int enable() { mEnabled = true; return S_OK; };
413 virtual int disable() { mEnabled = false; return S_OK; };
414 void unregister() { mUnregistered = true; };
415
416 bool isUnregistered() { return mUnregistered; };
417 bool isEnabled() { return mEnabled; };
418 ULONG getPeriod() { return mPeriod; };
419 ULONG getLength() { return mLength; };
420 const char *getName() { return mName.c_str(); };
421 ComPtr<IUnknown> getObject() { return mObject; };
422 bool associatedWith(ComPtr<IUnknown> object) { return mObject == object; };
423
424 protected:
425 ULONG mPeriod;
426 ULONG mLength;
427 CollectorHAL *mHAL;
428 const com::Utf8Str mName;
429 ComPtr<IUnknown> mObject;
430 uint64_t mLastSampleTaken;
431 bool mEnabled;
432 bool mUnregistered;
433 };
434
435 class BaseGuestMetric : public BaseMetric
436 {
437 public:
438 BaseGuestMetric(CollectorGuest *cguest, const char *name, ComPtr<IUnknown> object)
439 : BaseMetric(NULL, name, object), mCGuest(cguest) {};
440 protected:
441 CollectorGuest *mCGuest;
442 };
443
444 class HostCpuLoad : public BaseMetric
445 {
446 public:
447 HostCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
448 : BaseMetric(hal, "CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
449 ~HostCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
450
451 void init(ULONG period, ULONG length);
452
453 void collect();
454 const char *getUnit() { return "%"; };
455 ULONG getMinValue() { return 0; };
456 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
457 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
458
459 protected:
460 SubMetric *mUser;
461 SubMetric *mKernel;
462 SubMetric *mIdle;
463 };
464
465 class HostCpuLoadRaw : public HostCpuLoad
466 {
467 public:
468 HostCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
469 : HostCpuLoad(hal, object, user, kernel, idle), mUserPrev(0), mKernelPrev(0), mIdlePrev(0) {};
470
471 void preCollect(CollectorHints& hints, uint64_t iTick);
472 void collect();
473 private:
474 uint64_t mUserPrev;
475 uint64_t mKernelPrev;
476 uint64_t mIdlePrev;
477 };
478
479 class HostCpuMhz : public BaseMetric
480 {
481 public:
482 HostCpuMhz(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *mhz)
483 : BaseMetric(hal, "CPU/MHz", object), mMHz(mhz) {};
484 ~HostCpuMhz() { delete mMHz; };
485
486 void init(ULONG period, ULONG length);
487 void preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) {}
488 void collect();
489 const char *getUnit() { return "MHz"; };
490 ULONG getMinValue() { return 0; };
491 ULONG getMaxValue() { return INT32_MAX; };
492 ULONG getScale() { return 1; }
493 private:
494 SubMetric *mMHz;
495 };
496
497 class HostRamUsage : public BaseMetric
498 {
499 public:
500 HostRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available)
501 : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mUsed(used), mAvailable(available) {};
502 ~HostRamUsage() { delete mTotal; delete mUsed; delete mAvailable; };
503
504 void init(ULONG period, ULONG length);
505 void preCollect(CollectorHints& hints, uint64_t iTick);
506 void collect();
507 const char *getUnit() { return "kB"; };
508 ULONG getMinValue() { return 0; };
509 ULONG getMaxValue() { return INT32_MAX; };
510 ULONG getScale() { return 1; }
511 private:
512 SubMetric *mTotal;
513 SubMetric *mUsed;
514 SubMetric *mAvailable;
515 };
516
517 class HostNetworkLoadRaw : public BaseMetric
518 {
519 public:
520 HostNetworkLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str shortname, com::Utf8Str ifname, uint32_t speed, SubMetric *rx, SubMetric *tx)
521 : BaseMetric(hal, name, object), mShortName(shortname), mInterfaceName(ifname), mRx(rx), mTx(tx), mRxPrev(0), mTxPrev(0), mRc(VINF_SUCCESS) { mSpeed = (uint64_t)speed * (1000000/8); /* Convert to bytes/sec */ };
522 ~HostNetworkLoadRaw() { delete mRx; delete mTx; };
523
524 void init(ULONG period, ULONG length);
525
526 void preCollect(CollectorHints& hints, uint64_t iTick);
527 void collect();
528 const char *getUnit() { return "%"; };
529 ULONG getMinValue() { return 0; };
530 ULONG getMaxValue() { return PM_NETWORK_LOAD_MULTIPLIER; };
531 ULONG getScale() { return PM_NETWORK_LOAD_MULTIPLIER / 100; }
532
533 private:
534 com::Utf8Str mShortName;
535 com::Utf8Str mInterfaceName;
536 SubMetric *mRx;
537 SubMetric *mTx;
538 uint64_t mRxPrev;
539 uint64_t mTxPrev;
540 uint64_t mSpeed;
541 int mRc;
542 };
543
544 class HostFilesystemUsage : public BaseMetric
545 {
546 public:
547 HostFilesystemUsage(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str fsname, SubMetric *total, SubMetric *used, SubMetric *available)
548 : BaseMetric(hal, name, object), mFsName(fsname), mTotal(total), mUsed(used), mAvailable(available) {};
549 ~HostFilesystemUsage() { delete mTotal; delete mUsed; delete mAvailable; };
550
551 void init(ULONG period, ULONG length);
552 void preCollect(CollectorHints& hints, uint64_t iTick);
553 void collect();
554 const char *getUnit() { return "mB"; };
555 ULONG getMinValue() { return 0; };
556 ULONG getMaxValue() { return INT32_MAX; };
557 ULONG getScale() { return 1; }
558 private:
559 com::Utf8Str mFsName;
560 SubMetric *mTotal;
561 SubMetric *mUsed;
562 SubMetric *mAvailable;
563 };
564
565 class HostDiskLoadRaw : public BaseMetric
566 {
567 public:
568 HostDiskLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str diskname, SubMetric *util)
569 : BaseMetric(hal, name, object), mDiskName(diskname), mUtil(util), mDiskPrev(0), mTotalPrev(0) {};
570 ~HostDiskLoadRaw() { delete mUtil; };
571
572 void init(ULONG period, ULONG length);
573
574 void preCollect(CollectorHints& hints, uint64_t iTick);
575 void collect();
576 const char *getUnit() { return "%"; };
577 ULONG getMinValue() { return 0; };
578 ULONG getMaxValue() { return PM_DISK_LOAD_MULTIPLIER; };
579 ULONG getScale() { return PM_DISK_LOAD_MULTIPLIER / 100; }
580
581 private:
582 com::Utf8Str mDiskName;
583 SubMetric *mUtil;
584 uint64_t mDiskPrev;
585 uint64_t mTotalPrev;
586 };
587
588
589#ifndef VBOX_COLLECTOR_TEST_CASE
590 class HostRamVmm : public BaseMetric
591 {
592 public:
593 HostRamVmm(CollectorGuestManager *gm, ComPtr<IUnknown> object, SubMetric *allocVMM, SubMetric *freeVMM, SubMetric *balloonVMM, SubMetric *sharedVMM)
594 : BaseMetric(NULL, "RAM/VMM", object), mCollectorGuestManager(gm),
595 mAllocVMM(allocVMM), mFreeVMM(freeVMM), mBalloonVMM(balloonVMM), mSharedVMM(sharedVMM),
596 mAllocCurrent(0), mFreeCurrent(0), mBalloonedCurrent(0), mSharedCurrent(0) {};
597 ~HostRamVmm() { delete mAllocVMM; delete mFreeVMM; delete mBalloonVMM; delete mSharedVMM; };
598
599 void init(ULONG period, ULONG length);
600 void preCollect(CollectorHints& hints, uint64_t iTick);
601 void collect();
602 int enable();
603 int disable();
604 const char *getUnit() { return "kB"; };
605 ULONG getMinValue() { return 0; };
606 ULONG getMaxValue() { return INT32_MAX; };
607 ULONG getScale() { return 1; }
608
609 private:
610 CollectorGuestManager *mCollectorGuestManager;
611 SubMetric *mAllocVMM;
612 SubMetric *mFreeVMM;
613 SubMetric *mBalloonVMM;
614 SubMetric *mSharedVMM;
615 ULONG mAllocCurrent;
616 ULONG mFreeCurrent;
617 ULONG mBalloonedCurrent;
618 ULONG mSharedCurrent;
619 };
620#endif /* VBOX_COLLECTOR_TEST_CASE */
621
622 class MachineCpuLoad : public BaseMetric
623 {
624 public:
625 MachineCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
626 : BaseMetric(hal, "CPU/Load", object), mProcess(process), mUser(user), mKernel(kernel) {};
627 ~MachineCpuLoad() { delete mUser; delete mKernel; };
628
629 void init(ULONG period, ULONG length);
630 void collect();
631 const char *getUnit() { return "%"; };
632 ULONG getMinValue() { return 0; };
633 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
634 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
635 protected:
636 RTPROCESS mProcess;
637 SubMetric *mUser;
638 SubMetric *mKernel;
639 };
640
641 class MachineCpuLoadRaw : public MachineCpuLoad
642 {
643 public:
644 MachineCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
645 : MachineCpuLoad(hal, object, process, user, kernel), mHostTotalPrev(0), mProcessUserPrev(0), mProcessKernelPrev(0) {};
646
647 void preCollect(CollectorHints& hints, uint64_t iTick);
648 void collect();
649 private:
650 uint64_t mHostTotalPrev;
651 uint64_t mProcessUserPrev;
652 uint64_t mProcessKernelPrev;
653 };
654
655 class MachineRamUsage : public BaseMetric
656 {
657 public:
658 MachineRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used)
659 : BaseMetric(hal, "RAM/Usage", object), mProcess(process), mUsed(used) {};
660 ~MachineRamUsage() { delete mUsed; };
661
662 void init(ULONG period, ULONG length);
663 void preCollect(CollectorHints& hints, uint64_t iTick);
664 void collect();
665 const char *getUnit() { return "kB"; };
666 ULONG getMinValue() { return 0; };
667 ULONG getMaxValue() { return INT32_MAX; };
668 ULONG getScale() { return 1; }
669 private:
670 RTPROCESS mProcess;
671 SubMetric *mUsed;
672 };
673
674
675#ifndef VBOX_COLLECTOR_TEST_CASE
676 /*
677 * Although MachineNetRate is measured for VM, not for the guest, it is
678 * derived from BaseGuestMetric since it uses the same mechanism for
679 * data collection -- values get pushed by Guest class along with other
680 * guest statistics.
681 */
682 class MachineNetRate : public BaseGuestMetric
683 {
684 public:
685 MachineNetRate(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *rx, SubMetric *tx)
686 : BaseGuestMetric(cguest, "Net/Rate", object), mRx(rx), mTx(tx) {};
687 ~MachineNetRate() { delete mRx; delete mTx; };
688
689 void init(ULONG period, ULONG length);
690 void preCollect(CollectorHints& hints, uint64_t iTick);
691 void collect();
692 int enable();
693 int disable();
694 const char *getUnit() { return "B/s"; };
695 ULONG getMinValue() { return 0; };
696 ULONG getMaxValue() { return INT32_MAX; };
697 ULONG getScale() { return 1; }
698 private:
699 SubMetric *mRx, *mTx;
700 };
701
702 class GuestCpuLoad : public BaseGuestMetric
703 {
704 public:
705 GuestCpuLoad(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
706 : BaseGuestMetric(cguest, "Guest/CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
707 ~GuestCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
708
709 void init(ULONG period, ULONG length);
710 void preCollect(CollectorHints& hints, uint64_t iTick);
711 void collect();
712 int enable();
713 int disable();
714 const char *getUnit() { return "%"; };
715 ULONG getMinValue() { return 0; };
716 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
717 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
718 protected:
719 SubMetric *mUser;
720 SubMetric *mKernel;
721 SubMetric *mIdle;
722 };
723
724 class GuestRamUsage : public BaseGuestMetric
725 {
726 public:
727 GuestRamUsage(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *shared, SubMetric *cache, SubMetric *pagedtotal)
728 : BaseGuestMetric(cguest, "Guest/RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mCache(cache), mPagedTotal(pagedtotal), mShared(shared) {};
729 ~GuestRamUsage() { delete mTotal; delete mFree; delete mBallooned; delete mShared; delete mCache; delete mPagedTotal; };
730
731 void init(ULONG period, ULONG length);
732 void preCollect(CollectorHints& hints, uint64_t iTick);
733 void collect();
734 int enable();
735 int disable();
736 const char *getUnit() { return "kB"; };
737 ULONG getMinValue() { return 0; };
738 ULONG getMaxValue() { return INT32_MAX; };
739 ULONG getScale() { return 1; }
740 private:
741 SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal, *mShared;
742 };
743#endif /* VBOX_COLLECTOR_TEST_CASE */
744
745 /* Aggregate Functions **************************************************/
746 class Aggregate
747 {
748 public:
749 virtual ULONG compute(ULONG *data, ULONG length) = 0;
750 virtual const char *getName() = 0;
751 };
752
753 class AggregateAvg : public Aggregate
754 {
755 public:
756 virtual ULONG compute(ULONG *data, ULONG length);
757 virtual const char *getName();
758 };
759
760 class AggregateMin : public Aggregate
761 {
762 public:
763 virtual ULONG compute(ULONG *data, ULONG length);
764 virtual const char *getName();
765 };
766
767 class AggregateMax : public Aggregate
768 {
769 public:
770 virtual ULONG compute(ULONG *data, ULONG length);
771 virtual const char *getName();
772 };
773
774 /* Metric Class *********************************************************/
775 class Metric
776 {
777 public:
778 Metric(BaseMetric *baseMetric, SubMetric *subMetric, Aggregate *aggregate) :
779 mName(subMetric->getName()), mBaseMetric(baseMetric), mSubMetric(subMetric), mAggregate(aggregate)
780 {
781 if (mAggregate)
782 {
783 mName.append(":");
784 mName.append(mAggregate->getName());
785 }
786 }
787
788 ~Metric()
789 {
790 delete mAggregate;
791 }
792 bool associatedWith(ComPtr<IUnknown> object) { return getObject() == object; };
793
794 const char *getName() { return mName.c_str(); };
795 ComPtr<IUnknown> getObject() { return mBaseMetric->getObject(); };
796 const char *getDescription()
797 { return mAggregate ? "" : mSubMetric->getDescription(); };
798 const char *getUnit() { return mBaseMetric->getUnit(); };
799 ULONG getMinValue() { return mBaseMetric->getMinValue(); };
800 ULONG getMaxValue() { return mBaseMetric->getMaxValue(); };
801 ULONG getPeriod() { return mBaseMetric->getPeriod(); };
802 ULONG getLength()
803 { return mAggregate ? 1 : mBaseMetric->getLength(); };
804 ULONG getScale() { return mBaseMetric->getScale(); }
805 void query(ULONG **data, ULONG *count, ULONG *sequenceNumber);
806
807 private:
808 RTCString mName;
809 BaseMetric *mBaseMetric;
810 SubMetric *mSubMetric;
811 Aggregate *mAggregate;
812 };
813
814 /* Filter Class *********************************************************/
815
816 class Filter
817 {
818 public:
819 Filter(ComSafeArrayIn(IN_BSTR, metricNames),
820 ComSafeArrayIn(IUnknown * , objects));
821 Filter(const com::Utf8Str name, const ComPtr<IUnknown> &aObject);
822 static bool patternMatch(const char *pszPat, const char *pszName,
823 bool fSeenColon = false);
824 bool match(const ComPtr<IUnknown> object, const RTCString &name) const;
825 private:
826 void init(ComSafeArrayIn(IN_BSTR, metricNames),
827 ComSafeArrayIn(IUnknown * , objects));
828
829 typedef std::pair<const ComPtr<IUnknown>, const RTCString> FilterElement;
830 typedef std::list<FilterElement> ElementList;
831
832 ElementList mElements;
833
834 void processMetricList(const com::Utf8Str &name, const ComPtr<IUnknown> object);
835 };
836}
837#endif /* ___performance_h */
838/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette