1 | /* $Id: UIVMActivityMonitor.h 106061 2024-09-16 14:03:52Z vboxsync $ */
|
---|
2 | /** @file
|
---|
3 | * VBox Qt GUI - UIVMActivityMonitor class declaration.
|
---|
4 | */
|
---|
5 |
|
---|
6 | /*
|
---|
7 | * Copyright (C) 2016-2024 Oracle and/or its affiliates.
|
---|
8 | *
|
---|
9 | * This file is part of VirtualBox base platform packages, as
|
---|
10 | * available from https://www.virtualbox.org.
|
---|
11 | *
|
---|
12 | * This program is free software; you can redistribute it and/or
|
---|
13 | * modify it under the terms of the GNU General Public License
|
---|
14 | * as published by the Free Software Foundation, in version 3 of the
|
---|
15 | * License.
|
---|
16 | *
|
---|
17 | * This program is distributed in the hope that it will be useful, but
|
---|
18 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
20 | * General Public License for more details.
|
---|
21 | *
|
---|
22 | * You should have received a copy of the GNU General Public License
|
---|
23 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
24 | *
|
---|
25 | * SPDX-License-Identifier: GPL-3.0-only
|
---|
26 | */
|
---|
27 |
|
---|
28 | #ifndef FEQT_INCLUDED_SRC_activity_vmactivity_UIVMActivityMonitor_h
|
---|
29 | #define FEQT_INCLUDED_SRC_activity_vmactivity_UIVMActivityMonitor_h
|
---|
30 | #ifndef RT_WITHOUT_PRAGMA_ONCE
|
---|
31 | # pragma once
|
---|
32 | #endif
|
---|
33 |
|
---|
34 | /* Qt includes: */
|
---|
35 | #include <QColor>
|
---|
36 | #include <QWidget>
|
---|
37 | #include <QMap>
|
---|
38 | #include <QQueue>
|
---|
39 | #include <QTextStream>
|
---|
40 | #include <QHash>
|
---|
41 |
|
---|
42 | /* COM includes: */
|
---|
43 | #include "CGuest.h"
|
---|
44 | #include "CMachine.h"
|
---|
45 | #include "CCloudMachine.h"
|
---|
46 | #include "CMachineDebugger.h"
|
---|
47 | #include "CPerformanceCollector.h"
|
---|
48 | #include "CSession.h"
|
---|
49 |
|
---|
50 | /* GUI includes: */
|
---|
51 | #include "QIManagerDialog.h"
|
---|
52 | #include "UIMonitorCommon.h"
|
---|
53 |
|
---|
54 | /* Forward declarations: */
|
---|
55 | class QGridLayout;
|
---|
56 | class QTimer;
|
---|
57 | class QVBoxLayout;
|
---|
58 | class QLabel;
|
---|
59 | class UIActionPool;
|
---|
60 | class UIChart;
|
---|
61 | class UISession;
|
---|
62 | class UIRuntimeInfoWidget;
|
---|
63 | class UIProgressTaskReadCloudMachineMetricList;
|
---|
64 |
|
---|
65 | #define DATA_SERIES_SIZE 2
|
---|
66 |
|
---|
67 | enum Metric_Type
|
---|
68 | {
|
---|
69 | Metric_Type_CPU = 0,
|
---|
70 | Metric_Type_RAM,
|
---|
71 | Metric_Type_Disk_InOut,
|
---|
72 | Metric_Type_Disk_In,
|
---|
73 | Metric_Type_Disk_Out,
|
---|
74 | Metric_Type_Network_InOut,
|
---|
75 | Metric_Type_Network_In,
|
---|
76 | Metric_Type_Network_Out,
|
---|
77 | Metric_Type_VM_Exits,
|
---|
78 | Metric_Type_Max
|
---|
79 | };
|
---|
80 |
|
---|
81 | /** UIMetric represents a performance metric and is used to store data related to the corresponding metric. */
|
---|
82 | class UIMetric
|
---|
83 | {
|
---|
84 |
|
---|
85 | public:
|
---|
86 |
|
---|
87 | UIMetric(const QString &strUnit, int iMaximumQueueSize);
|
---|
88 | UIMetric();
|
---|
89 |
|
---|
90 | void setMaximum(quint64 iMaximum);
|
---|
91 | quint64 maximum() const;
|
---|
92 |
|
---|
93 | void setUnit(QString strUnit);
|
---|
94 | const QString &unit() const;
|
---|
95 |
|
---|
96 | void addData(int iDataSeriesIndex, quint64 fData);
|
---|
97 | void addData(int iDataSeriesIndex, quint64 fData, const QString &strLabel);
|
---|
98 |
|
---|
99 | const QQueue<quint64> *data(int iDataSeriesIndex) const;
|
---|
100 | const QQueue<QString> *labels() const;
|
---|
101 | bool hasDataLabels() const;
|
---|
102 |
|
---|
103 | /** # of the data point of the data series with index iDataSeriesIndex. */
|
---|
104 | int dataSize(int iDataSeriesIndex) const;
|
---|
105 |
|
---|
106 | void setDataSeriesName(int iDataSeriesIndex, const QString &strName);
|
---|
107 | QString dataSeriesName(int iDataSeriesIndex) const;
|
---|
108 |
|
---|
109 | void setTotal(int iDataSeriesIndex, quint64 iTotal);
|
---|
110 | quint64 total(int iDataSeriesIndex) const;
|
---|
111 |
|
---|
112 | bool requiresGuestAdditions() const;
|
---|
113 | void setRequiresGuestAdditions(bool fRequiresGAs);
|
---|
114 |
|
---|
115 | void setIsInitialized(bool fIsInitialized);
|
---|
116 | bool isInitialized() const;
|
---|
117 |
|
---|
118 | void reset();
|
---|
119 | void toFile(QTextStream &stream) const;
|
---|
120 |
|
---|
121 | void setAutoUpdateMaximum(bool fAuto);
|
---|
122 | bool autoUpdateMaximum() const;
|
---|
123 |
|
---|
124 | private:
|
---|
125 | void updateMax();
|
---|
126 |
|
---|
127 | QString m_strUnit;
|
---|
128 | QString m_strDataSeriesName[DATA_SERIES_SIZE];
|
---|
129 | quint64 m_iMaximum;
|
---|
130 | QQueue<quint64> m_data[DATA_SERIES_SIZE];
|
---|
131 | /** We assume m_data[0] and m_data[1] have a common label array. */
|
---|
132 | QQueue<QString> m_labels;
|
---|
133 | /** The total data (the counter value we get from IMachineDebugger API). For the metrics
|
---|
134 | * we get from IMachineDebugger m_data values are computed as deltas of total values t - (t-1) */
|
---|
135 | quint64 m_iTotal[DATA_SERIES_SIZE];
|
---|
136 |
|
---|
137 | bool m_fRequiresGuestAdditions;
|
---|
138 | /** Used for metrices whose data is computed as total deltas. That is we receieve only total value and
|
---|
139 | * compute time step data from total deltas. m_isInitialised is true if the total has been set first time. */
|
---|
140 | bool m_fIsInitialized;
|
---|
141 | /** Maximum is updated as a new data is added to data queue. */
|
---|
142 | bool m_fAutoUpdateMaximum;
|
---|
143 | int m_iMaximumQueueSize;
|
---|
144 | };
|
---|
145 |
|
---|
146 | /** UIVMActivityMonitor class displays some high level performance metrics of the guest system.
|
---|
147 | * The values are read in certain periods and cached in the GUI side. Currently we draw some line charts
|
---|
148 | * and pie charts (where applicable) alongside with some text. IPerformanceCollector and IMachineDebugger are
|
---|
149 | * two sources of the performance metrics. Unfortunately these two have very distinct APIs resulting a bit too much
|
---|
150 | * special casing etc.*/
|
---|
151 | class SHARED_LIBRARY_STUFF UIVMActivityMonitor : public QWidget
|
---|
152 | {
|
---|
153 |
|
---|
154 | Q_OBJECT;
|
---|
155 |
|
---|
156 | public:
|
---|
157 |
|
---|
158 | UIVMActivityMonitor(EmbedTo enmEmbedding, QWidget *pParent, UIActionPool *pActionPool, int iMaximumQueueSize);
|
---|
159 | virtual QUuid machineId() const = 0;
|
---|
160 | virtual QString machineName() const = 0;
|
---|
161 | void setDataSeriesColor(int iIndex, const QColor &color);
|
---|
162 |
|
---|
163 | public slots:
|
---|
164 |
|
---|
165 | void sltExportMetricsToFile();
|
---|
166 |
|
---|
167 | protected slots:
|
---|
168 |
|
---|
169 | virtual void sltRetranslateUI();
|
---|
170 |
|
---|
171 | protected:
|
---|
172 |
|
---|
173 | virtual void obtainDataAndUpdate() = 0;
|
---|
174 | virtual QString defaultMachineFolder() const = 0;
|
---|
175 | virtual void reset() = 0;
|
---|
176 | virtual void start() = 0;
|
---|
177 |
|
---|
178 | QString dataColorString(Metric_Type enmType, int iDataIndex);
|
---|
179 |
|
---|
180 | /** @name The following functions reset corresponding info labels
|
---|
181 | * @{ */
|
---|
182 | virtual void resetCPUInfoLabel() = 0;
|
---|
183 | void resetRAMInfoLabel();
|
---|
184 | /** @} */
|
---|
185 |
|
---|
186 | virtual void prepareWidgets();
|
---|
187 | void prepareActions();
|
---|
188 | void setInfoLabelWidth();
|
---|
189 |
|
---|
190 | QGridLayout *m_pContainerLayout;
|
---|
191 | QTimer *m_pTimer;
|
---|
192 | quint64 m_iTimeStep;
|
---|
193 | QMap<Metric_Type, UIMetric> m_metrics;
|
---|
194 |
|
---|
195 | /** @name The following are used during UIPerformanceCollector::QueryMetricsData(..)
|
---|
196 | * @{ */
|
---|
197 | QVector<QString> m_nameList;
|
---|
198 | QVector<CUnknown> m_objectList;
|
---|
199 | /** @} */
|
---|
200 | QMap<Metric_Type, UIChart*> m_charts;
|
---|
201 | QMap<Metric_Type, QLabel*> m_infoLabels;
|
---|
202 |
|
---|
203 | /** @name Cached translated strings.
|
---|
204 | * @{ */
|
---|
205 | /** CPU info label strings. */
|
---|
206 | QString m_strCPUInfoLabelTitle;
|
---|
207 | QString m_strCPUInfoLabelGuest;
|
---|
208 | QString m_strCPUInfoLabelVMM;
|
---|
209 | /** RAM usage info label strings. */
|
---|
210 | QString m_strRAMInfoLabelTitle;
|
---|
211 | QString m_strRAMInfoLabelTotal;
|
---|
212 | QString m_strRAMInfoLabelFree;
|
---|
213 | QString m_strRAMInfoLabelUsed;
|
---|
214 | /** Net traffic info label strings. */
|
---|
215 | QString m_strNetworkInfoLabelReceived;
|
---|
216 | QString m_strNetworkInfoLabelTransmitted;
|
---|
217 | QString m_strNetworkInfoLabelReceivedTotal;
|
---|
218 | QString m_strNetworkInfoLabelTransmittedTotal;
|
---|
219 | /** Disk IO info label strings. */
|
---|
220 | QString m_strDiskIOInfoLabelTitle;
|
---|
221 | QString m_strDiskIOInfoLabelWritten;
|
---|
222 | QString m_strDiskIOInfoLabelRead;
|
---|
223 | QString m_strDiskIOInfoLabelWrittenTotal;
|
---|
224 | QString m_strDiskIOInfoLabelReadTotal;
|
---|
225 | /** @} */
|
---|
226 | int m_iMaximumLabelLength;
|
---|
227 | int m_iMaximumQueueSize;
|
---|
228 | QColor m_dataSeriesColor[DATA_SERIES_SIZE];
|
---|
229 | UIActionPool *m_pActionPool;
|
---|
230 | private slots:
|
---|
231 |
|
---|
232 | /** Reads the metric values for several sources and calls corresponding update functions. */
|
---|
233 | void sltTimeout();
|
---|
234 | void sltCreateContextMenu(const QPoint &point);
|
---|
235 |
|
---|
236 | private:
|
---|
237 |
|
---|
238 | bool guestAdditionsAvailable(const char *pszMinimumVersion);
|
---|
239 |
|
---|
240 | /** Holds the instance of layout we create. */
|
---|
241 | QVBoxLayout *m_pMainLayout;
|
---|
242 | EmbedTo m_enmEmbedding;
|
---|
243 | };
|
---|
244 |
|
---|
245 | class SHARED_LIBRARY_STUFF UIVMActivityMonitorLocal : public UIVMActivityMonitor
|
---|
246 | {
|
---|
247 |
|
---|
248 | Q_OBJECT;
|
---|
249 |
|
---|
250 | public:
|
---|
251 |
|
---|
252 | /** Constructs information-tab passing @a pParent to the QWidget base-class constructor.
|
---|
253 | * @param machine is machine reference. */
|
---|
254 | UIVMActivityMonitorLocal(EmbedTo enmEmbedding, QWidget *pParent, const CMachine &machine, UIActionPool *pActionPool);
|
---|
255 | ~UIVMActivityMonitorLocal();
|
---|
256 | virtual QUuid machineId() const RT_OVERRIDE;
|
---|
257 | virtual QString machineName() const RT_OVERRIDE;
|
---|
258 | void guestAdditionsStateChange();
|
---|
259 |
|
---|
260 | protected slots:
|
---|
261 |
|
---|
262 | virtual void sltRetranslateUI() RT_OVERRIDE;
|
---|
263 |
|
---|
264 | protected:
|
---|
265 |
|
---|
266 | virtual void obtainDataAndUpdate() RT_OVERRIDE;
|
---|
267 | virtual QString defaultMachineFolder() const RT_OVERRIDE;
|
---|
268 | virtual void reset() RT_OVERRIDE;
|
---|
269 | virtual void start() RT_OVERRIDE;
|
---|
270 |
|
---|
271 | private slots:
|
---|
272 |
|
---|
273 | /** Stop updating the charts if/when the machine state changes something other than KMachineState_Running. */
|
---|
274 | void sltMachineStateChange(const QUuid &uId);
|
---|
275 | void sltClearCOMData();
|
---|
276 |
|
---|
277 | private:
|
---|
278 |
|
---|
279 | void setMachine(const CMachine &machine);
|
---|
280 | void openSession();
|
---|
281 | void prepareMetrics();
|
---|
282 | bool guestAdditionsAvailable(const char *pszMinimumVersion);
|
---|
283 | void enableDisableGuestAdditionDependedWidgets(bool fEnable);
|
---|
284 | void updateCPUChart(quint64 iLoadPercentage, ULONG iOtherPercentage);
|
---|
285 | void updateRAMGraphsAndMetric(quint64 iTotalRAM, quint64 iFreeRAM);
|
---|
286 | void updateNetworkChart(quint64 uReceiveTotal, quint64 uTransmitTotal);
|
---|
287 | void updateDiskIOChart(quint64 uDiskIOTotalWritten, quint64 uDiskIOTotalRead);
|
---|
288 | void updateVMExitMetric(quint64 uTotalVMExits);
|
---|
289 | void resetVMExitInfoLabel();
|
---|
290 | virtual void resetCPUInfoLabel() RT_OVERRIDE;
|
---|
291 | void resetNetworkInfoLabel();
|
---|
292 | void resetDiskIOInfoLabel();
|
---|
293 | virtual void prepareWidgets() RT_OVERRIDE;
|
---|
294 | void configureCOMPerformanceCollector();
|
---|
295 |
|
---|
296 | bool m_fGuestAdditionsAvailable;
|
---|
297 | CMachine m_comMachine;
|
---|
298 | CSession m_comSession;
|
---|
299 | CGuest m_comGuest;
|
---|
300 |
|
---|
301 | CPerformanceCollector m_performanceCollector;
|
---|
302 | bool m_fCOMPerformanceCollectorConfigured;
|
---|
303 | CMachineDebugger m_comMachineDebugger;
|
---|
304 | /** VM Exit info label strings. */
|
---|
305 | QString m_strVMExitInfoLabelTitle;
|
---|
306 | QString m_strVMExitLabelCurrent;
|
---|
307 | QString m_strVMExitLabelTotal;
|
---|
308 | QString m_strNetworkInfoLabelTitle;
|
---|
309 | };
|
---|
310 |
|
---|
311 | class SHARED_LIBRARY_STUFF UIVMActivityMonitorCloud : public UIVMActivityMonitor
|
---|
312 | {
|
---|
313 |
|
---|
314 | Q_OBJECT;
|
---|
315 |
|
---|
316 | public:
|
---|
317 |
|
---|
318 | UIVMActivityMonitorCloud(EmbedTo enmEmbedding, QWidget *pParent, const CCloudMachine &machine, UIActionPool *pActionPool);
|
---|
319 | virtual QUuid machineId() const RT_OVERRIDE;
|
---|
320 | virtual QString machineName() const RT_OVERRIDE;
|
---|
321 | /** According to OCI docs returned time stamp is in RFC3339 format. */
|
---|
322 | static QString formatCloudTimeStamp(const QString &strInput);
|
---|
323 |
|
---|
324 | protected slots:
|
---|
325 |
|
---|
326 | virtual void sltRetranslateUI() RT_OVERRIDE;
|
---|
327 |
|
---|
328 | private slots:
|
---|
329 |
|
---|
330 | void sltMetricNameListingComplete(QVector<QString> metricNameList);
|
---|
331 | void sltMetricDataReceived(KMetricType enmMetricType,
|
---|
332 | const QVector<QString> &data, const QVector<QString> &timeStamps);
|
---|
333 | void sltMachineStateUpdateTimeout();
|
---|
334 |
|
---|
335 | private:
|
---|
336 | void setMachine(const CCloudMachine &comMachine);
|
---|
337 | virtual void obtainDataAndUpdate() RT_OVERRIDE;
|
---|
338 |
|
---|
339 | virtual QString defaultMachineFolder() const RT_OVERRIDE;
|
---|
340 | virtual void reset() RT_OVERRIDE;
|
---|
341 | virtual void start() RT_OVERRIDE;
|
---|
342 | virtual void prepareWidgets() RT_OVERRIDE;
|
---|
343 | /** @name The following functions update corresponding metric charts and labels with new values
|
---|
344 | * @{ */
|
---|
345 | void updateCPUChart(quint64 iLoadPercentage, const QString &strLabel);
|
---|
346 | void updateNetworkInChart(quint64 uReceive, const QString &strLabel);
|
---|
347 | void updateNetworkOutChart(quint64 uTransmit, const QString &strLabel);
|
---|
348 | void updateDiskIOReadChart(quint64 uReadRate, const QString &strLabel);
|
---|
349 | void updateDiskIOWrittenChart(quint64 uWriteRate, const QString &strLabel);
|
---|
350 | void updateRAMChart(quint64 iUsagePercentage, const QString &strLabel);
|
---|
351 | /** @} */
|
---|
352 | virtual void resetCPUInfoLabel() RT_OVERRIDE;
|
---|
353 | void resetNetworkInInfoLabel();
|
---|
354 | void resetNetworkOutInfoLabel();
|
---|
355 | void resetDiskIOWrittenInfoLabel();
|
---|
356 | void resetDiskIOReadInfoLabel();
|
---|
357 |
|
---|
358 | bool findMetric(KMetricType enmMetricType, UIMetric &metric, int &iDataSeriesIndex) const;
|
---|
359 | void prepareMetrics();
|
---|
360 |
|
---|
361 | CCloudMachine m_comMachine;
|
---|
362 | QPointer<UIProgressTaskReadCloudMachineMetricList> m_ReadListProgressTask;
|
---|
363 |
|
---|
364 | QVector<KMetricType> m_availableMetricTypes;
|
---|
365 | /** Mapping from API enums to internal metric type enum. */
|
---|
366 | QHash<KMetricType, Metric_Type> m_metricTypeDict;
|
---|
367 |
|
---|
368 | /** Total amount of RAM in kb. */
|
---|
369 | quint64 m_uTotalRAM;
|
---|
370 | QTimer *m_pMachineStateUpdateTimer;
|
---|
371 | KCloudMachineState m_enmMachineState;
|
---|
372 |
|
---|
373 | QString m_strNetworkInInfoLabelTitle;
|
---|
374 | QString m_strNetworkOutInfoLabelTitle;
|
---|
375 | };
|
---|
376 | #endif /* !FEQT_INCLUDED_SRC_activity_vmactivity_UIVMActivityMonitor_h */
|
---|