mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-11-04 00:02:37 +01:00 
			
		
		
		
	* VSP ID Caching * VSP call Statistics * 5.0 Support Co-Authored-By: Frank Maximus <frank.maximus@nuagenetworks.net> Co-Authored-By: Raf Smeets <raf.smeets@nuagenetworks.net>
		
			
				
	
	
		
			203 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			203 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# Licensed to the Apache Software Foundation (ASF) under one
 | 
						|
# or more contributor license agreements.  See the NOTICE file
 | 
						|
# distributed with this work for additional information
 | 
						|
# regarding copyright ownership.  The ASF licenses this file
 | 
						|
# to you under the Apache License, Version 2.0 (the
 | 
						|
# "License"); you may not use this file except in compliance
 | 
						|
# with the License.  You may obtain a copy of the License at
 | 
						|
#
 | 
						|
#   http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
#
 | 
						|
# Unless required by applicable law or agreed to in writing,
 | 
						|
# software distributed under the License is distributed on an
 | 
						|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 | 
						|
# KIND, either express or implied.  See the License for the
 | 
						|
# specific language governing permissions and limitations
 | 
						|
# under the License.
 | 
						|
 | 
						|
import jpype
 | 
						|
from jpype import *
 | 
						|
from jpype import java
 | 
						|
from jpype import javax
 | 
						|
 | 
						|
J_STRING = "java.lang.String"
 | 
						|
 | 
						|
 | 
						|
class VsdDataCollector:
 | 
						|
    def __init__(self, name, host="localhost", port=1099, debug=False,
 | 
						|
                 output_channel=None):
 | 
						|
        self.jmx = ConnectionJmx(host, port, debug, output_channel)
 | 
						|
        self.jmx.create_management_object(name=name)
 | 
						|
        self.saved_stats = None
 | 
						|
        self.saved_vsd_calls = 0
 | 
						|
 | 
						|
    def start_test(self):
 | 
						|
        self.saved_stats = self.jmx.get_attribute("VsdStatisticsReport")
 | 
						|
        self.saved_vsd_calls = self.jmx.get_attribute("VSDStatistics")
 | 
						|
        return
 | 
						|
 | 
						|
    def end_test(self):
 | 
						|
        self.jmx.print_rapport(old_stats=self.saved_stats,
 | 
						|
                               old_vsd_count=self.saved_vsd_calls)
 | 
						|
        return
 | 
						|
 | 
						|
 | 
						|
class ConnectionJmx:
 | 
						|
 | 
						|
    def __init__(self, host="localhost", port=1099, debug=False,
 | 
						|
                 output_channel=None):
 | 
						|
        self.host = host
 | 
						|
        self.port = port
 | 
						|
        self.url = "service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi" % (host, port)
 | 
						|
        self.debug = debug
 | 
						|
        self.mbean = None
 | 
						|
        self.output_channel = output_channel
 | 
						|
        jpype.startJVM(jpype.get_default_jvm_path())
 | 
						|
        if debug:
 | 
						|
            self.__print_to_ouput_channel("JVM loaded")
 | 
						|
            self.__print_to_ouput_channel(jpype.get_default_jvm_path())
 | 
						|
 | 
						|
        jmx_url = javax.management.remote.JMXServiceURL(self.url)
 | 
						|
        jmx_soc = javax.management.remote.JMXConnectorFactory.connect(
 | 
						|
            jmx_url, java.util.HashMap())
 | 
						|
        self.connection = jmx_soc.getMBeanServerConnection()
 | 
						|
        if self.debug:
 | 
						|
            self.__print_to_ouput_channel("Connection successful")
 | 
						|
 | 
						|
    def __print_to_ouput_channel(self, text):
 | 
						|
        if self.output_channel:
 | 
						|
            self.output_channel.debug(text)
 | 
						|
        else:
 | 
						|
            print text
 | 
						|
 | 
						|
    def create_management_object(self, domain="com.cloud",
 | 
						|
                                 type="NuageVspResource",
 | 
						|
                                 name="Nuage VSD - 0.0.0.0"):
 | 
						|
        if name is not None:
 | 
						|
            object_name = domain + ":type=" + type + ", name=" + name
 | 
						|
        else:
 | 
						|
            object_name = domain + ":" + type
 | 
						|
 | 
						|
        if self.debug:
 | 
						|
            self.__print_to_ouput_channel(object_name)
 | 
						|
 | 
						|
        self.mbean = javax.management.ObjectName(object_name)
 | 
						|
        return self.mbean
 | 
						|
 | 
						|
    def get_vsd_statistics_by_request_and_entity_type(self,
 | 
						|
                                                      entity_type,
 | 
						|
                                                      request_type,
 | 
						|
                                                      mbean=None):
 | 
						|
        self._get_stats_by_entity_or_request_type(
 | 
						|
            mbean, [[entity_type, request_type]],
 | 
						|
            "getVsdStatisticsByEntityType")
 | 
						|
 | 
						|
    def _jStringArray(self, elements):
 | 
						|
        return jpype.JArray(java.lang.String)(elements)
 | 
						|
 | 
						|
    def get_vsd_statistics_by_request_type(self, request_type, mbean=None):
 | 
						|
        return self._get_stats_by_entity_or_request_type(
 | 
						|
            mbean, [request_type], "getVsdStatisticsByRequestType")
 | 
						|
 | 
						|
    def get_vsd_statistics_by_entity_type(self, entity_type, mbean=None):
 | 
						|
        return self._get_stats_by_entity_or_request_type(
 | 
						|
            mbean, [entity_type], "getVsdStatisticsByEntityType")
 | 
						|
 | 
						|
    def _get_stats_by_entity_or_request_type(self, vars, method, mbean=None):
 | 
						|
        if not mbean:
 | 
						|
            mbean = self.mbean
 | 
						|
        jarray = self._jStringArray(vars)
 | 
						|
        signature = self._jStringArray([J_STRING for _ in vars])
 | 
						|
        result = self.connection.invoke(mbean, method, jarray, signature)
 | 
						|
        if self.debug:
 | 
						|
            self.__print_to_ouput_channel(vars + ": " + str(result))
 | 
						|
        return result
 | 
						|
 | 
						|
    def get_attribute(self, attribute, mbean=None):
 | 
						|
        if not mbean:
 | 
						|
            mbean = self.mbean
 | 
						|
 | 
						|
        result = self.connection.getAttribute(mbean, attribute)
 | 
						|
        if self.debug:
 | 
						|
            self.__print_to_ouput_channel("Attribute " + attribute + ": " +
 | 
						|
                                          str(result))
 | 
						|
        return result
 | 
						|
 | 
						|
    def print_rapport(self, mbean=None, old_stats=None, old_vsd_count=0):
 | 
						|
        if not mbean:
 | 
						|
            mbean = self.mbean
 | 
						|
        stat = self.get_attribute("VsdStatisticsReport", mbean)
 | 
						|
        number_of_vsd_calls = int(str(self.get_attribute("VSDStatistics",
 | 
						|
                                                         mbean)))
 | 
						|
        number_of_vsd_calls = number_of_vsd_calls - int(str(old_vsd_count))
 | 
						|
 | 
						|
        self.__print_to_ouput_channel("\n================"
 | 
						|
                                      "RAPPORT:"
 | 
						|
                                      "================\n")
 | 
						|
        self.__print_to_ouput_channel("Total VSD calls: " +
 | 
						|
                                      str(number_of_vsd_calls))
 | 
						|
        self.__print_to_ouput_channel("For each Entity:\n")
 | 
						|
        self.__print_total_for_entity(stat, old_stats)
 | 
						|
        self.__print_to_ouput_channel("\nFor each Request:\n")
 | 
						|
        self.__print_total_per_request(stat, old_stats)
 | 
						|
        self.__print_to_ouput_channel("\nCombined:\n")
 | 
						|
        self.__print_total_per_entity_and_request(stat, old_stats)
 | 
						|
        self.__print_to_ouput_channel("\n============="
 | 
						|
                                      "END OF RAPPORT"
 | 
						|
                                      "=============")
 | 
						|
 | 
						|
    def __print_total_per_request(self, stat, old_stat=None):
 | 
						|
        data = dict()
 | 
						|
 | 
						|
        entries = ((entry.getKey(), entry.getValue().get())
 | 
						|
                   for requestmap in stat.values()
 | 
						|
                   for entry in requestmap.entrySet())
 | 
						|
 | 
						|
        for request, value in entries:
 | 
						|
            if request in data:
 | 
						|
                data[request] += value
 | 
						|
            else:
 | 
						|
                data[request] = value
 | 
						|
 | 
						|
        if old_stat:
 | 
						|
            old_entries = ((entry.getKey(), entry.getValue().get())
 | 
						|
                           for requestmap in old_stat.values()
 | 
						|
                           for entry in requestmap.entrySet())
 | 
						|
 | 
						|
            for request, value in old_entries:
 | 
						|
                if request in data:
 | 
						|
                    data[request] -= value
 | 
						|
                else:
 | 
						|
                    data[request] = 0
 | 
						|
 | 
						|
        for key, value in data.iteritems():
 | 
						|
            self.__print_to_ouput_channel(" " + str(key) + ": " + str(value))
 | 
						|
 | 
						|
    def __print_total_per_entity_and_request(self, stat, old_stat=None):
 | 
						|
        for entity in stat:
 | 
						|
            self.__print_to_ouput_channel(entity + ":")
 | 
						|
            for request in stat[entity]:
 | 
						|
                previous = 0
 | 
						|
                if old_stat and old_stat[entity] and old_stat[entity][request]:
 | 
						|
                    previous = int(str(old_stat[entity][request]))
 | 
						|
 | 
						|
                current = int(str(stat[entity][request]))
 | 
						|
 | 
						|
                self.__print_to_ouput_channel(" " + str(request) + ":" +
 | 
						|
                                              str(current - previous))
 | 
						|
            self.__print_to_ouput_channel("--------------------"
 | 
						|
                                          "--------------------")
 | 
						|
 | 
						|
    def __print_total_for_entity(self, stat, old_stat=None):
 | 
						|
        for entity in stat:
 | 
						|
            total = 0
 | 
						|
            for val in stat[entity]:
 | 
						|
                minus = 0
 | 
						|
                if old_stat and old_stat[entity] and old_stat[entity][val]:
 | 
						|
                    minus = int(str(old_stat[entity][val]))
 | 
						|
                total = str(stat[entity][val])
 | 
						|
 | 
						|
                total = int(total) - minus
 | 
						|
            self.__print_to_ouput_channel(" " + str(entity) +
 | 
						|
                                          ": " + str(total))
 |