Merge "makefile: update collectd Makefile with intel_pmu configuration"
authorMaryam Tahhan <maryam.tahhan@intel.com>
Fri, 19 May 2017 12:10:13 +0000 (12:10 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Fri, 19 May 2017 12:10:13 +0000 (12:10 +0000)
12 files changed:
3rd_party/collectd-ves-plugin/ves_plugin/ves_plugin.py
ci/build_rpm.sh [changed mode: 0644->0755]
ci/install_dependencies.sh [changed mode: 0644->0755]
ci/utility/check_git_repo.sh [changed mode: 0644->0755]
ci/utility/collectd_build_rpm.sh [changed mode: 0644->0755]
ci/utility/collectd_get_sources.sh [changed mode: 0644->0755]
ci/utility/intel_cmt_cat_build_install_rpm.sh [changed mode: 0644->0755]
ci/utility/package-list.sh [changed mode: 0644->0755]
docs/release/userguide/collectd.ves.userguide.rst
docs/release/userguide/feature.userguide.rst
systems/build_base_machine.sh
systems/ubuntu/16.04/build_base_machine.sh [new file with mode: 0755]

index 3e30089..1ab8f67 100644 (file)
@@ -24,7 +24,12 @@ import collectd
 import json
 import sys
 import base64
-import urllib2
+try:
+    # For Python 3.0 and later
+    import urllib.request as url
+except ImportError:
+    # Fall back to Python 2's urllib2
+    import urllib2 as url
 import socket
 import time
 from threading import Timer
@@ -70,7 +75,7 @@ class Event(object):
                 'commonEventHeader' : obj,
                 self.get_name() : self.get_obj()
             }
-        })
+        }).encode()
 
     def get_name():
         assert False, 'abstract method get_name() is not implemented'
@@ -114,7 +119,12 @@ class MeasurementsForVfScaling(Event):
         self.concurrent_sessions = 0
         self.configured_entities = 0
         self.cpu_usage_array = []
-        self.errors = []
+        self.errors = {
+            "receiveDiscards" : 0,
+            "receiveErrors" : 0,
+            "transmitDiscards" : 0,
+            "transmitErrors" : 0
+        }
         self.feature_usage_array = []
         self.filesystem_usage_array = []
         self.latency_distribution = []
@@ -240,11 +250,11 @@ class VESPlugin(object):
             'UseHttps' : False,
             'SendEventInterval' : 20.0,
             'FunctionalRole' : 'Collectd VES Agent',
-            'GuestRunning' : False
+            'GuestRunning' : False,
+            'ApiVersion' : 1.0
         }
         self.__host_name = None
         self.__ves_timer = None
-        self.__event_timer_interval = 20.0
         self.__lock = Lock()
         self.__event_id = 0
 
@@ -263,7 +273,7 @@ class VESPlugin(object):
 
     def start_timer(self):
         """Start event timer"""
-        self.__ves_timer = Timer(self.__event_timer_interval, self.__on_time)
+        self.__ves_timer = Timer(self.__plugin_config['SendEventInterval'], self.__on_time)
         self.__ves_timer.start()
 
     def stop_timer(self):
@@ -272,30 +282,34 @@ class VESPlugin(object):
 
     def __on_time(self):
         """Timer thread"""
-        self.start_timer()
         self.event_timer()
+        self.start_timer()
 
     def event_send(self, event):
         """Send event to VES"""
-        server_url = "http{}://{}:{}/{}eventListener/v3{}".format(
+        server_url = "http{}://{}:{}{}/eventListener/v{}{}".format(
             's' if self.__plugin_config['UseHttps'] else '', self.__plugin_config['Domain'],
-            int(self.__plugin_config['Port']), '{}/'.format(
-            '/{}'.format(self.__plugin_config['Path'])) if (len(self.__plugin_config['Path']) > 0) else '',
-            self.__plugin_config['Topic'])
+            int(self.__plugin_config['Port']), '{}'.format(
+            '/{}'.format(self.__plugin_config['Path']) if (len(self.__plugin_config['Path']) > 0) else ''),
+            int(self.__plugin_config['ApiVersion']), '{}'.format(
+            '/{}'.format(self.__plugin_config['Topic']) if (len(self.__plugin_config['Topic']) > 0) else ''))
         collectd.info('Vendor Event Listener is at: {}'.format(server_url))
         credentials = base64.b64encode('{}:{}'.format(
-            self.__plugin_config['Username'], self.__plugin_config['Password']))
+            self.__plugin_config['Username'], self.__plugin_config['Password']).encode()).decode()
         collectd.info('Authentication credentials are: {}'.format(credentials))
         try:
-            request = urllib2.Request(server_url)
+            request = url.Request(server_url)
             request.add_header('Authorization', 'Basic {}'.format(credentials))
             request.add_header('Content-Type', 'application/json')
             collectd.debug("Sending {} to {}".format(event.get_json(), server_url))
-            vel = urllib2.urlopen(request, event.get_json(), timeout=1)
-        except urllib2.HTTPError as e:
+            vel = url.urlopen(request, event.get_json(), timeout=1)
+            collectd.debug("Sent data to {} successfully".format(server_url))
+        except url.HTTPError as e:
             collectd.error('Vendor Event Listener exception: {}'.format(e))
-        except urllib2.URLError as e:
+        except url.URLError as e:
             collectd.error('Vendor Event Listener is is not reachable: {}'.format(e))
+        except:
+            collectd.error('Vendor Event Listener unknown error')
 
     def bytes_to_gb(self, bytes):
         """Convert bytes to GB"""
@@ -388,23 +402,24 @@ class VESPlugin(object):
                 reporting_entity = '{}-{}-{}'.format(self.get_hostname(), 'virt', vm_name)
                 measurement.reporting_entity_id = reporting_entity
                 measurement.reporting_entity_name = reporting_entity
+                # virt_vcpu
+                virt_vcpus = self.cache_get_value(plugin_instance=vm_name,
+                                                  plugin_name='virt', type_name='virt_vcpu')
+                if len(virt_vcpus) > 0:
+                    for virt_vcpu in virt_vcpus:
+                        cpu_usage = self.cpu_ns_to_percentage(virt_vcpu)
+                        measurement.add_cpu_usage(virt_vcpu['type_instance'], cpu_usage)
                 # virt_cpu_total
                 virt_vcpu_total = self.cache_get_value(plugin_instance=vm_name,
                                                        plugin_name='virt', type_name='virt_cpu_total')
                 if len(virt_vcpu_total) > 0:
-                    measurement.aggregate_cpu_usage = self.cpu_ns_to_percentage(virt_vcpu_total[0])
+                    average_cpu_usage = self.cpu_ns_to_percentage(virt_vcpu_total[0]) / len(virt_vcpus)
+                    measurement.aggregate_cpu_usage = average_cpu_usage
                     # set source as a host for virt_vcpu_total value
                     measurement.source_id = virt_vcpu_total[0]['host']
                     measurement.source_name = measurement.source_id
                     # fill out EpochMicrosec (convert to us)
                     measurement.start_epoch_microsec = (virt_vcpu_total[0]['time'] * 1000000)
-                # virt_vcp
-                virt_vcpus = self.cache_get_value(plugin_instance=vm_name,
-                                                  plugin_name='virt', type_name='virt_vcpu')
-                if len(virt_vcpus) > 0:
-                    for virt_vcpu in virt_vcpus:
-                        cpu_usage = self.cpu_ns_to_percentage(virt_vcpu)
-                        measurement.add_cpu_usage(virt_vcpu['type_instance'], cpu_usage)
                 # plugin interval
                 measurement.measurement_interval = self.__plugin_data_cache['virt']['interval']
                 # memory-total
@@ -456,7 +471,7 @@ class VESPlugin(object):
                         '-{}'.format(val['type_instance']) if len(val['type_instance']) else '')
                     mgroup = MeasurementGroup(mgroup_name)
                     ds = collectd.get_dataset(val['type'])
-                    for index in xrange(len(ds)):
+                    for index in range(len(ds)):
                         mname = '{}-{}'.format(val['type'], ds[index][0])
                         mgroup.add_measurement(mname, str(val['values'][index]))
                     measurement.add_measurement_group(mgroup);
@@ -476,6 +491,10 @@ class VESPlugin(object):
             pre_total_time, pre_total, total_time, total, round(percent, 2)))
         return round(percent, 2)
 
+    def make_dash_string(self, *args):
+        """Join non empty strings with dash symbol"""
+        return '-'.join(filter(lambda x: len(x) > 0, args))
+
     def config(self, config):
         """Collectd config callback"""
         for child in config.children:
@@ -485,8 +504,9 @@ class VESPlugin(object):
                 raise RuntimeError('Configuration key name error')
             # check the config entry value type
             if len(child.values) == 0 or type(child.values[0]) != type(self.__plugin_config[child.key]):
-                collectd.error("Key '{}' value type should be {}".format(
-                               child.key, str(type(self.__plugin_config[child.key]))))
+                collectd.error("Key '{}' value type '{}' should be {}".format(
+                               child.key, str(type(child.values[0])),
+                               str(type(self.__plugin_config[child.key]))))
                 raise RuntimeError('Configuration key value error')
             # store the value in configuration
             self.__plugin_config[child.key] = child.values[0]
@@ -505,7 +525,7 @@ class VESPlugin(object):
         if vl.plugin not in self.__plugin_data_cache:
              self.__plugin_data_cache[vl.plugin] = {'vls': []}
         plugin_vl = self.__plugin_data_cache[vl.plugin]['vls']
-        for index in xrange(len(plugin_vl)):
+        for index in range(len(plugin_vl)):
             # record found, so just update time the values
             if (plugin_vl[index]['plugin_instance'] ==
                 vl.plugin_instance) and (plugin_vl[index]['type_instance'] ==
@@ -593,10 +613,8 @@ class VESPlugin(object):
         fault.last_epoch_micro_sec = fault.start_epoch_microsec
         # fill out fault header
         fault.event_severity = collectd_event_severity_map[n.severity]
-        fault.specific_problem = '{}{}'.format('{}-'.format(n.plugin_instance
-            if len(n.plugin_instance) else ''), n.type_instance)
-        fault.alarm_interface_a = '{}{}'.format(n.plugin, '-{}'.format(
-            n.plugin_instance if len(n.plugin_instance) else ''))
+        fault.specific_problem = self.make_dash_string(n.plugin_instance, n.type_instance)
+        fault.alarm_interface_a = self.make_dash_string(n.plugin, n.plugin_instance)
         fault.event_source_type = 'virtualMachine(8)' if self.__plugin_config['GuestRunning'] else 'host(3)'
         fault.alarm_condition = n.message
         self.event_send(fault)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index d0e8954..e91e977
@@ -46,5 +46,5 @@ then
        echo "*** intel-cmt-cat is already installed"
 else
        RPM_NAME=`ls -1 $RPM_DIR | grep -E "cmt-cat-[0-9]"`
-       rpm -ivf $RPM_DIR/$RPM_NAME
+       sudo rpm -ivf $RPM_DIR/$RPM_NAME
 fi
old mode 100644 (file)
new mode 100755 (executable)
index 3cf2600..7ed6be9 100644 (file)
@@ -61,36 +61,42 @@ REST resources are of the form:
     {ServerRoot}/eventListener/v{apiVersion}/{topicName}`
     {ServerRoot}/eventListener/v{apiVersion}/eventBatch`
 
-
 **Domain** *"host"*
-* VES domain name. It can be IP address or hostname of VES collector
-(default: `127.0.0.1`)
+  VES domain name. It can be IP address or hostname of VES collector
+  (default: `127.0.0.1`)
 
 **Port** *port*
-* VES port (default: `30000`)
+  VES port (default: `30000`)
 
 **Path** *"path"*
-* Used as the "optionalRoutingPath" element in the REST path (default: `empty`)
+  Used as the "optionalRoutingPath" element in the REST path (default: `empty`)
 
 **Topic** *"path"*
-* Used as the "topicName" element in the REST  path (default: `empty`)
+  Used as the "topicName" element in the REST  path (default: `empty`)
 
 **UseHttps** *true|false*
-* Allow plugin to use HTTPS instead of HTTP (default: `false`)
+  Allow plugin to use HTTPS instead of HTTP (default: `false`)
 
 **Username** *"username"*
-* VES collector user name (default: `empty`)
+  VES collector user name (default: `empty`)
 
 **Password** *"passwd"*
-* VES collector password (default: `empty`)
+  VES collector password (default: `empty`)
 
 **FunctionalRole** *"role"*
-* Used as the 'functionalRole' field of 'commonEventHeader' event (default:
-`Collectd VES Agent`)
+  Used as the 'functionalRole' field of 'commonEventHeader' event (default:
+  `Collectd VES Agent`)
 
 **GuestRunning** *true|false*
-* This option is used if the collectd is running on a guest machine, e.g this
-option should be set to `true` in this case. Defaults to `false`.
+  This option is used if the collectd is running on a guest machine, e.g this
+  option should be set to `true` in this case. Defaults to `false`.
+
+**SendEventInterval** *interval*
+  This configuration option controls how often (sec) collectd data is sent to
+  Vendor Event Listener (default: `20`)
+
+**ApiVersion** *version*
+  Used as the "apiVersion" element in the REST path (default: `1`)
 
 Other collectd.conf configurations
 ----------------------------------
@@ -100,7 +106,6 @@ Please ensure that FQDNLookup is set to false
 
     FQDNLookup   false
 
-
 Please ensure that the virt plugin is enabled and configured as follows. This configuration
 is is required only on a host side ('GuestRunning' = false).
 
@@ -125,7 +130,11 @@ Please ensure that the cpu plugin is enabled and configured as follows
         ValuesPercentage true
     </Plugin>
 
+**Note**: The `ReportByCpu` option should be set to `true` (default) if VES pugin
+is running on guest machine ('GuestRunning' = true).
+
 Please ensure that the aggregation plugin is enabled and configured as follows
+(required if 'GuestRunning' = true)
 
 .. code:: bash
 
@@ -146,7 +155,9 @@ If plugin is running on a guest side, it is important to enable uuid plugin
 too. In this case the hostname in event message will be represented as UUID
 instead of system host name.
 
-LoadPlugin uuid
+.. code:: bash
+
+  LoadPlugin uuid
 
 If custom UUID needs to be provided, the following configuration is required in collectd.conf
 file:
index c1463e7..3bda303 100644 (file)
@@ -106,17 +106,11 @@ To build and install these dependencies, clone the barometer repo:
 
     $ git clone https://gerrit.opnfv.org/gerrit/barometer
 
-Install the build dependencies
-
-.. code:: bash
-
-    $ ./src/install_build_deps.sh
-
 To install collectd as a service and install all it's dependencies:
 
 .. code:: bash
 
-    $ cd barometer/src && sudo make && sudo make install
+    $ cd barometer && ./systems/build_base_machine.sh
 
 This will install collectd as a service and the base install directory
 will be /opt/collectd.
index f6f72b7..7b877f5 100755 (executable)
@@ -46,14 +46,14 @@ then
     SUDO="sudo -E"
 fi
 
-# If there is version specific dir available then set distro_dir to that
-if [ -d "$OS_NAME/$VERSION_ID" ]; then
-    distro_dir="$OS_NAME/$VERSION_ID"
-else
-    # Fallback - Default distro_dir = OS name
-    distro_dir="$OS_NAME"
+if [ "$1" != "-f" ] && [ -d "/opt/collectd" ] || [ -d "/etc/collectd" ]
+then
+    die "collectd is already installed on this system, if you wish to reinstall please rerun the script with a -f argument"
 fi
 
+# If there is version specific dir available then set distro_dir to that
+distro_dir="$OS_NAME/$VERSION_ID"
+
 # build base system using OS specific scripts
 if [ -d "$distro_dir" ] && [ -e "$distro_dir/build_base_machine.sh" ]; then
     $SUDO $distro_dir/build_base_machine.sh || die "$distro_dir/build_base_machine.sh failed"
diff --git a/systems/ubuntu/16.04/build_base_machine.sh b/systems/ubuntu/16.04/build_base_machine.sh
new file mode 100755 (executable)
index 0000000..440b3e7
--- /dev/null
@@ -0,0 +1,59 @@
+#!/bin/bash
+#
+# Build a base machine for Ubuntu 16.04
+#
+# Copyright 2015-2017 OPNFV, Intel Corporation.
+#
+# Licensed 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.
+#
+# Contributors:
+#   Aihua Li, Huawei Technologies.
+#   Martin Klozik, Intel Corporation.
+#   Abdul Halim, Intel Corporation.
+
+apt-get update
+apt-get -y install $(echo "
+# Make and Compilers
+make
+automake
+gcc
+g++
+libc6
+libc6-dev
+
+# Linux Kernel Source
+linux-source
+linux-headers-$(uname -r)
+pkg-config
+
+# tools
+curl
+libcurl4-openssl-dev
+automake
+autoconf
+libtool
+libpcap-dev
+libnet1
+libncurses5-dev
+vim
+wget
+git
+pciutils
+cifs-utils
+socat
+libpixman-1-0
+libpixman-1-dev
+
+# install git-review tool
+git-review
+" | grep -v ^#)