VBoxManageMetrics.cpp revision 1207f59aa62006952dbb0bf7700decf34d8caeb2
9476d2be49d26a770787f5957478b930484c6ea5vboxsync * VBoxManage - The 'metrics' command.
3a8aa22ef125135ef67bfc396771bcee15ef02dfvboxsync * Copyright (C) 2006-2010 Oracle Corporation
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* Header Files *
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync*******************************************************************************/
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncusing namespace com;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync///////////////////////////////////////////////////////////////////////////////
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic char *toBaseMetricNames(const char *metricList)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync char *newList = (char*)RTMemAlloc(strlen(metricList) + 1);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync bool fSkip = false;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync while ((c = *src++))
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync if (c == ':')
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync else if (c == ',')
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic int parseFilterParameters(int argc, char *argv[],
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync /* Metric list */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync /* Object name */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(aVirtualBox, COMGETTER(Host)(host.asOutParam()));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync errorArgument("Invalid machine name: '%s'", argv[0]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync retMetrics.detachTo(ComSafeArrayOutArg(outMetrics));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync retBaseMetrics.detachTo(ComSafeArrayOutArg(outBaseMetrics));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync retObjects.detachTo(ComSafeArrayOutArg(outObjects));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic Bstr getObjectName(ComPtr<IVirtualBox> aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(machine, COMGETTER(Name)(name.asOutParam()));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic void listAffectedMetrics(ComPtr<IVirtualBox> aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeIfaceArray<IPerformanceMetric> metrics(ComSafeArrayInArg(aMetrics));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("The following metrics were modified:\n\n"
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync "Object Metric\n"
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync "---------- --------------------\n");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(metrics[i], COMGETTER(Object)(object.asOutParam()));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR(metrics[i], COMGETTER(MetricName)(metricName.asOutParam()));
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync getObjectName(aVirtualBox, object).raw(), metricName.raw());
3a8aa22ef125135ef67bfc396771bcee15ef02dfvboxsync RTMsgError("No metrics match the specified filter!");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic int handleMetricsList(int argc, char *argv[],
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IPerformanceCollector> performanceCollector)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync rc = parseFilterParameters(argc - 1, &argv[1], aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeIfaceArray<IPerformanceMetric> metricInfo;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync"Object Metric Unit Minimum Maximum Period Count Description\n"
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync"---------- -------------------- ---- ---------- ---------- ---------- ---------- -----------\n");
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 * Metics setup
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic int handleMetricsSetup(int argc, char *argv[],
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IPerformanceCollector> performanceCollector)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync bool listMatches = false;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorArgument("Missing argument to '%s'", argv[i]);
833069e69d399f40e0d571808c7d18dea777044avboxsync if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &period)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorArgument("Invalid value for 'period' parameter: '%s'", argv[i]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorArgument("Missing argument to '%s'", argv[i]);
833069e69d399f40e0d571808c7d18dea777044avboxsync if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &samples)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorArgument("Invalid value for 'samples' parameter: '%s'", argv[i]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync break; /* The rest of params should define the filter */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync rc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * metrics query
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic int handleMetricsQuery(int argc, char *argv[],
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IPerformanceCollector> performanceCollector)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync rc = parseFilterParameters(argc - 1, &argv[1], aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR (performanceCollector, QueryMetricsData(ComSafeArrayAsInParam(metrics),
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync "---------- -------------------- --------------------------------------------\n");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("%-10ls %-20ls ", getObjectName(aVirtualBox, retObjects[i]).raw(), metricName.raw());
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync for (unsigned j = 0; j < retLengths[i]; j++)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("%s%d %ls", separator, retData[retIndices[i] + j], metricUnit.raw());
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 pts += RTStrFormatNumber(pts, Time.u8Hour, 10, 2, 0, RTSTR_F_ZEROPAD);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync pts += RTStrFormatNumber(pts, Time.u8Minute, 10, 2, 0, RTSTR_F_ZEROPAD);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync pts += RTStrFormatNumber(pts, Time.u8Second, 10, 2, 0, RTSTR_F_ZEROPAD);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync pts += RTStrFormatNumber(pts, Time.u32Nanosecond / 1000000, 10, 3, 0, RTSTR_F_ZEROPAD);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync/** Used by the handleMetricsCollect loop. */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic bool volatile g_fKeepGoing = true;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * Handler routine for catching Ctrl-C, Ctrl-Break and closing of
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * the console.
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * @returns true if handled, false if not handled.
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * @param dwCtrlType The type of control signal.
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync * @remarks This is called on a new thread.
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync /* Ctrl-C or Ctrl-Break or Close */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync /* Let's shut down gracefully. */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync /* Don't care about the rest -- let it die a horrible death. */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#endif /* RT_OS_WINDOWS */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsyncstatic int handleMetricsCollect(int argc, char *argv[],
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IPerformanceCollector> performanceCollector)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorArgument("Missing argument to '%s'", argv[i]);
833069e69d399f40e0d571808c7d18dea777044avboxsync if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &period)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorArgument("Invalid value for 'period' parameter: '%s'", argv[i]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorArgument("Missing argument to '%s'", argv[i]);
833069e69d399f40e0d571808c7d18dea777044avboxsync if ( VINF_SUCCESS != RTStrToUInt32Full(argv[++i], 10, &samples)
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorArgument("Invalid value for 'samples' parameter: '%s'", argv[i]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync break; /* The rest of params should define the filter */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync rc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
3a8aa22ef125135ef67bfc396771bcee15ef02dfvboxsync RTMsgWarning("The background process holding collected metrics will shutdown\n"
3a8aa22ef125135ef67bfc396771bcee15ef02dfvboxsync "in few seconds, discarding all collected data and parameters.");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#endif /* RT_OS_WINDOWS */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTPrintf("------------ ---------- -------------------- --------------------\n");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync RTThreadSleep(period * 1000); // Sleep for 'period' seconds
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync CHECK_ERROR (performanceCollector, QueryMetricsData(ComSafeArrayAsInParam(metrics),
d873c7d42b4cd0c9841007f9a55d7b723c9dc0cevboxsync RTPrintf("%-12s %-10ls %-20ls ", ts, getObjectName(aVirtualBox, retObjects[j]).raw(), metricName.raw());
d873c7d42b4cd0c9841007f9a55d7b723c9dc0cevboxsync for (unsigned k = 0; k < retLengths[j]; k++)
d873c7d42b4cd0c9841007f9a55d7b723c9dc0cevboxsync RTPrintf("%s%d %ls", separator, retData[retIndices[j] + k], metricUnit.raw());
d873c7d42b4cd0c9841007f9a55d7b723c9dc0cevboxsync RTPrintf("%s%d.%02d%ls", separator, retData[retIndices[j] + k] / retScales[j],
d873c7d42b4cd0c9841007f9a55d7b723c9dc0cevboxsync (retData[retIndices[j] + k] * 100 / retScales[j]) % 100, metricUnit.raw());
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#endif /* RT_OS_WINDOWS */
e46a94731390fd08fb2097fab60d378853c4a293vboxsync * Enable metrics
e46a94731390fd08fb2097fab60d378853c4a293vboxsyncstatic int handleMetricsEnable(int argc, char *argv[],
e46a94731390fd08fb2097fab60d378853c4a293vboxsync ComPtr<IPerformanceCollector> performanceCollector)
e46a94731390fd08fb2097fab60d378853c4a293vboxsync bool listMatches = false;
e46a94731390fd08fb2097fab60d378853c4a293vboxsync break; /* The rest of params should define the filter */
e46a94731390fd08fb2097fab60d378853c4a293vboxsync rc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
e46a94731390fd08fb2097fab60d378853c4a293vboxsync com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
e46a94731390fd08fb2097fab60d378853c4a293vboxsync * Disable metrics
e46a94731390fd08fb2097fab60d378853c4a293vboxsyncstatic int handleMetricsDisable(int argc, char *argv[],
e46a94731390fd08fb2097fab60d378853c4a293vboxsync ComPtr<IPerformanceCollector> performanceCollector)
e46a94731390fd08fb2097fab60d378853c4a293vboxsync bool listMatches = false;
e46a94731390fd08fb2097fab60d378853c4a293vboxsync break; /* The rest of params should define the filter */
e46a94731390fd08fb2097fab60d378853c4a293vboxsync rc = parseFilterParameters(argc - i, &argv[i], aVirtualBox,
e46a94731390fd08fb2097fab60d378853c4a293vboxsync com::SafeIfaceArray<IPerformanceMetric> affectedMetrics;
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync /* at least one option: subcommand name */
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync return errorSyntax(USAGE_METRICS, "Subcommand missing");
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync ComPtr<IPerformanceCollector> performanceCollector;
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync CHECK_ERROR(a->virtualBox, COMGETTER(PerformanceCollector)(performanceCollector.asOutParam()));
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync rc = handleMetricsList(a->argc, a->argv, a->virtualBox, performanceCollector);
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync rc = handleMetricsSetup(a->argc, a->argv, a->virtualBox, performanceCollector);
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync rc = handleMetricsQuery(a->argc, a->argv, a->virtualBox, performanceCollector);
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync rc = handleMetricsCollect(a->argc, a->argv, a->virtualBox, performanceCollector);
e46a94731390fd08fb2097fab60d378853c4a293vboxsync rc = handleMetricsEnable(a->argc, a->argv, a->virtualBox, performanceCollector);
e46a94731390fd08fb2097fab60d378853c4a293vboxsync rc = handleMetricsDisable(a->argc, a->argv, a->virtualBox, performanceCollector);
4b34a2a15d6421e86cd192dfe63b817d1dab38a1vboxsync return errorSyntax(USAGE_METRICS, "Invalid subcommand '%s'", a->argv[0]);
5b93fdb3b4e681a6e4e01a3000f2a3ac07d99895vboxsync#endif /* VBOX_ONLY_DOCS */