VirtualBox

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

Last change on this file since 43949 was 43949, checked in by vboxsync, 13 years ago

Main/Metics: VM disk usage metric (#6345)

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

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