So, I'm working on a python application that reports information about a host running VirtualBox to a webserver. Therefore I am using vboxapi. I can send information about the host with the following code:

from vboxapi import VirtualBoxManager
mgr = VirtualBoxManager(None, None)
vbox = mgr.vbox
host = vbox.host
log['host'] = {
    'processorCount': host.processorCount,
    'processorCoreCount': host.processorCoreCount,
    'processorOnlineCount': host.processorOnlineCount,
    'processorOnlineCoreCount': host.processorOnlineCoreCount,
    'memorySize': host.memorySize,
    'memoryAvailable': host.memoryAvailable,

What I would like to do is send information about the running guests, such as RAM and CPU usage. I can retrieve the max available amount of RAM with machine.memorySize, but not the current usage. When going through the vboxapi documentation, this should be possible with the PerformanceCollector, but I can get this to work, neither can I find a working example. Can someone help me with this?

The necessary steps are on page 274 of the docs.

Ps. my host is a Windows machine, my guests are Ubuntu 16.04.


I figured it out after all. Just in case anyone else is looking into this:

mgr = VirtualBoxManager(None, None)
vbox = mgr.vbox
# Enabling performance collection
perfomance_collector = self.vbox.performanceCollector
# Enable metrics (None = all metrics, None = all machines)
perfomance_collector.enableMetrics(None, None)
# Setup metrics (None = all metrics, None = all machines, 1 sample every second, keep up to 15 samples)
perfomance_collector.setupMetrics(None, None, 1, 15)

while True:
    # get metrics
    (values, names_out, objects_out, units, scales, sequence_numbers, indices, lengths) = perfomance_collector.queryMetricsData(None, None)
    out = []
    # process results
    for i in range(0, len(names_out)):
        scale = int(scales[i])
        if scale != 1:
            fmt = '%.2f%s'
            fmt = '%d %s'
            'name': str(names_out[i]),
            'object': str(objects_out[i]),
            'unit': str(units[i]),
            'scale': scale,
            'values': [int(values[j]) for j in range(int(indices[i]), int(indices[i]) + int(lengths[i]))],
            'values_as_string': '[' + ', '.join([fmt % (int(values[j]) / scale, units[i]) for j in range(int(indices[i]), int(indices[i]) + int(lengths[i]))]) + ']'
    # print something useful
    for metric in out:
        print(metric['name'], metric['values_as_string'])
|improve this answer|||||
  • How do you run this script? Just py <filename> or such? – Frank Nocke Sep 17 '18 at 15:18
  • It's part of a larger application, but if you combine the code of my question and answer, it should work I guess. – Joren Inghelbrecht Sep 18 '18 at 21:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.