why it returns worng performance metrics

Discussion about using the VirtualBox API, Tutorials, Samples.
Ghetas
Posts: 19
Joined: 19. Dec 2015, 17:35

why it returns worng performance metrics

Post by Ghetas »

hello every one
I am trying to collect performance metrics for CPU using the below code. the code is running without error but the performance metrics values i got from the code is completely different when it is compared with the values from top command

Code: Select all

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.virtualbox_5_0.Holder;
import org.virtualbox_5_0.IMachine;
import org.virtualbox_5_0.IPerformanceCollector;
import org.virtualbox_5_0.IUnknown;
import org.virtualbox_5_0.IVirtualBox;
import org.virtualbox_5_0.VBoxException;
import org.virtualbox_5_0.VirtualBoxManager;


public class VmIPerformanceCollector {
	IVirtualBox vbox;
	IMachine machine;
	IPerformanceCollector oCollector;
	VirtualBoxManager mgr;
	String machinename;

	long scale;
	double Cpuutilization;
	
	public VmIPerformanceCollector(String machinename){
		this.machinename=machinename;
		
	}
	@SuppressWarnings("finally")
	public boolean ConnecttoVirtualbox(){
		boolean connectsucess=false;
		mgr = VirtualBoxManager.createInstance(null);
		try{
			mgr.connect(vm.getVboxsrvUrl(), null, null);
			vbox=mgr.getVBox();
			machine=vbox.findMachine(machinename);
			
		}catch (VBoxException e){
			e.printStackTrace();
		}finally{
		return connectsucess;
		}
	}
	
	public void setup(long Period, long Count){
		 oCollector = vbox.getPerformanceCollector();
         oCollector.setupMetrics(Arrays.asList(new String[]{"CPU/*:avg"}),
                 new ArrayList<IUnknown>(),
                 Period, Count);
	}

	public void CollectCpuUtilization(long time) throws InterruptedException{
		

        Holder<List<String>> names = new Holder<List<String>> ();
        Holder<List<IUnknown>> objects = new Holder<List<IUnknown>>() ;
        Holder<List<String>> units = new Holder<List<String>>();
        Holder<List<Long>> scales =  new Holder<List<Long>>();
        Holder<List<Long>> sequenceNumbers =  new Holder<List<Long>>();
        Holder<List<Long>> indices =  new Holder<List<Long>>();
        Holder<List<Long>> lengths =  new Holder<List<Long>>();
        oCollector = vbox.getPerformanceCollector();         

        List<Integer> values = oCollector.queryMetricsData(Arrays.asList(new String[]{"CPU/*:avg"}),
                Arrays.asList(new IUnknown[]{machine}),
                names, objects, units, scales,
                sequenceNumbers, indices, lengths);
        Cpuutilization=0;
        System.out.println();
        for (int i=0; i < names.value.size(); i++){
        		scale=scales.value.get(i);
        		System.out.println(names.value.get(i));
                for (int j = 0; j < lengths.value.get(i); j++)
                {
                    long val= values.get(indices.value.get(i).intValue() + j).longValue();
                    System.out.println(val);
                    Long val2=val;
                }
        }

        System.out.println("------------------");
        disconnect();
        
	}
	
	public void disconnect(){
        try {
            mgr.disconnect();
        } catch (VBoxException e) {
        	e.printStackTrace();
			safeprinterr.safeprintErr(e.getMessage());
			safePrintln.safeprintln("Cannot disconnect, start webserver first!");
        }
        mgr.cleanup();
	}

}
and i call the VmIPerformanceCollector from the main

Code: Select all



public class testcpuperformance {
	
	public static void main(String[] args) throws InterruptedException{
		
		String VmName="VmLab11";

		VmIPerformanceCollector vmper=new VmIPerformanceCollector(VmName);
		vmper.ConnecttoVirtualbox();
		vmper.setup(new Long(1), new Long(3));
		vmper.disconnect();
		for(int i=1; i<100; i++){
			Thread.sleep(2000);
			vmper.ConnecttoVirtualbox();
			
			vmper.CollectCpuUtilization(3);
		}
	}
}
and the output is

Code: Select all

CPU/Load/User
250
375
CPU/Load/Kernel
250
250
------------------

CPU/Load/User
375
250
125
CPU/Load/Kernel
250
125
250
------------------
the performance values are completely different from that i got using the top commands

i am using
Centos 6.7
Virtualbox 5.0.12
Language Java (jdk 1.7)

any help will be appreciated
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: why it returns worng performance metrics

Post by noteirak »

Nothing looks wrong to me, you do get values back.
If you are concerned about the values themselves, the CPU Load per example would be from 0 to 100 per CPU configured in the VM. so if you have 4 CPU all running at 50%, you'll get a load of 200.
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: why it returns worng performance metrics

Post by noteirak »

Actually, checking the doc again to be sure, here is the meaning of CPU/Load:

Code: Select all

CPU/Load/User        %             0     100000          0          0 Percentage of processor time spent in user mode by the VM process.
If you want a full list of metrics and their meaning, via the API: IPerformanceCollector::metrics and then ::getMetrics() on each and finally IPerformanceMetric::getDescription()

via vboxmanage:

Code: Select all

vboxmanage metrics list
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
Ghetas
Posts: 19
Joined: 19. Dec 2015, 17:35

Re: why it returns worng performance metrics

Post by Ghetas »

noteirak wrote:Nothing looks wrong to me, you do get values back.
If you are concerned about the values themselves, the CPU Load per example would be from 0 to 100 per CPU configured in the VM. so if you have 4 CPU all running at 50%, you'll get a load of 200.

thanks noteirak
now i update my code to display metric name, unit and scale as indicated by the comments

Code: Select all

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import org.virtualbox_5_0.Holder;
    import org.virtualbox_5_0.IMachine;
    import org.virtualbox_5_0.IPerformanceCollector;
    import org.virtualbox_5_0.IUnknown;
    import org.virtualbox_5_0.IVirtualBox;
    import org.virtualbox_5_0.VBoxException;
    import org.virtualbox_5_0.VirtualBoxManager;


    public class VmIPerformanceCollector {
       IVirtualBox vbox;
       IMachine machine;
       IPerformanceCollector oCollector;
       VirtualBoxManager mgr;
       String machinename;

       long scale;
       double Cpuutilization;
       
       public VmIPerformanceCollector(String machinename){
          this.machinename=machinename;
          
       }
       @SuppressWarnings("finally")
       public boolean ConnecttoVirtualbox(){
          boolean connectsucess=false;
          mgr = VirtualBoxManager.createInstance(null);
          try{
             mgr.connect(vm.getVboxsrvUrl(), null, null);
             vbox=mgr.getVBox();
             machine=vbox.findMachine(machinename);
             
          }catch (VBoxException e){
             e.printStackTrace();
          }finally{
          return connectsucess;
          }
       }
       
       public void setup(long Period, long Count){
           oCollector = vbox.getPerformanceCollector();
             oCollector.setupMetrics(Arrays.asList(new String[]{"CPU/*:avg"}),
                     new ArrayList<IUnknown>(),
                     Period, Count);
       }

       public void CollectCpuUtilization(long time) throws InterruptedException{
          

            Holder<List<String>> names = new Holder<List<String>> ();
            Holder<List<IUnknown>> objects = new Holder<List<IUnknown>>() ;
            Holder<List<String>> units = new Holder<List<String>>();
            Holder<List<Long>> scales =  new Holder<List<Long>>();
            Holder<List<Long>> sequenceNumbers =  new Holder<List<Long>>();
            Holder<List<Long>> indices =  new Holder<List<Long>>();
            Holder<List<Long>> lengths =  new Holder<List<Long>>();
            oCollector = vbox.getPerformanceCollector();         

            List<Integer> values = oCollector.queryMetricsData(Arrays.asList(new String[]{"CPU/*:avg"}),
                    Arrays.asList(new IUnknown[]{machine}),
                    names, objects, units, scales,
                    sequenceNumbers, indices, lengths);
            Cpuutilization=0;
            System.out.println();
           // new updated part
            for (int i=0; i < names.value.size(); i++){
                 scale=scales.value.get(i);
                  System.out.println(names.value.get(i));
        		System.out.println("Metric Name: "+names.value.get(i));
        		System.out.println("Scale: "+scales.value.get(i));
        		System.out.println("unit: "+units.value.get(i));
        		scale=scales.value.get(i);
                for (int j = 0; j < lengths.value.get(i); j++)
                {
                    long val= values.get(indices.value.get(i).intValue() + j).longValue();
                    System.out.println("value: "+ val); 
                }
            }

            System.out.println("------------------");
            disconnect();
           
       }
       
       public void disconnect(){
            try {
                mgr.disconnect();
            } catch (VBoxException e) {
               e.printStackTrace();
             safeprinterr.safeprintErr(e.getMessage());
             safePrintln.safeprintln("Cannot disconnect, start webserver first!");
            }
            mgr.cleanup();
       }

    }
i update testcpuperformance class to get the metric one time

Code: Select all

    public class testcpuperformance {
       
       public static void main(String[] args) throws InterruptedException{
          
          String VmName="VmLab11";

          VmIPerformanceCollector vmper=new VmIPerformanceCollector(VmName);
          vmper.ConnecttoVirtualbox();
          vmper.setup(new Long(1), new Long(3));
          vmper.disconnect();

             Thread.sleep(2000);
             vmper.ConnecttoVirtualbox();
             
             vmper.CollectCpuUtilization(3);

       }
    }
the output results from the running is

Code: Select all

Metric Name: CPU/Load/User:avg
Scale: 1000
unit: %
value: 66
Metric Name: CPU/Load/Kernel:avg
Scale: 1000
unit: %
value: 125
------------------
here the virtual machine has one virtual cpu
please correct me if i am wrong, the CPU/Load/User:avg is 6.6 % of virtual CPU and CPU/Load/Kernel:avg is 12.5% of virtual CPU, therefore the total the average CPU usage in the monitoring period is 12.5+6.6= 19.1 % of the virtual CPU
is explanation for these values correct?
thanks
Last edited by Ghetas on 13. Jan 2016, 03:45, edited 1 time in total.
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: why it returns worng performance metrics

Post by noteirak »

Ghetas wrote:here the virtual machine has one virtual cpu
please correct me if i am wrong, the CPU/Load/User:avg is 6.6 % and CPU/Load/Kernel:avg is 12.5%
I think the values are actually 0.066% and 0.125%
Scale is 1000, max value is 100000, so 100000 would be 100% while the scale would give you where to put the decimal delimiter

If you want from the guest, you need Guest/CPU/Load/<type>
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: why it returns worng performance metrics

Post by noteirak »

I've edited my previous reply, make sure to double check it
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
Ghetas
Posts: 19
Joined: 19. Dec 2015, 17:35

Re: why it returns worng performance metrics

Post by Ghetas »

noteirak wrote:
Ghetas wrote:here the virtual machine has one virtual cpu
please correct me if i am wrong, the CPU/Load/User:avg is 6.6 % and CPU/Load/Kernel:avg is 12.5%
I think the values are actually 0.066% and 0.125%
Scale is 1000, max value is 100000, so 100000 would be 100% while the scale would give you where to put the decimal delimiter

If you want from the guest, you need Guest/CPU/Load/<type>
i want to get the virtual CPU usage of Virtual machine now i update the metric as follows

Code: Select all

oCollector.setupMetrics(Arrays.asList(new String[]{"Guest/CPU/Load/User:avg"}),
and

Code: Select all

        List<Integer> values = oCollector.queryMetricsData(Arrays.asList(new String[]{"Guest/CPU/Load/User:avg"}),
                Arrays.asList(new IUnknown[]{machine}),
                names, objects, units, scales,
                sequenceNumbers, indices, lengths);
and i use the following to get the metrics as before

Code: Select all

        for (int i=0; i < names.value.size(); i++){
        		
        		System.out.println("Metric Name: "+names.value.get(i));
        		System.out.println("Scale: "+scales.value.get(i));
        		System.out.println("unit: "+units.value.get(i));
        		scale=scales.value.get(i);
                for (int j = 0; j < lengths.value.get(i); j++)
                {
                    long val= values.get(indices.value.get(i).intValue() + j).longValue();
                    Long val2=val;
                    double val3=val2.doubleValue()/scale;
                    System.out.println(val3);
                }
        }

but it does not give me any values

Code: Select all

Metric Name: Guest/CPU/Load/User:avg
Scale: 1000
unit: %
------------------
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: why it returns worng performance metrics

Post by noteirak »

Do you have the guest additions installed in the VM? Last I rememeber, guest metrics don't work if they are not installed.
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
Ghetas
Posts: 19
Joined: 19. Dec 2015, 17:35

Re: why it returns worng performance metrics

Post by Ghetas »

noteirak wrote:Do you have the guest additions installed in the VM? Last I rememeber, guest metrics don't work if they are not installed.
no i don't, i will install and try again
thanks so much noteirak
Ghetas
Posts: 19
Joined: 19. Dec 2015, 17:35

Re: why it returns worng performance metrics

Post by Ghetas »

noteirak wrote:Do you have the guest additions installed in the VM? Last I rememeber, guest metrics don't work if they are not installed.
Thanks noteirak i installed Guest Additions and now it works with me very well

thanks
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: why it returns worng performance metrics

Post by noteirak »

Glad this is solved then :) happy coding!
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
Ghetas
Posts: 19
Joined: 19. Dec 2015, 17:35

Re: why it returns worng performance metrics

Post by Ghetas »

noteirak wrote:Glad this is solved then :) happy coding!
hi noteirak
my code is running well but i noticed one problem
i setup the metric using

Code: Select all

	public void setup(long Period, long Count){
		 oCollector = vbox.getPerformanceCollector();
         oCollector.setupMetrics(Arrays.asList(new String[]{"Guest/CPU/Load/Kernel:avg,Guest/CPU/Load/User:avg,Guest/CPU/Load/Idle:avg"}),
                 new ArrayList<IUnknown>(),
                 Period, Count);
	}
and collect performance using

Code: Select all

        List<Integer> values = oCollector.queryMetricsData(Arrays.asList(new String[]{"Guest/CPU/Load/Kernel:avg,Guest/CPU/Load/User:avg,Guest/CPU/Load/Idle:avg"}),
                Arrays.asList(new IUnknown[]{machine}),
                names, objects, units, scales,
                sequenceNumbers, indices, lengths);
the code is running well and gives me correct values but if i restart my VM and try to run my code again to collect performance values it returns all values zero
but if i change the setup to

Code: Select all

	public void setup(long Period, long Count){
		 oCollector = vbox.getPerformanceCollector();
         oCollector.setupMetrics(Arrays.asList(new String[]{"*"}),
                 new ArrayList<IUnknown>(),
                 Period, Count);
	}
and try to run the code it gives me values that are correct and non zeros

is there any explanation and solution to this ?

appreciate your help
noteirak
Site Moderator
Posts: 5229
Joined: 13. Jan 2012, 11:14
Primary OS: Debian other
VBox Version: OSE Debian
Guest OSses: Debian, Win 2k8, Win 7
Contact:

Re: why it returns worng performance metrics

Post by noteirak »

If by restart you mean poweroff and then poweron, this is normal. Performance metrics collector are bound to the running process of the VM and therefore lost when you restart it.
You'll need to re-add a performance collector when the VM restart. This is explained in the description of IPerformanceCollector.

If you want to do it the right way, you would need to setup an event listener on IVirtualBox object that would add the performance monitor again.
If you go in the Samples topic, you'll find a specific example for events that show the particular event you're looking for. While it's for 4.3.x, just adjust the imports for 5.0.x and it should work out of the box.
Hyperbox - Virtual Infrastructure Manager - https://apps.kamax.lu/hyperbox/
Manage your VirtualBox infrastructure the free way!
Ghetas
Posts: 19
Joined: 19. Dec 2015, 17:35

Re: why it returns worng performance metrics

Post by Ghetas »

noteirak wrote:If by restart you mean poweroff and then poweron, this is normal. Performance metrics collector are bound to the running process of the VM and therefore lost when you restart it.
You'll need to re-add a performance collector when the VM restart. This is explained in the description of IPerformanceCollector.

If you want to do it the right way, you would need to setup an event listener on IVirtualBox object that would add the performance monitor again.
If you go in the Samples topic, you'll find a specific example for events that show the particular event you're looking for. While it's for 4.3.x, just adjust the imports for 5.0.x and it should work out of the box.
let me check and understand how it works :shock: and come back a while :arrow:
Ghetas
Posts: 19
Joined: 19. Dec 2015, 17:35

Re: why it returns worng performance metrics

Post by Ghetas »

Hello noteirak
please this is the problem in details

if i call the oCollector.setupMetrics with the same type of performance metrics that i used before i turn off the vm then the following function

Code: Select all

public void CollectCpuUtilization(long time) throws InterruptedException{
        Holder<List<String>> names = new Holder<List<String>> ();
        Holder<List<IUnknown>> objects = new Holder<List<IUnknown>>() ;
        Holder<List<String>> units = new Holder<List<String>>();
        Holder<List<Long>> scales =  new Holder<List<Long>>();
        Holder<List<Long>> sequenceNumbers =  new Holder<List<Long>>();
        Holder<List<Long>> indices =  new Holder<List<Long>>();
        Holder<List<Long>> lengths =  new Holder<List<Long>>();
        oCollector = vbox.getPerformanceCollector();         

        List<Integer> values = oCollector.queryMetricsData(Arrays.asList(new String[]{"CPU/*:avg"}),
                Arrays.asList(new IUnknown[]{machine}),
                names, objects, units, scales,
                sequenceNumbers, indices, lengths);
        Cpuutilization=0;
        System.out.println();
        for (int i=0; i < names.value.size(); i++){
              scale=scales.value.get(i);
              System.out.println(names.value.get(i));
                for (int j = 0; j < lengths.value.get(i); j++)
                {
                    long val= values.get(indices.value.get(i).intValue() + j).longValue();
                    System.out.println(val);
                    Long val2=val;
                }
        }

        System.out.println("------------------");
        disconnect();
       
   }
it reruns all values zero

but if i change the performance metrics than i used before i turned off the VM it gives me correct values.

to solve this problem i tried to call the setup metrics every time i turned vm on and off but it still not working
i hope i could make it clear
appreciated your help thanks
Post Reply