VirtualBox

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

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

Main/Metrics: Do not collect data for unplugged host interfaces (#6345)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 33.7 KB
Line 
1/* $Id: Performance.h 43994 2012-11-29 08:58:17Z 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#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 list of disks used by the specified file system. */
392 virtual int getDiskListByFs(const char *name, DiskList& list);
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 preCollect(CollectorHints& hints, uint64_t iTick);
476 void collect();
477 private:
478 uint64_t mUserPrev;
479 uint64_t mKernelPrev;
480 uint64_t mIdlePrev;
481 };
482
483 class HostCpuMhz : public BaseMetric
484 {
485 public:
486 HostCpuMhz(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *mhz)
487 : BaseMetric(hal, "CPU/MHz", object), mMHz(mhz) {};
488 ~HostCpuMhz() { delete mMHz; };
489
490 void init(ULONG period, ULONG length);
491 void preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) {}
492 void collect();
493 const char *getUnit() { return "MHz"; };
494 ULONG getMinValue() { return 0; };
495 ULONG getMaxValue() { return INT32_MAX; };
496 ULONG getScale() { return 1; }
497 private:
498 SubMetric *mMHz;
499 };
500
501 class HostRamUsage : public BaseMetric
502 {
503 public:
504 HostRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available)
505 : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mUsed(used), mAvailable(available) {};
506 ~HostRamUsage() { delete mTotal; delete mUsed; delete mAvailable; };
507
508 void init(ULONG period, ULONG length);
509 void preCollect(CollectorHints& hints, uint64_t iTick);
510 void collect();
511 const char *getUnit() { return "kB"; };
512 ULONG getMinValue() { return 0; };
513 ULONG getMaxValue() { return INT32_MAX; };
514 ULONG getScale() { return 1; }
515 private:
516 SubMetric *mTotal;
517 SubMetric *mUsed;
518 SubMetric *mAvailable;
519 };
520
521 class HostNetworkSpeed : public BaseMetric
522 {
523 public:
524 HostNetworkSpeed(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str /* shortname */, com::Utf8Str /* ifname */, uint32_t speed, SubMetric *linkspeed)
525 : BaseMetric(hal, name, object), mSpeed(speed), mLinkSpeed(linkspeed) {};
526 ~HostNetworkSpeed() { delete mLinkSpeed; };
527
528 void init(ULONG period, ULONG length) { mPeriod = period; mLength = length; mLinkSpeed->init(length); };
529 void preCollect(CollectorHints& /* hints */, uint64_t /* iTick */) {};
530 void collect() { if (mSpeed) mLinkSpeed->put(mSpeed); };
531 const char *getUnit() { return "mbit/s"; };
532 ULONG getMinValue() { return 0; };
533 ULONG getMaxValue() { return INT32_MAX; };
534 ULONG getScale() { return 1; }
535 private:
536 ULONG mSpeed;
537 SubMetric *mLinkSpeed;
538 };
539
540 class HostNetworkLoadRaw : public BaseMetric
541 {
542 public:
543 HostNetworkLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str shortname, com::Utf8Str ifname, uint32_t speed, SubMetric *rx, SubMetric *tx)
544 : 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 */ };
545 ~HostNetworkLoadRaw() { delete mRx; delete mTx; };
546
547 void init(ULONG period, ULONG length);
548
549 void preCollect(CollectorHints& hints, uint64_t iTick);
550 void collect();
551 const char *getUnit() { return "%"; };
552 ULONG getMinValue() { return 0; };
553 ULONG getMaxValue() { return PM_NETWORK_LOAD_MULTIPLIER; };
554 ULONG getScale() { return PM_NETWORK_LOAD_MULTIPLIER / 100; }
555
556 private:
557 com::Utf8Str mShortName;
558 com::Utf8Str mInterfaceName;
559 SubMetric *mRx;
560 SubMetric *mTx;
561 uint64_t mRxPrev;
562 uint64_t mTxPrev;
563 uint64_t mSpeed;
564 int mRc;
565 };
566
567 class HostFilesystemUsage : public BaseMetric
568 {
569 public:
570 HostFilesystemUsage(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str fsname, SubMetric *total, SubMetric *used, SubMetric *available)
571 : BaseMetric(hal, name, object), mFsName(fsname), mTotal(total), mUsed(used), mAvailable(available) {};
572 ~HostFilesystemUsage() { delete mTotal; delete mUsed; delete mAvailable; };
573
574 void init(ULONG period, ULONG length);
575 void preCollect(CollectorHints& hints, uint64_t iTick);
576 void collect();
577 const char *getUnit() { return "mB"; };
578 ULONG getMinValue() { return 0; };
579 ULONG getMaxValue() { return INT32_MAX; };
580 ULONG getScale() { return 1; }
581 private:
582 com::Utf8Str mFsName;
583 SubMetric *mTotal;
584 SubMetric *mUsed;
585 SubMetric *mAvailable;
586 };
587
588 class HostDiskUsage : public BaseMetric
589 {
590 public:
591 HostDiskUsage(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str diskname, SubMetric *total)
592 : BaseMetric(hal, name, object), mDiskName(diskname), mTotal(total) {};
593 ~HostDiskUsage() { delete mTotal; };
594
595 void init(ULONG period, ULONG length);
596 void preCollect(CollectorHints& hints, uint64_t iTick);
597 void collect();
598 const char *getUnit() { return "mB"; };
599 ULONG getMinValue() { return 0; };
600 ULONG getMaxValue() { return INT32_MAX; };
601 ULONG getScale() { return 1; }
602 private:
603 com::Utf8Str mDiskName;
604 SubMetric *mTotal;
605 };
606
607 class HostDiskLoadRaw : public BaseMetric
608 {
609 public:
610 HostDiskLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, com::Utf8Str name, com::Utf8Str diskname, SubMetric *util)
611 : BaseMetric(hal, name, object), mDiskName(diskname), mUtil(util), mDiskPrev(0), mTotalPrev(0) {};
612 ~HostDiskLoadRaw() { delete mUtil; };
613
614 void init(ULONG period, ULONG length);
615
616 void preCollect(CollectorHints& hints, uint64_t iTick);
617 void collect();
618 const char *getUnit() { return "%"; };
619 ULONG getMinValue() { return 0; };
620 ULONG getMaxValue() { return PM_DISK_LOAD_MULTIPLIER; };
621 ULONG getScale() { return PM_DISK_LOAD_MULTIPLIER / 100; }
622
623 private:
624 com::Utf8Str mDiskName;
625 SubMetric *mUtil;
626 uint64_t mDiskPrev;
627 uint64_t mTotalPrev;
628 };
629
630
631#ifndef VBOX_COLLECTOR_TEST_CASE
632 class HostRamVmm : public BaseMetric
633 {
634 public:
635 HostRamVmm(CollectorGuestManager *gm, ComPtr<IUnknown> object, SubMetric *allocVMM, SubMetric *freeVMM, SubMetric *balloonVMM, SubMetric *sharedVMM)
636 : BaseMetric(NULL, "RAM/VMM", object), mCollectorGuestManager(gm),
637 mAllocVMM(allocVMM), mFreeVMM(freeVMM), mBalloonVMM(balloonVMM), mSharedVMM(sharedVMM),
638 mAllocCurrent(0), mFreeCurrent(0), mBalloonedCurrent(0), mSharedCurrent(0) {};
639 ~HostRamVmm() { delete mAllocVMM; delete mFreeVMM; delete mBalloonVMM; delete mSharedVMM; };
640
641 void init(ULONG period, ULONG length);
642 void preCollect(CollectorHints& hints, uint64_t iTick);
643 void collect();
644 int enable();
645 int disable();
646 const char *getUnit() { return "kB"; };
647 ULONG getMinValue() { return 0; };
648 ULONG getMaxValue() { return INT32_MAX; };
649 ULONG getScale() { return 1; }
650
651 private:
652 CollectorGuestManager *mCollectorGuestManager;
653 SubMetric *mAllocVMM;
654 SubMetric *mFreeVMM;
655 SubMetric *mBalloonVMM;
656 SubMetric *mSharedVMM;
657 ULONG mAllocCurrent;
658 ULONG mFreeCurrent;
659 ULONG mBalloonedCurrent;
660 ULONG mSharedCurrent;
661 };
662#endif /* VBOX_COLLECTOR_TEST_CASE */
663
664 class MachineCpuLoad : public BaseMetric
665 {
666 public:
667 MachineCpuLoad(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
668 : BaseMetric(hal, "CPU/Load", object), mProcess(process), mUser(user), mKernel(kernel) {};
669 ~MachineCpuLoad() { delete mUser; delete mKernel; };
670
671 void init(ULONG period, ULONG length);
672 void collect();
673 const char *getUnit() { return "%"; };
674 ULONG getMinValue() { return 0; };
675 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
676 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
677 protected:
678 RTPROCESS mProcess;
679 SubMetric *mUser;
680 SubMetric *mKernel;
681 };
682
683 class MachineCpuLoadRaw : public MachineCpuLoad
684 {
685 public:
686 MachineCpuLoadRaw(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *user, SubMetric *kernel)
687 : MachineCpuLoad(hal, object, process, user, kernel), mHostTotalPrev(0), mProcessUserPrev(0), mProcessKernelPrev(0) {};
688
689 void preCollect(CollectorHints& hints, uint64_t iTick);
690 void collect();
691 private:
692 uint64_t mHostTotalPrev;
693 uint64_t mProcessUserPrev;
694 uint64_t mProcessKernelPrev;
695 };
696
697 class MachineRamUsage : public BaseMetric
698 {
699 public:
700 MachineRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, RTPROCESS process, SubMetric *used)
701 : BaseMetric(hal, "RAM/Usage", object), mProcess(process), mUsed(used) {};
702 ~MachineRamUsage() { delete mUsed; };
703
704 void init(ULONG period, ULONG length);
705 void preCollect(CollectorHints& hints, uint64_t iTick);
706 void collect();
707 const char *getUnit() { return "kB"; };
708 ULONG getMinValue() { return 0; };
709 ULONG getMaxValue() { return INT32_MAX; };
710 ULONG getScale() { return 1; }
711 private:
712 RTPROCESS mProcess;
713 SubMetric *mUsed;
714 };
715
716
717#ifndef VBOX_COLLECTOR_TEST_CASE
718 typedef std::list<ComObjPtr<Medium> > MediaList;
719 class MachineDiskUsage : public BaseMetric
720 {
721 public:
722 MachineDiskUsage(CollectorHAL *hal, ComPtr<IUnknown> object, MediaList &disks, SubMetric *used)
723 : BaseMetric(hal, "Disk/Usage", object), mDisks(disks), mUsed(used) {};
724 ~MachineDiskUsage() { delete mUsed; };
725
726 void init(ULONG period, ULONG length);
727 void preCollect(CollectorHints& hints, uint64_t iTick);
728 void collect();
729 const char *getUnit() { return "mB"; };
730 ULONG getMinValue() { return 0; };
731 ULONG getMaxValue() { return INT32_MAX; };
732 ULONG getScale() { return 1; }
733 private:
734 MediaList mDisks;
735 SubMetric *mUsed;
736 };
737
738 /*
739 * Although MachineNetRate is measured for VM, not for the guest, it is
740 * derived from BaseGuestMetric since it uses the same mechanism for
741 * data collection -- values get pushed by Guest class along with other
742 * guest statistics.
743 */
744 class MachineNetRate : public BaseGuestMetric
745 {
746 public:
747 MachineNetRate(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *rx, SubMetric *tx)
748 : BaseGuestMetric(cguest, "Net/Rate", object), mRx(rx), mTx(tx) {};
749 ~MachineNetRate() { delete mRx; delete mTx; };
750
751 void init(ULONG period, ULONG length);
752 void preCollect(CollectorHints& hints, uint64_t iTick);
753 void collect();
754 int enable();
755 int disable();
756 const char *getUnit() { return "B/s"; };
757 ULONG getMinValue() { return 0; };
758 ULONG getMaxValue() { return INT32_MAX; };
759 ULONG getScale() { return 1; }
760 private:
761 SubMetric *mRx, *mTx;
762 };
763
764 class GuestCpuLoad : public BaseGuestMetric
765 {
766 public:
767 GuestCpuLoad(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *user, SubMetric *kernel, SubMetric *idle)
768 : BaseGuestMetric(cguest, "Guest/CPU/Load", object), mUser(user), mKernel(kernel), mIdle(idle) {};
769 ~GuestCpuLoad() { delete mUser; delete mKernel; delete mIdle; };
770
771 void init(ULONG period, ULONG length);
772 void preCollect(CollectorHints& hints, uint64_t iTick);
773 void collect();
774 int enable();
775 int disable();
776 const char *getUnit() { return "%"; };
777 ULONG getMinValue() { return 0; };
778 ULONG getMaxValue() { return PM_CPU_LOAD_MULTIPLIER; };
779 ULONG getScale() { return PM_CPU_LOAD_MULTIPLIER / 100; }
780 protected:
781 SubMetric *mUser;
782 SubMetric *mKernel;
783 SubMetric *mIdle;
784 };
785
786 class GuestRamUsage : public BaseGuestMetric
787 {
788 public:
789 GuestRamUsage(CollectorGuest *cguest, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *shared, SubMetric *cache, SubMetric *pagedtotal)
790 : BaseGuestMetric(cguest, "Guest/RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mCache(cache), mPagedTotal(pagedtotal), mShared(shared) {};
791 ~GuestRamUsage() { delete mTotal; delete mFree; delete mBallooned; delete mShared; delete mCache; delete mPagedTotal; };
792
793 void init(ULONG period, ULONG length);
794 void preCollect(CollectorHints& hints, uint64_t iTick);
795 void collect();
796 int enable();
797 int disable();
798 const char *getUnit() { return "kB"; };
799 ULONG getMinValue() { return 0; };
800 ULONG getMaxValue() { return INT32_MAX; };
801 ULONG getScale() { return 1; }
802 private:
803 SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal, *mShared;
804 };
805#endif /* VBOX_COLLECTOR_TEST_CASE */
806
807 /* Aggregate Functions **************************************************/
808 class Aggregate
809 {
810 public:
811 virtual ULONG compute(ULONG *data, ULONG length) = 0;
812 virtual const char *getName() = 0;
813 };
814
815 class AggregateAvg : public Aggregate
816 {
817 public:
818 virtual ULONG compute(ULONG *data, ULONG length);
819 virtual const char *getName();
820 };
821
822 class AggregateMin : public Aggregate
823 {
824 public:
825 virtual ULONG compute(ULONG *data, ULONG length);
826 virtual const char *getName();
827 };
828
829 class AggregateMax : public Aggregate
830 {
831 public:
832 virtual ULONG compute(ULONG *data, ULONG length);
833 virtual const char *getName();
834 };
835
836 /* Metric Class *********************************************************/
837 class Metric
838 {
839 public:
840 Metric(BaseMetric *baseMetric, SubMetric *subMetric, Aggregate *aggregate) :
841 mName(subMetric->getName()), mBaseMetric(baseMetric), mSubMetric(subMetric), mAggregate(aggregate)
842 {
843 if (mAggregate)
844 {
845 mName.append(":");
846 mName.append(mAggregate->getName());
847 }
848 }
849
850 ~Metric()
851 {
852 delete mAggregate;
853 }
854 bool associatedWith(ComPtr<IUnknown> object) { return getObject() == object; };
855
856 const char *getName() { return mName.c_str(); };
857 ComPtr<IUnknown> getObject() { return mBaseMetric->getObject(); };
858 const char *getDescription()
859 { return mAggregate ? "" : mSubMetric->getDescription(); };
860 const char *getUnit() { return mBaseMetric->getUnit(); };
861 ULONG getMinValue() { return mBaseMetric->getMinValue(); };
862 ULONG getMaxValue() { return mBaseMetric->getMaxValue(); };
863 ULONG getPeriod() { return mBaseMetric->getPeriod(); };
864 ULONG getLength()
865 { return mAggregate ? 1 : mBaseMetric->getLength(); };
866 ULONG getScale() { return mBaseMetric->getScale(); }
867 void query(ULONG **data, ULONG *count, ULONG *sequenceNumber);
868
869 private:
870 RTCString mName;
871 BaseMetric *mBaseMetric;
872 SubMetric *mSubMetric;
873 Aggregate *mAggregate;
874 };
875
876 /* Filter Class *********************************************************/
877
878 class Filter
879 {
880 public:
881 Filter(ComSafeArrayIn(IN_BSTR, metricNames),
882 ComSafeArrayIn(IUnknown * , objects));
883 Filter(const com::Utf8Str name, const ComPtr<IUnknown> &aObject);
884 static bool patternMatch(const char *pszPat, const char *pszName,
885 bool fSeenColon = false);
886 bool match(const ComPtr<IUnknown> object, const RTCString &name) const;
887 private:
888 void init(ComSafeArrayIn(IN_BSTR, metricNames),
889 ComSafeArrayIn(IUnknown * , objects));
890
891 typedef std::pair<const ComPtr<IUnknown>, const RTCString> FilterElement;
892 typedef std::list<FilterElement> ElementList;
893
894 ElementList mElements;
895
896 void processMetricList(const com::Utf8Str &name, const ComPtr<IUnknown> object);
897 };
898}
899#endif /* ___performance_h */
900/* 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