VirtualBox

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

Last change on this file since 47469 was 45051, checked in by vboxsync, 11 years ago

Main/Metrics: handle less common cases for FS to disk resolution (#6345)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 33.8 KB
Line 
1/* $Id: Performance.h 45051 2013-03-15 15:34:54Z vboxsync $ */
2/** @file
3 * VirtualBox Main - Performance Classes declaration.
4 */
5
6/*
7 * Copyright (C) 2008-2013 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#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 disk size in bytes. */
376 virtual int getHostDiskSize(const char *name, uint64_t *size);
377 /** Returns CPU usage in 1/1000th per cent by a particular process. */
378 virtual int getProcessCpuLoad(RTPROCESS process, ULONG *user, ULONG *kernel);
379 /** Returns the amount of memory used by a process in kilobytes. */
380 virtual int getProcessMemoryUsage(RTPROCESS process, ULONG *used);
381
382 /** Returns CPU usage counters in platform-specific units. */
383 virtual int getRawHostCpuLoad(uint64_t *user, uint64_t *kernel, uint64_t *idle);
384 /** Returns received and transmitted bytes. */
385 virtual int getRawHostNetworkLoad(const char *name, uint64_t *rx, uint64_t *tx);
386 /** Returns disk usage counters in platform-specific units. */
387 virtual int getRawHostDiskLoad(const char *name, uint64_t *disk_ms, uint64_t *total_ms);
388 /** Returns process' CPU usage counter in platform-specific units. */
389 virtual int getRawProcessCpuLoad(RTPROCESS process, uint64_t *user, uint64_t *kernel, uint64_t *total);
390
391 /** Returns the lists of disks (aggregate and physical) used by the specified file system. */
392 virtual int getDiskListByFs(const char *name, DiskList& listUsage, DiskList& listLoad);
393 };
394
395 extern CollectorHAL *createHAL();
396
397 /* Base Metrics *********************************************************/
398 class BaseMetric
399 {
400 public:
401 BaseMetric(CollectorHAL *hal, const com::Utf8Str name, ComPtr<IUnknown> object)
402 : mPeriod(0), mLength(0), mHAL(hal), mName(name), mObject(object),
403 mLastSampleTaken(0), mEnabled(false), mUnregistered(false) {};
404 virtual ~BaseMetric() {};
405
406 virtual void init(ULONG period, ULONG length) = 0;
407 virtual void preCollect(CollectorHints& hints, uint64_t iTick) = 0;
408 virtual void collect() = 0;
409 virtual const char *getUnit() = 0;
410 virtual ULONG getMinValue() = 0;
411 virtual ULONG getMaxValue() = 0;
412 virtual ULONG getScale() = 0;
413
414 bool collectorBeat(uint64_t nowAt);
415
416 virtual int enable() { mEnabled = true; return S_OK; };
417 virtual int disable() { mEnabled = false; return S_OK; };
418 void unregister() { mUnregistered = true; };
419
420 bool isUnregistered() { return mUnregistered; };
421 bool isEnabled() { return mEnabled; };
422 ULONG getPeriod() { return mPeriod; };
423 ULONG getLength() { return mLength; };
424 const char *getName() { return mName.c_str(); };
425 ComPtr<IUnknown> getObject() { return mObject; };
426 bool associatedWith(ComPtr<IUnknown> object) { return mObject == object; };
427
428 protected:
429 ULONG mPeriod;
430 ULONG mLength;
431 CollectorHAL *mHAL;
432 const com::Utf8Str mName;
433 ComPtr<IUnknown> mObject;
434 uint64_t mLastSampleTaken;
435 bool mEnabled;
436 bool mUnregistered;
437 };
438
439 class BaseGuestMetric : public BaseMetric
440 {
441 public:
442 BaseGuestMetric(CollectorGuest *cguest, const char *name, ComPtr<IUnknown> object)
443 : BaseMetric(NULL, name, object), mCGuest(cguest) {};
444 protected:
445 CollectorGuest *mCGuest;
446 };
447
448 class HostCpuLoad : public BaseMetric
449 {
450 public:
451 HostCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
452 : BaseMetric(hal, "CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
453 ~HostCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
454
455 void init(ULONG period, ULONG length);
456
457 void collect();
458 const char *getUnit() { return "%"; };
459 ULONG getMinValue() { return 0; };
460 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
461 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
462
463 protected:
464 SubMetric *mUser;
465 SubMetric *mKernel;
466 SubMetric *mIdle;
467 };
468
469 class HostCpuLoadRaw : public HostCpuLoad
470 {
471 public:
472 HostCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
473 : HostCpuLoad(hal, object, user, kernel, idle), mUserPrev(0), mKernelPrev(0), mIdlePrev(0) {};
474
475 void init(ULONG period, ULONG length);
476 void preCollect(CollectorHints& hints, uint64_t iTick);
477 void collect();
478 private:
479 uint64_t mUserPrev;
480 uint64_t mKernelPrev;
481 uint64_t mIdlePrev;
482 };
483
484 class HostCpuMhz : public BaseMetric
485 {
486 public:
487 HostCpuMhz(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *mhz)
488 : BaseMetric(hal, "CPU/MHz", object), mMHz(mhz) {};
489 ~HostCpuMhz() { delete mMHz; };
490
491 void init(ULONG period, ULONG length);
492 void preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) {}
493 void collect();
494 const char *getUnit() { return "MHz"; };
495 ULONG getMinValue() { return 0; };
496 ULONG getMaxValue() { return INT32_MAX; };
497 ULONG getScale() { return 1; }
498 private:
499 SubMetric *mMHz;
500 };
501
502 class HostRamUsage : public BaseMetric
503 {
504 public:
505 HostRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available)
506 : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mUsed(used), mAvailable(available) {};
507 ~HostRamUsage() { delete mTotal; delete mUsed; delete mAvailable; };
508
509 void init(ULONG period, ULONG length);
510 void preCollect(CollectorHints& hints, uint64_t iTick);
511 void collect();
512 const char *getUnit() { return "kB"; };
513 ULONG getMinValue() { return 0; };
514 ULONG getMaxValue() { return INT32_MAX; };
515 ULONG getScale() { return 1; }
516 private:
517 SubMetric *mTotal;
518 SubMetric *mUsed;
519 SubMetric *mAvailable;
520 };
521
522 class HostNetworkSpeed : public BaseMetric
523 {
524 public:
525 HostNetworkSpeed(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str shortname, com::Utf8Str /* ifname */, uint32_t speed, SubMetric *linkspeed)
526 : BaseMetric(hal, name, object), mShortName(shortname), mSpeed(speed), mLinkSpeed(linkspeed) {};
527 ~HostNetworkSpeed() { delete mLinkSpeed; };
528
529 void init(ULONG period, ULONG length);
530
531 void preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) {};
532 void collect() { if (mSpeed) mLinkSpeed->put(mSpeed); };
533 const char *getUnit() { return "mbit/s"; };
534 ULONG getMinValue() { return 0; };
535 ULONG getMaxValue() { return INT32_MAX; };
536 ULONG getScale() { return 1; }
537 private:
538 com::Utf8Str mShortName;
539 uint32_t mSpeed;
540 SubMetric *mLinkSpeed;
541 };
542
543 class HostNetworkLoadRaw : public BaseMetric
544 {
545 public:
546 HostNetworkLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str shortname, com::Utf8Str ifname, uint32_t speed, SubMetric *rx, SubMetric *tx)
547 : 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 */ };
548 ~HostNetworkLoadRaw() { delete mRx; delete mTx; };
549
550 void init(ULONG period, ULONG length);
551
552 void preCollect(CollectorHints& hints, uint64_t iTick);
553 void collect();
554 const char *getUnit() { return "%"; };
555 ULONG getMinValue() { return 0; };
556 ULONG getMaxValue() { return PM_NETWORK_LOAD_MULTIPLIER; };
557 ULONG getScale() { return PM_NETWORK_LOAD_MULTIPLIER / 100; }
558
559 private:
560 com::Utf8Str mShortName;
561 com::Utf8Str mInterfaceName;
562 SubMetric *mRx;
563 SubMetric *mTx;
564 uint64_t mRxPrev;
565 uint64_t mTxPrev;
566 uint64_t mSpeed;
567 int mRc;
568 };
569
570 class HostFilesystemUsage : public BaseMetric
571 {
572 public:
573 HostFilesystemUsage(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str fsname, SubMetric *total, SubMetric *used, SubMetric *available)
574 : BaseMetric(hal, name, object), mFsName(fsname), mTotal(total), mUsed(used), mAvailable(available) {};
575 ~HostFilesystemUsage() { delete mTotal; delete mUsed; delete mAvailable; };
576
577 void init(ULONG period, ULONG length);
578 void preCollect(CollectorHints& hints, uint64_t iTick);
579 void collect();
580 const char *getUnit() { return "mB"; };
581 ULONG getMinValue() { return 0; };
582 ULONG getMaxValue() { return INT32_MAX; };
583 ULONG getScale() { return 1; }
584 private:
585 com::Utf8Str mFsName;
586 SubMetric *mTotal;
587 SubMetric *mUsed;
588 SubMetric *mAvailable;
589 };
590
591 class HostDiskUsage : public BaseMetric
592 {
593 public:
594 HostDiskUsage(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str diskname, SubMetric *total)
595 : BaseMetric(hal, name, object), mDiskName(diskname), mTotal(total) {};
596 ~HostDiskUsage() { delete mTotal; };
597
598 void init(ULONG period, ULONG length);
599 void preCollect(CollectorHints& hints, uint64_t iTick);
600 void collect();
601 const char *getUnit() { return "mB"; };
602 ULONG getMinValue() { return 0; };
603 ULONG getMaxValue() { return INT32_MAX; };
604 ULONG getScale() { return 1; }
605 private:
606 com::Utf8Str mDiskName;
607 SubMetric *mTotal;
608 };
609
610 class HostDiskLoadRaw : public BaseMetric
611 {
612 public:
613 HostDiskLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str diskname, SubMetric *util)
614 : BaseMetric(hal, name, object), mDiskName(diskname), mUtil(util), mDiskPrev(0), mTotalPrev(0) {};
615 ~HostDiskLoadRaw() { delete mUtil; };
616
617 void init(ULONG period, ULONG length);
618
619 void preCollect(CollectorHints& hints, uint64_t iTick);
620 void collect();
621 const char *getUnit() { return "%"; };
622 ULONG getMinValue() { return 0; };
623 ULONG getMaxValue() { return PM_DISK_LOAD_MULTIPLIER; };
624 ULONG getScale() { return PM_DISK_LOAD_MULTIPLIER / 100; }
625
626 private:
627 com::Utf8Str mDiskName;
628 SubMetric *mUtil;
629 uint64_t mDiskPrev;
630 uint64_t mTotalPrev;
631 };
632
633
634#ifndef VBOX_COLLECTOR_TEST_CASE
635 class HostRamVmm : public BaseMetric
636 {
637 public:
638 HostRamVmm(CollectorGuestManager *gm, ComPtr<IUnknown> object, SubMetric *allocVMM, SubMetric *freeVMM, SubMetric *balloonVMM, SubMetric *sharedVMM)
639 : BaseMetric(NULL, "RAM/VMM", object), mCollectorGuestManager(gm),
640 mAllocVMM(allocVMM), mFreeVMM(freeVMM), mBalloonVMM(balloonVMM), mSharedVMM(sharedVMM),
641 mAllocCurrent(0), mFreeCurrent(0), mBalloonedCurrent(0), mSharedCurrent(0) {};
642 ~HostRamVmm() { delete mAllocVMM; delete mFreeVMM; delete mBalloonVMM; delete mSharedVMM; };
643
644 void init(ULONG period, ULONG length);
645 void preCollect(CollectorHints& hints, uint64_t iTick);
646 void collect();
647 int enable();
648 int disable();
649 const char *getUnit() { return "kB"; };
650 ULONG getMinValue() { return 0; };
651 ULONG getMaxValue() { return INT32_MAX; };
652 ULONG getScale() { return 1; }
653
654 private:
655 CollectorGuestManager *mCollectorGuestManager;
656 SubMetric *mAllocVMM;
657 SubMetric *mFreeVMM;
658 SubMetric *mBalloonVMM;
659 SubMetric *mSharedVMM;
660 ULONG mAllocCurrent;
661 ULONG mFreeCurrent;
662 ULONG mBalloonedCurrent;
663 ULONG mSharedCurrent;
664 };
665#endif /* VBOX_COLLECTOR_TEST_CASE */
666
667 class MachineCpuLoad : public BaseMetric
668 {
669 public:
670 MachineCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
671 : BaseMetric(hal, "CPU/Load", object), mProcess(process), mUser(user), mKernel(kernel) {};
672 ~MachineCpuLoad() { delete mUser; delete mKernel; };
673
674 void init(ULONG period, ULONG length);
675 void collect();
676 const char *getUnit() { return "%"; };
677 ULONG getMinValue() { return 0; };
678 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
679 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
680 protected:
681 RTPROCESS mProcess;
682 SubMetric *mUser;
683 SubMetric *mKernel;
684 };
685
686 class MachineCpuLoadRaw : public MachineCpuLoad
687 {
688 public:
689 MachineCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
690 : MachineCpuLoad(hal, object, process, user, kernel), mHostTotalPrev(0), mProcessUserPrev(0), mProcessKernelPrev(0) {};
691
692 void preCollect(CollectorHints& hints, uint64_t iTick);
693 void collect();
694 private:
695 uint64_t mHostTotalPrev;
696 uint64_t mProcessUserPrev;
697 uint64_t mProcessKernelPrev;
698 };
699
700 class MachineRamUsage : public BaseMetric
701 {
702 public:
703 MachineRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used)
704 : BaseMetric(hal, "RAM/Usage", object), mProcess(process), mUsed(used) {};
705 ~MachineRamUsage() { delete mUsed; };
706
707 void init(ULONG period, ULONG length);
708 void preCollect(CollectorHints& hints, uint64_t iTick);
709 void collect();
710 const char *getUnit() { return "kB"; };
711 ULONG getMinValue() { return 0; };
712 ULONG getMaxValue() { return INT32_MAX; };
713 ULONG getScale() { return 1; }
714 private:
715 RTPROCESS mProcess;
716 SubMetric *mUsed;
717 };
718
719
720#ifndef VBOX_COLLECTOR_TEST_CASE
721 typedef std::list<ComObjPtr<Medium> > MediaList;
722 class MachineDiskUsage : public BaseMetric
723 {
724 public:
725 MachineDiskUsage(CollectorHAL *hal, ComPtr<IUnknown> object, MediaList &disks, SubMetric *used)
726 : BaseMetric(hal, "Disk/Usage", object), mDisks(disks), mUsed(used) {};
727 ~MachineDiskUsage() { delete mUsed; };
728
729 void init(ULONG period, ULONG length);
730 void preCollect(CollectorHints& hints, uint64_t iTick);
731 void collect();
732 const char *getUnit() { return "mB"; };
733 ULONG getMinValue() { return 0; };
734 ULONG getMaxValue() { return INT32_MAX; };
735 ULONG getScale() { return 1; }
736 private:
737 MediaList mDisks;
738 SubMetric *mUsed;
739 };
740
741 /*
742 * Although MachineNetRate is measured for VM, not for the guest, it is
743 * derived from BaseGuestMetric since it uses the same mechanism for
744 * data collection -- values get pushed by Guest class along with other
745 * guest statistics.
746 */
747 class MachineNetRate : public BaseGuestMetric
748 {
749 public:
750 MachineNetRate(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *rx, SubMetric *tx)
751 : BaseGuestMetric(cguest, "Net/Rate", object), mRx(rx), mTx(tx) {};
752 ~MachineNetRate() { delete mRx; delete mTx; };
753
754 void init(ULONG period, ULONG length);
755 void preCollect(CollectorHints& hints, uint64_t iTick);
756 void collect();
757 int enable();
758 int disable();
759 const char *getUnit() { return "B/s"; };
760 ULONG getMinValue() { return 0; };
761 ULONG getMaxValue() { return INT32_MAX; };
762 ULONG getScale() { return 1; }
763 private:
764 SubMetric *mRx, *mTx;
765 };
766
767 class GuestCpuLoad : public BaseGuestMetric
768 {
769 public:
770 GuestCpuLoad(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
771 : BaseGuestMetric(cguest, "Guest/CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
772 ~GuestCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
773
774 void init(ULONG period, ULONG length);
775 void preCollect(CollectorHints& hints, uint64_t iTick);
776 void collect();
777 int enable();
778 int disable();
779 const char *getUnit() { return "%"; };
780 ULONG getMinValue() { return 0; };
781 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
782 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
783 protected:
784 SubMetric *mUser;
785 SubMetric *mKernel;
786 SubMetric *mIdle;
787 };
788
789 class GuestRamUsage : public BaseGuestMetric
790 {
791 public:
792 GuestRamUsage(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *shared, SubMetric *cache, SubMetric *pagedtotal)
793 : BaseGuestMetric(cguest, "Guest/RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mCache(cache), mPagedTotal(pagedtotal), mShared(shared) {};
794 ~GuestRamUsage() { delete mTotal; delete mFree; delete mBallooned; delete mShared; delete mCache; delete mPagedTotal; };
795
796 void init(ULONG period, ULONG length);
797 void preCollect(CollectorHints& hints, uint64_t iTick);
798 void collect();
799 int enable();
800 int disable();
801 const char *getUnit() { return "kB"; };
802 ULONG getMinValue() { return 0; };
803 ULONG getMaxValue() { return INT32_MAX; };
804 ULONG getScale() { return 1; }
805 private:
806 SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal, *mShared;
807 };
808#endif /* VBOX_COLLECTOR_TEST_CASE */
809
810 /* Aggregate Functions **************************************************/
811 class Aggregate
812 {
813 public:
814 virtual ULONG compute(ULONG *data, ULONG length) = 0;
815 virtual const char *getName() = 0;
816 };
817
818 class AggregateAvg : public Aggregate
819 {
820 public:
821 virtual ULONG compute(ULONG *data, ULONG length);
822 virtual const char *getName();
823 };
824
825 class AggregateMin : public Aggregate
826 {
827 public:
828 virtual ULONG compute(ULONG *data, ULONG length);
829 virtual const char *getName();
830 };
831
832 class AggregateMax : public Aggregate
833 {
834 public:
835 virtual ULONG compute(ULONG *data, ULONG length);
836 virtual const char *getName();
837 };
838
839 /* Metric Class *********************************************************/
840 class Metric
841 {
842 public:
843 Metric(BaseMetric *baseMetric, SubMetric *subMetric, Aggregate *aggregate) :
844 mName(subMetric->getName()), mBaseMetric(baseMetric), mSubMetric(subMetric), mAggregate(aggregate)
845 {
846 if (mAggregate)
847 {
848 mName.append(":");
849 mName.append(mAggregate->getName());
850 }
851 }
852
853 ~Metric()
854 {
855 delete mAggregate;
856 }
857 bool associatedWith(ComPtr<IUnknown> object) { return getObject() == object; };
858
859 const char *getName() { return mName.c_str(); };
860 ComPtr<IUnknown> getObject() { return mBaseMetric->getObject(); };
861 const char *getDescription()
862 { return mAggregate ? "" : mSubMetric->getDescription(); };
863 const char *getUnit() { return mBaseMetric->getUnit(); };
864 ULONG getMinValue() { return mBaseMetric->getMinValue(); };
865 ULONG getMaxValue() { return mBaseMetric->getMaxValue(); };
866 ULONG getPeriod() { return mBaseMetric->getPeriod(); };
867 ULONG getLength()
868 { return mAggregate ? 1 : mBaseMetric->getLength(); };
869 ULONG getScale() { return mBaseMetric->getScale(); }
870 void query(ULONG **data, ULONG *count, ULONG *sequenceNumber);
871
872 private:
873 RTCString mName;
874 BaseMetric *mBaseMetric;
875 SubMetric *mSubMetric;
876 Aggregate *mAggregate;
877 };
878
879 /* Filter Class *********************************************************/
880
881 class Filter
882 {
883 public:
884 Filter(ComSafeArrayIn(IN_BSTR, metricNames),
885 ComSafeArrayIn(IUnknown * , objects));
886 Filter(const com::Utf8Str name, const ComPtr<IUnknown> &aObject);
887 static bool patternMatch(const char *pszPat, const char *pszName,
888 bool fSeenColon = false);
889 bool match(const ComPtr<IUnknown> object, const RTCString &name) const;
890 private:
891 void init(ComSafeArrayIn(IN_BSTR, metricNames),
892 ComSafeArrayIn(IUnknown * , objects));
893
894 typedef std::pair<const ComPtr<IUnknown>, const RTCString> FilterElement;
895 typedef std::list<FilterElement> ElementList;
896
897 ElementList mElements;
898
899 void processMetricList(const com::Utf8Str &name, const ComPtr<IUnknown> object);
900 };
901}
902#endif /* ___performance_h */
903/* vi: set tabstop=4 shiftwidth=4 expandtab: */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use