VBoxManageMetrics.cpp revision e6e720b395adb47b68a3e440cfcd50f45e14c1a6
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync/* $Id$ */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync/** @file
9476d2be49d26a770787f5957478b930484c6ea5vboxsync * VBoxManage - The 'metrics' command.
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync/*
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * Copyright (C) 2006-2008 Sun Microsystems, Inc.
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync *
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * available from http://www.virtualbox.org. This file is free software;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * you can redistribute it and/or modify it under the terms of the GNU
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * General Public License (GPL) as published by the Free Software
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync *
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * additional information or have any questions.
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#ifndef VBOX_ONLY_DOCS
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync/*******************************************************************************
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync* Header Files *
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync*******************************************************************************/
b7782c7ad55341aaa2bcc6c5f20c8fcaf4d8dd7bvboxsync#include <VBox/com/com.h>
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#include <VBox/com/array.h>
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#include <VBox/com/ErrorInfo.h>
07bf154df97af02974bb89d4f1ad36afa2b45443vboxsync#include <VBox/com/errorprint2.h>
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#include <VBox/com/VirtualBox.h>
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
389492cf692ff5f76b379f1142092a3091e9bb8dvboxsync#include <iprt/asm.h>
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#include <iprt/stream.h>
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#include <iprt/string.h>
1715638289c28170682182429eaae968dddbe120vboxsync#include <iprt/time.h>
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#include <iprt/thread.h>
1715638289c28170682182429eaae968dddbe120vboxsync#include <VBox/log.h>
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#include "VBoxManage.h"
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncusing namespace com;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync// funcs
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync///////////////////////////////////////////////////////////////////////////////
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic char *toBaseMetricNames(const char *metricList)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync{
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync char *newList = (char*)RTMemAlloc(strlen(metricList) + 1);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync int cSlashes = 0;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync bool fSkip = false;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync const char *src = metricList;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync char c, *dst = newList;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync while ((c = *src++))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (c == ':')
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync fSkip = true;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync else if (c == '/' && ++cSlashes == 2)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync fSkip = true;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync else if (c == ',')
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync fSkip = false;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync cSlashes = 0;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync *dst++ = c;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync else
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (!fSkip)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync *dst++ = c;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync *dst = 0;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return newList;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync}
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic int parseFilterParameters(int argc, char *argv[],
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IVirtualBox> aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayOut(BSTR, outMetrics),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayOut(BSTR, outBaseMetrics),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayOut(IUnknown *, outObjects))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync{
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync HRESULT rc = S_OK;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<BSTR> retMetrics(1);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<BSTR> retBaseMetrics(1);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeIfaceArray <IUnknown> retObjects;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync Bstr metricNames, baseNames;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync /* Metric list */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (argc > 1)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync metricNames = argv[1];
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync char *tmp = toBaseMetricNames(argv[1]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (!tmp)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return VERR_NO_MEMORY;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync baseNames = tmp;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTMemFree(tmp);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync else
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync metricNames = L"*";
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync baseNames = L"*";
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync metricNames.cloneTo(&retMetrics[0]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync baseNames.cloneTo(&retBaseMetrics[0]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync /* Object name */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (argc > 0 && strcmp(argv[0], "*"))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (!strcmp(argv[0], "host"))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IHost> host;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(aVirtualBox, COMGETTER(Host)(host.asOutParam()));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync retObjects.reset(1);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync host.queryInterfaceTo(&retObjects[0]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync else
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr <IMachine> machine;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync rc = aVirtualBox->FindMachine(Bstr(argv[0]), machine.asOutParam());
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (SUCCEEDED (rc))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync retObjects.reset(1);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync machine.queryInterfaceTo(&retObjects[0]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync else
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync errorArgument("Invalid machine name: '%s'", argv[0]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return rc;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync retBaseMetrics.detachTo(ComSafeArrayOutArg(outBaseMetrics));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync retObjects.detachTo(ComSafeArrayOutArg(outObjects));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return rc;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync}
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic Bstr getObjectName(ComPtr<IVirtualBox> aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IUnknown> aObject)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync{
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync HRESULT rc;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IHost> host = aObject;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (!host.isNull())
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return Bstr("host");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IMachine> machine = aObject;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (!machine.isNull())
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync Bstr name;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(machine, COMGETTER(Name)(name.asOutParam()));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (SUCCEEDED(rc))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return name;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return Bstr("unknown");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync}
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic void listAffectedMetrics(ComPtr<IVirtualBox> aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayIn(IPerformanceMetric*, aMetrics))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync{
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync HRESULT rc;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeIfaceArray<IPerformanceMetric> metrics(ComSafeArrayInArg(aMetrics));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (metrics.size())
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IUnknown> object;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync Bstr metricName;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("The following metrics were modified:\n\n"
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync "Object Metric\n"
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync "---------- --------------------\n");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync for (size_t i = 0; i < metrics.size(); i++)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(metrics[i], COMGETTER(Object)(object.asOutParam()));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(metrics[i], COMGETTER(MetricName)(metricName.asOutParam()));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("%-10ls %-20ls\n",
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync getObjectName(aVirtualBox, object).raw(), metricName.raw());
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("\n");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync else
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("No metrics match the specified filter!\n");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync}
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync/**
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * list *
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic int handleMetricsList(int argc, char *argv[],
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IVirtualBox> aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IPerformanceCollector> performanceCollector)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync{
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync HRESULT rc;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<BSTR> metrics;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<BSTR> baseMetrics;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeIfaceArray<IUnknown> objects;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync rc = parseFilterParameters(argc - 1, &argv[1], aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(metrics),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(baseMetrics),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(objects));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (FAILED(rc))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return 1;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeIfaceArray<IPerformanceMetric> metricInfo;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(performanceCollector,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync GetMetrics(ComSafeArrayAsInParam(metrics),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsInParam(objects),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(metricInfo)));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IUnknown> object;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync Bstr metricName, unit, description;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ULONG period, count;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync LONG minimum, maximum;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf(
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync"Object Metric Unit Minimum Maximum Period Count Description\n"
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync"---------- -------------------- ---- ---------- ---------- ---------- ---------- -----------\n");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync for (size_t i = 0; i < metricInfo.size(); i++)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(metricInfo[i], COMGETTER(Object)(object.asOutParam()));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(metricInfo[i], COMGETTER(MetricName)(metricName.asOutParam()));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(metricInfo[i], COMGETTER(Period)(&period));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(metricInfo[i], COMGETTER(Count)(&count));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(metricInfo[i], COMGETTER(MinimumValue)(&minimum));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(metricInfo[i], COMGETTER(MaximumValue)(&maximum));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(metricInfo[i], COMGETTER(Unit)(unit.asOutParam()));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(metricInfo[i], COMGETTER(Description)(description.asOutParam()));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("%-10ls %-20ls %-4ls %10d %10d %10u %10u %ls\n",
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync getObjectName(aVirtualBox, object).raw(), metricName.raw(), unit.raw(),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync minimum, maximum, period, count, description.raw());
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return 0;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync}
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync/**
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * Metics setup
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic int handleMetricsSetup(int argc, char *argv[],
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IVirtualBox> aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IPerformanceCollector> performanceCollector)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync{
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync HRESULT rc;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<BSTR> metrics;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<BSTR> baseMetrics;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeIfaceArray<IUnknown> objects;
833069e69d399f40e0d571808c7d18dea777044avboxsync uint32_t period = 1, samples = 1;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync bool listMatches = false;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync int i;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync for (i = 1; i < argc; i++)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
e6e720b395adb47b68a3e440cfcd50f45e14c1a6vboxsync if ( !strcmp(argv[i], "--period")
e6e720b395adb47b68a3e440cfcd50f45e14c1a6vboxsync || !strcmp(argv[i], "-period"))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (argc <= i + 1)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorArgument("Missing argument to '%s'", argv[i]);
833069e69d399f40e0d571808c7d18dea777044avboxsync if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &period)
833069e69d399f40e0d571808c7d18dea777044avboxsync || !period)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorArgument("Invalid value for 'period' parameter: '%s'", argv[i]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
e6e720b395adb47b68a3e440cfcd50f45e14c1a6vboxsync else if ( !strcmp(argv[i], "--samples")
e6e720b395adb47b68a3e440cfcd50f45e14c1a6vboxsync || !strcmp(argv[i], "-samples"))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (argc <= i + 1)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorArgument("Missing argument to '%s'", argv[i]);
833069e69d399f40e0d571808c7d18dea777044avboxsync if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &samples)
833069e69d399f40e0d571808c7d18dea777044avboxsync || !samples)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorArgument("Invalid value for 'samples' parameter: '%s'", argv[i]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
e6e720b395adb47b68a3e440cfcd50f45e14c1a6vboxsync else if ( !strcmp(argv[i], "--list")
e6e720b395adb47b68a3e440cfcd50f45e14c1a6vboxsync || !strcmp(argv[i], "-list"))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync listMatches = true;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync else
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync break; /* The rest of params should define the filter */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync rc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(metrics),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(baseMetrics),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(objects));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (FAILED(rc))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return 1;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(performanceCollector,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync SetupMetrics(ComSafeArrayAsInParam(metrics),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsInParam(objects), period, samples,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(affectedMetrics)));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (listMatches)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync listAffectedMetrics(aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsInParam(affectedMetrics));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return 0;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync}
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync/**
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * metrics query
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic int handleMetricsQuery(int argc, char *argv[],
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IVirtualBox> aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IPerformanceCollector> performanceCollector)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync{
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync HRESULT rc;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<BSTR> metrics;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<BSTR> baseMetrics;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeIfaceArray<IUnknown> objects;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync rc = parseFilterParameters(argc - 1, &argv[1], aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(metrics),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(baseMetrics),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(objects));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (FAILED(rc))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return 1;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<BSTR> retNames;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeIfaceArray<IUnknown> retObjects;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<BSTR> retUnits;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<ULONG> retScales;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<ULONG> retSequenceNumbers;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<ULONG> retIndices;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<ULONG> retLengths;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<LONG> retData;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR (performanceCollector, QueryMetricsData(ComSafeArrayAsInParam(metrics),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsInParam(objects),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(retNames),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(retObjects),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(retUnits),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(retScales),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(retSequenceNumbers),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(retIndices),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(retLengths),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(retData)) );
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("Object Metric Values\n"
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync "---------- -------------------- --------------------------------------------\n");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync for (unsigned i = 0; i < retNames.size(); i++)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync Bstr metricUnit(retUnits[i]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync Bstr metricName(retNames[i]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("%-10ls %-20ls ", getObjectName(aVirtualBox, retObjects[i]).raw(), metricName.raw());
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync const char *separator = "";
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync for (unsigned j = 0; j < retLengths[i]; j++)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (retScales[i] == 1)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("%s%d %ls", separator, retData[retIndices[i] + j], metricUnit.raw());
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync else
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("%s%d.%02d%ls", separator, retData[retIndices[i] + j] / retScales[i],
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync (retData[retIndices[i] + j] * 100 / retScales[i]) % 100, metricUnit.raw());
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync separator = ", ";
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("\n");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return 0;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync}
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic void getTimestamp(char *pts, size_t tsSize)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync{
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync *pts = 0;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync AssertReturnVoid(tsSize >= 13); /* 3+3+3+3+1 */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTTIMESPEC TimeSpec;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTTIME Time;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTTimeExplode(&Time, RTTimeNow(&TimeSpec));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync pts += RTStrFormatNumber(pts, Time.u8Hour, 10, 2, 0, RTSTR_F_ZEROPAD);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync *pts++ = ':';
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync pts += RTStrFormatNumber(pts, Time.u8Minute, 10, 2, 0, RTSTR_F_ZEROPAD);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync *pts++ = ':';
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync pts += RTStrFormatNumber(pts, Time.u8Second, 10, 2, 0, RTSTR_F_ZEROPAD);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync *pts++ = '.';
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync pts += RTStrFormatNumber(pts, Time.u32Nanosecond / 1000000, 10, 3, 0, RTSTR_F_ZEROPAD);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync *pts = 0;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync}
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync/** Used by the handleMetricsCollect loop. */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic bool volatile g_fKeepGoing = true;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#ifdef RT_OS_WINDOWS
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync/**
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * Handler routine for catching Ctrl-C, Ctrl-Break and closing of
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * the console.
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync *
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * @returns true if handled, false if not handled.
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * @param dwCtrlType The type of control signal.
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync *
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * @remarks This is called on a new thread.
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic BOOL WINAPI ctrlHandler(DWORD dwCtrlType)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync{
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync switch (dwCtrlType)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync /* Ctrl-C or Ctrl-Break or Close */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync case CTRL_C_EVENT:
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync case CTRL_BREAK_EVENT:
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync case CTRL_CLOSE_EVENT:
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync /* Let's shut down gracefully. */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ASMAtomicWriteBool(&g_fKeepGoing, false);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return TRUE;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync /* Don't care about the rest -- let it die a horrible death. */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return FALSE;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync}
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#endif /* RT_OS_WINDOWS */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync/**
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * collect
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic int handleMetricsCollect(int argc, char *argv[],
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IVirtualBox> aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IPerformanceCollector> performanceCollector)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync{
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync HRESULT rc;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<BSTR> metrics;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<BSTR> baseMetrics;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeIfaceArray<IUnknown> objects;
833069e69d399f40e0d571808c7d18dea777044avboxsync uint32_t period = 1, samples = 1;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync bool isDetached = false, listMatches = false;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync int i;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync for (i = 1; i < argc; i++)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
e6e720b395adb47b68a3e440cfcd50f45e14c1a6vboxsync if ( !strcmp(argv[i], "--period")
e6e720b395adb47b68a3e440cfcd50f45e14c1a6vboxsync || !strcmp(argv[i], "-period"))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (argc <= i + 1)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorArgument("Missing argument to '%s'", argv[i]);
833069e69d399f40e0d571808c7d18dea777044avboxsync if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &period)
833069e69d399f40e0d571808c7d18dea777044avboxsync || !period)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorArgument("Invalid value for 'period' parameter: '%s'", argv[i]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
e6e720b395adb47b68a3e440cfcd50f45e14c1a6vboxsync else if ( !strcmp(argv[i], "--samples")
e6e720b395adb47b68a3e440cfcd50f45e14c1a6vboxsync || !strcmp(argv[i], "-samples"))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (argc <= i + 1)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorArgument("Missing argument to '%s'", argv[i]);
833069e69d399f40e0d571808c7d18dea777044avboxsync if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &samples)
833069e69d399f40e0d571808c7d18dea777044avboxsync || !samples)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorArgument("Invalid value for 'samples' parameter: '%s'", argv[i]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
e6e720b395adb47b68a3e440cfcd50f45e14c1a6vboxsync else if ( !strcmp(argv[i], "--list")
e6e720b395adb47b68a3e440cfcd50f45e14c1a6vboxsync || !strcmp(argv[i], "-list"))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync listMatches = true;
e6e720b395adb47b68a3e440cfcd50f45e14c1a6vboxsync else if ( !strcmp(argv[i], "--detach")
e6e720b395adb47b68a3e440cfcd50f45e14c1a6vboxsync || !strcmp(argv[i], "-detach"))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync isDetached = true;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync else
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync break; /* The rest of params should define the filter */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync rc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(metrics),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(baseMetrics),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(objects));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (FAILED(rc))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return 1;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(performanceCollector,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync SetupMetrics(ComSafeArrayAsInParam(baseMetrics),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsInParam(objects), period, samples,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(affectedMetrics)));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (listMatches)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync listAffectedMetrics(aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsInParam(affectedMetrics));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (!affectedMetrics.size())
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return 1;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (isDetached)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("Warning! The background process holding collected metrics will shutdown\n"
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync "in few seconds, discarding all collected data and parameters.\n");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return 0;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#ifdef RT_OS_WINDOWS
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync SetConsoleCtrlHandler(ctrlHandler, true);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#endif /* RT_OS_WINDOWS */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("Time stamp Object Metric Value\n");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync while (g_fKeepGoing)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("------------ ---------- -------------------- --------------------\n");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTThreadSleep(period * 1000); // Sleep for 'period' seconds
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync char ts[15];
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync getTimestamp(ts, sizeof(ts));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<BSTR> retNames;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeIfaceArray<IUnknown> retObjects;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<BSTR> retUnits;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<ULONG> retScales;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<ULONG> retSequenceNumbers;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<ULONG> retIndices;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<ULONG> retLengths;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeArray<LONG> retData;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR (performanceCollector, QueryMetricsData(ComSafeArrayAsInParam(metrics),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsInParam(objects),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(retNames),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(retObjects),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(retUnits),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(retScales),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(retSequenceNumbers),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(retIndices),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(retLengths),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComSafeArrayAsOutParam(retData)) );
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync for (unsigned i = 0; i < retNames.size(); i++)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync Bstr metricUnit(retUnits[i]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync Bstr metricName(retNames[i]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("%-12s %-10ls %-20ls ", ts, getObjectName(aVirtualBox, retObjects[i]).raw(), metricName.raw());
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync const char *separator = "";
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync for (unsigned j = 0; j < retLengths[i]; j++)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync {
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (retScales[i] == 1)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("%s%d %ls", separator, retData[retIndices[i] + j], metricUnit.raw());
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync else
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("%s%d.%02d%ls", separator, retData[retIndices[i] + j] / retScales[i],
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync (retData[retIndices[i] + j] * 100 / retScales[i]) % 100, metricUnit.raw());
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync separator = ", ";
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("\n");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync }
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#ifdef RT_OS_WINDOWS
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync SetConsoleCtrlHandler(ctrlHandler, false);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#endif /* RT_OS_WINDOWS */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return 0;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync}
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsyncint handleMetrics(HandlerArg *a)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync{
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync int rc;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync /* at least one option: subcommand name */
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync if (a->argc < 1)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorSyntax(USAGE_METRICS, "Subcommand missing");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IPerformanceCollector> performanceCollector;
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync CHECK_ERROR(a->virtualBox, COMGETTER(PerformanceCollector)(performanceCollector.asOutParam()));
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync if (!strcmp(a->argv[0], "list"))
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync rc = handleMetricsList(a->argc, a->argv, a->virtualBox, performanceCollector);
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync else if (!strcmp(a->argv[0], "setup"))
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync rc = handleMetricsSetup(a->argc, a->argv, a->virtualBox, performanceCollector);
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync else if (!strcmp(a->argv[0], "query"))
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync rc = handleMetricsQuery(a->argc, a->argv, a->virtualBox, performanceCollector);
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync else if (!strcmp(a->argv[0], "collect"))
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync rc = handleMetricsCollect(a->argc, a->argv, a->virtualBox, performanceCollector);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync else
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync return errorSyntax(USAGE_METRICS, "Invalid subcommand '%s'", a->argv[0]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return rc;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync}
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#endif /* VBOX_ONLY_DOCS */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync