collectd: set intel_pmu events path and OVS socket path 71/45071/1
authorRoss Brattain <ross.b.brattain@intel.com>
Tue, 10 Oct 2017 22:03:22 +0000 (15:03 -0700)
committerRoss Brattain <ross.b.brattain@intel.com>
Fri, 13 Oct 2017 20:59:38 +0000 (13:59 -0700)
switch from hardcoded path to dynamic path
based on bin_path

also enable proxy for install_collectd

add barometer settings for virt and ovs_stats

Change-Id: Id138aef548332a3e3fcb3963b746e7c9f10c0948
Signed-off-by: Ross Brattain <ross.b.brattain@intel.com>
ansible/install_collectd.yml
ansible/roles/download_pmu_tools/files/event_download_local.py
ansible/roles/download_pmu_tools/tasks/main.yml
etc/yardstick/nodes/pod.yaml.collectd.sample
tests/unit/network_services/nfvi/test_resource.py
yardstick/network_services/nfvi/collectd.conf
yardstick/network_services/nfvi/resource.py

index 7b82915..637c42d 100644 (file)
@@ -15,6 +15,7 @@
 - hosts: all
   vars:
     clone_dir: /tmp/yardstick-clone
+  environment: "{{ proxy_env|default({}) }}"
 
   roles:
     # needed for collectd plugins
index 882fc50..8eda2cd 100755 (executable)
 # event_download.py         download for current cpu
 # event_download.py -a      download all
 # event_download.py cpustr...  Download for specific CPU
+from __future__ import absolute_import
+from __future__ import print_function
 import sys
+
 import re
-from urllib2 import urlopen, URLError
 import os
 import string
 from fnmatch import fnmatch
 from shutil import copyfile
 
+try:
+    from urllib2 import URLError
+except ImportError:
+    # python 3
+    from urllib.error import URLError
+
+
 urlpath = 'https://download.01.org/perfmon'
-localpath = 'download.01.org/perfmon'
+localpath = 'pmu_local_mirror/download.01.org/perfmon'
 mapfile = 'mapfile.csv'
 modelpath = localpath + "/" + mapfile
-NSB_JSON = '/opt/nsb_bin/pmu_event.json'
+NSB_JSON = os.environ.get("PMU_EVENTS_PATH", "/tmp/pmu_event.json")
+
 
 def get_cpustr():
-    f = open('/proc/cpuinfo', 'r')
-    cpu = [None, None, None]
-    for j in f:
-        n = j.split()
-        if n[0] == 'vendor_id':
-            cpu[0] = n[2]
-        elif n[0] == 'model' and n[1] == ':':
-            cpu[2] = int(n[2])
-        elif n[0] == 'cpu' and n[1] == 'family':
-            cpu[1] = int(n[3])
-        if all(cpu):
-            break
+    with open('/proc/cpuinfo', 'r') as f:
+        cpu = [None, None, None]
+        for j in f:
+            n = j.split()
+            if n[0] == 'vendor_id':
+                cpu[0] = n[2]
+            elif n[0] == 'model' and n[1] == ':':
+                cpu[2] = int(n[2])
+            elif n[0] == 'cpu' and n[1] == 'family':
+                cpu[1] = int(n[3])
+            if all(cpu):
+                break
     return "%s-%d-%X" % (cpu[0], cpu[1], cpu[2])
 
+
 def sanitize(s, a):
     o = ""
     for j in s:
@@ -52,13 +63,14 @@ def sanitize(s, a):
             o += j
     return o
 
+
 def getdir():
     try:
         d = os.getenv("XDG_CACHE_HOME")
         xd = d
         if not d:
             home = os.getenv("HOME")
-            d = "%s/.cache" % (home)
+            d = "%s/.cache" % home
         d += "/pmu-events"
         if not os.path.isdir(d):
             # try to handle the sudo case
@@ -73,11 +85,13 @@ def getdir():
     except OSError:
         raise Exception('Cannot access ' + d)
 
+
 NUM_TRIES = 3
 
+
 def getfile(url, dir, fn):
     tries = 0
-    print "Downloading", url, "to", fn
+    print("Downloading", url, "to", fn)
     while True:
         try:
             f = open(url)
@@ -86,15 +100,17 @@ def getfile(url, dir, fn):
             tries += 1
             if tries >= NUM_TRIES:
                 raise
-            print "retrying download"
+            print("retrying download")
             continue
         break
-    o = open(os.path.join(dir, fn), "w")
-    o.write(data)
-    o.close()
+    with open(os.path.join(dir, fn), "w") as o:
+        o.write(data)
     f.close()
 
+
 allowed_chars = string.ascii_letters + '_-.' + string.digits
+
+
 def download(match, key=None, link=True):
     found = 0
     dir = getdir()
@@ -105,14 +121,14 @@ def download(match, key=None, link=True):
             n = j.rstrip().split(",")
             if len(n) < 4:
                 if len(n) > 0:
-                    print "Cannot parse", n
+                    print("Cannot parse", n)
                 continue
             cpu, version, name, type = n
             if not fnmatch(cpu, match) or (key is not None and type not in key) or type.startswith("EventType"):
                 continue
             cpu = sanitize(cpu, allowed_chars)
             url = localpath + name
-           fn = "%s-%s.json" % (cpu, sanitize(type, allowed_chars))
+            fn = "%s-%s.json" % (cpu, sanitize(type, allowed_chars))
             try:
                 os.remove(os.path.join(dir, fn))
             except OSError:
@@ -128,34 +144,37 @@ def download(match, key=None, link=True):
                 try:
                     os.symlink(fn, os.path.join(dir, lname))
                 except OSError as e:
-                    print >>sys.stderr, "Cannot link %s to %s:" % (name, lname), e
+                    print("Cannot link %s to %s:" % (name, lname), e, file=sys.stderr)
             found += 1
         models.close()
         getfile(localpath + "/readme.txt", dir, "readme.txt")
     except URLError as e:
-        print >>sys.stderr, "Cannot access event server:", e
-        print >>sys.stderr, "If you need a proxy to access the internet please set it with:"
-        print >>sys.stderr, "\texport https_proxy=http://proxyname..."
-        print >>sys.stderr, "If you are not connected to the internet please run this on a connected system:"
-        print >>sys.stderr, "\tevent_download.py '%s'" % (match)
-        print >>sys.stderr, "and then copy ~/.cache/pmu-events to the system under test"
-        print >>sys.stderr, "To get events for all possible CPUs use:"
-        print >>sys.stderr, "\tevent_download.py -a"
+        print("Cannot access event server:", e, file=sys.stderr)
+        print("If you need a proxy to access the internet please set it with:", file=sys.stderr)
+        print("\texport https_proxy=http://proxyname...", file=sys.stderr)
+        print("If you are not connected to the internet please run this on a connected system:", file=sys.stderr)
+        print("\tevent_download.py '%s'" % match, file=sys.stderr)
+        print("and then copy ~/.cache/pmu-events to the system under test", file=sys.stderr)
+        print("To get events for all possible CPUs use:", file=sys.stderr)
+        print("\tevent_download.py -a", file=sys.stderr)
     except OSError as e:
-        print >>sys.stderr, "Cannot write events file:", e
+        print("Cannot write events file:", e, file=sys.stderr)
     return found
 
+
 def download_current(link=False):
     """Download JSON event list for current cpu.
        Returns >0 when a event list is found"""
     return download(get_cpustr(), link=link)
 
+
 def eventlist_name(name=None, key="core"):
     if not name:
         name = get_cpustr()
     cache = getdir()
     return "%s/%s-%s.json" % (cache, name, key)
 
+
 if __name__ == '__main__':
     # only import argparse when actually called from command line
     # this makes ocperf work on older python versions without it.
@@ -164,18 +183,19 @@ if __name__ == '__main__':
     p.add_argument('--all', '-a', help='Download all available event files', action='store_true')
     p.add_argument('--verbose', '-v', help='Be verbose', action='store_true')
     p.add_argument('--mine', help='Print name of current CPU', action='store_true')
-    p.add_argument('--link', help='Create links with the original event file name', action='store_true', default=True)
+    p.add_argument('--link', help='Create links with the original event file name',
+                   action='store_true', default=True)
     p.add_argument('cpus', help='CPU identifiers to download', nargs='*')
     args = p.parse_args()
 
     cpustr = get_cpustr()
     if args.verbose or args.mine:
-        print "My CPU", cpustr
+        print("My CPU", cpustr)
     if args.mine:
         sys.exit(0)
     d = getdir()
     if args.all:
-       found = download('*', link=args.link)
+        found = download('*', link=args.link)
     elif len(args.cpus) == 0:
         found = download_current(link=args.link)
     else:
@@ -184,10 +204,10 @@ if __name__ == '__main__':
             found += download(j, link=args.link)
 
     if found == 0:
-        print >>sys.stderr, "Nothing found"
+        print("Nothing found", file=sys.stderr)
 
     el = eventlist_name()
     if os.path.exists(el):
-        print "my event list", el 
-        copyfile(el,NSB_JSON)
-        print "File copied to ", NSB_JSON
+        print("my event list", el)
+        copyfile(el, NSB_JSON)
+        print("File copied to ", NSB_JSON)
index e78cc72..3ef4122 100644 (file)
     pmu_tools_path: "{{ pmu_tools_dest }}"
 
 - name: Create perfmon local mirror
-  command: "wget -mkEpnp {{ perfmon_url }} -P {{ pmu_tools_dest }}"
+  command: "wget -mkEpnp {{ perfmon_url }} -P {{ INSTALL_BIN_PATH }}/pmu_local_mirror"
   ignore_errors: yes
 
 - name: Copy local event download file
   copy:
     src: event_download_local.py
-    dest: "{{ pmu_tools_dest }}"
+    dest: "{{ INSTALL_BIN_PATH }}/event_download_local.py"
     owner: root
     group: root
     mode: 0755
index 6ebf9e2..aae677c 100644 (file)
@@ -21,5 +21,9 @@ nodes:
     password: r00t
     collectd:
         interval: 5
-        plugins:
-            ovs_stats: {}
+#        plugins:
+#            intel_rdt: {}
+#            virt: {}
+#            ovs_stats:
+#                ovs_socket_path: /var/run/openvswitch/db.sock
+#            intel_pmu: {}
index 799cc20..f3244fd 100644 (file)
@@ -134,6 +134,14 @@ class TestResourceProfile(unittest.TestCase):
             self.assertIsNone(
                 self.resource_profile._prepare_collectd_conf("/opt/nsb_bin"))
 
+    def test__setup_intel_pmu(self):
+        self.assertIsNone(
+            self.resource_profile._setup_intel_pmu(self.ssh_mock, "/opt/nsb_bin"))
+
+    def test__setup_ovs_stats(self):
+        self.assertIsNone(
+            self.resource_profile._setup_ovs_stats(self.ssh_mock))
+
     @mock.patch("yardstick.network_services.nfvi.resource.open")
     @mock.patch("yardstick.network_services.nfvi.resource.os")
     def test__provide_config_file(self, mock_open, mock_os):
@@ -187,7 +195,6 @@ class TestResourceProfile(unittest.TestCase):
         res = self.resource_profile.parse_collectd_result({})
         expected_result = {'cpu': {}, 'dpdkstat': {}, 'hugepages': {},
                            'memory': {}, 'ovs_stats': {}, 'timestamp': '',
-                           'intel_pmu': {},
                            'virt': {}}
         self.assertDictEqual(res, expected_result)
 
@@ -200,7 +207,6 @@ class TestResourceProfile(unittest.TestCase):
         res = self.resource_profile.parse_collectd_result(metric)
         expected_result = {'cpu': {1: {'ipc': '1234'}}, 'dpdkstat': {}, 'hugepages': {},
                            'memory': {}, 'ovs_stats': {}, 'timestamp': '',
-                           'intel_pmu': {},
                            'virt': {}}
         self.assertDictEqual(res, expected_result)
 
@@ -209,7 +215,6 @@ class TestResourceProfile(unittest.TestCase):
         res = self.resource_profile.parse_collectd_result(metric)
         expected_result = {'cpu': {}, 'dpdkstat': {}, 'hugepages': {},
                            'memory': {'bw': '101'}, 'ovs_stats': {}, 'timestamp': '',
-                           'intel_pmu': {},
                            'virt': {}}
         self.assertDictEqual(res, expected_result)
 
@@ -220,7 +225,6 @@ class TestResourceProfile(unittest.TestCase):
         res = self.resource_profile.parse_collectd_result(metric)
         expected_result = {'cpu': {}, 'dpdkstat': {}, 'hugepages': {'free': '101'},
                            'memory': {}, 'ovs_stats': {}, 'timestamp': '',
-                           'intel_pmu': {},
                            'virt': {}}
         self.assertDictEqual(res, expected_result)
 
@@ -237,7 +241,6 @@ class TestResourceProfile(unittest.TestCase):
         res = self.resource_profile.parse_collectd_result(metric)
         expected_result = {'cpu': {}, 'dpdkstat': {'tx': '101'}, 'hugepages': {},
                            'memory': {}, 'ovs_stats': {'tx': '101'}, 'timestamp': '',
-                           'intel_pmu': {},
                            'virt': {'memory': '101'}}
         self.assertDictEqual(res, expected_result)
 
index e6a1f0d..b166fe7 100644 (file)
@@ -24,10 +24,17 @@ Interval {{ interval }}
 ##############################################################################
 
 #LoadPlugin syslog
-{% for plugin in loadplugins %}
+{% for plugin in loadplugins if plugin != "ovs_stats" %}
 LoadPlugin {{ plugin }}
 {% endfor %}
 
+{% if "ovs_stats" in plugins %}
+<LoadPlugin ovs_stats>
+  Interval 1
+</LoadPlugin>
+{% endif %}
+
+
 ##############################################################################
 # Plugin configuration                                                       #
 #----------------------------------------------------------------------------#
@@ -82,12 +89,11 @@ LoadPlugin {{ plugin }}
 {% endif %}
 
 {% if "intel_pmu" in plugins %}
-<Plugin intel_pmu>
+<Plugin "intel_pmu">
    ReportHardwareCacheEvents true
    ReportKernelPMUEvents true
    ReportSoftwareEvents true
-   EventList "/opt/nsb_bin/pmu_event.json"
-   HardwareEvents "L2_RQSTS.CODE_RD_HIT,L2_RQSTS.CODE_RD_MISS" "L2_RQSTS.ALL_CODE_RD"
+   EventList "{{ plugins['intel_pmu']['pmu_event_path'] }}"
 </Plugin>
 {% endif %}
 
@@ -110,6 +116,8 @@ LoadPlugin {{ plugin }}
 {% if "virt" in plugins %}
 <Plugin "virt">
 # monitor all domains
+  RefreshInterval 60
+  ExtraStats "cpu_util disk disk_err domain_state fs_info job_stats_background pcpu perf vcpupin"
 </Plugin>
 {% endif %}
 
@@ -117,7 +125,7 @@ LoadPlugin {{ plugin }}
 <Plugin "ovs_stats">
   Port "6640"
   Address "127.0.0.1"
-  Socket "/usr/local/var/run/openvswitch/db.sock"
+  Socket "{{ plugins['ovs_stats']['ovs_socket_path'] }}"
 # don't specify bridges, monitor all bridges
 </Plugin>
 {% endif %}
index fef44e2..dea754d 100644 (file)
@@ -34,7 +34,7 @@ from yardstick import ssh
 from yardstick.common.task_template import finalize_for_yaml
 from yardstick.common.utils import validate_non_string_sequence
 from yardstick.network_services.nfvi.collectd import AmqpConsumer
-from yardstick.network_services.utils import get_nsb_option
+
 
 LOG = logging.getLogger(__name__)
 
@@ -53,6 +53,7 @@ class ResourceProfile(object):
     AMPQ_PORT = 5672
     DEFAULT_INTERVAL = 25
     DEFAULT_TIMEOUT = 3600
+    OVS_SOCKET_PATH = "/usr/local/var/run/openvswitch/db.sock"
 
     def __init__(self, mgmt, port_names=None, cores=None, plugins=None,
                  interval=None, timeout=None):
@@ -154,7 +155,6 @@ class ResourceProfile(object):
             "dpdkstat": {},
             "virt": {},
             "ovs_stats": {},
-            "intel_pmu": {},
         }
         testcase = ""
 
@@ -233,10 +233,32 @@ class ResourceProfile(object):
         }
         self._provide_config_file(config_file_path, self.COLLECTD_CONF, kwargs)
 
+    def _setup_intel_pmu(self, connection, bin_path):
+        pmu_event_path = os.path.join(bin_path, "pmu_event.json")
+        try:
+            self.plugins["intel_pmu"]["pmu_event_path"] = pmu_event_path
+        except KeyError:
+            # if intel_pmu is not a dict, force it into a dict
+            self.plugins["intel_pmu"] = {"pmu_event_path": pmu_event_path}
+        LOG.debug("Downloading event list for pmu_stats plugin")
+        cmd = 'cd {0}; PMU_EVENTS_PATH={1} python event_download_local.py'.format(
+            bin_path, pmu_event_path)
+        cmd = "sudo bash -c '{}'".format(cmd)
+        connection.execute(cmd)
+
+    def _setup_ovs_stats(self, connection):
+        try:
+            socket_path = self.plugins["ovs_stats"].get("ovs_socket_path", self.OVS_SOCKET_PATH)
+        except KeyError:
+            # ovs_stats is not a dict
+            socket_path = self.OVS_SOCKET_PATH
+        status = connection.execute("test -S {}".format(socket_path))[0]
+        if status != 0:
+            LOG.error("cannot find OVS socket %s", socket_path)
+
     def _start_collectd(self, connection, bin_path):
         LOG.debug("Starting collectd to collect NFVi stats")
         connection.execute('sudo pkill -x -9 collectd')
-        bin_path = get_nsb_option("bin_path")
         collectd_path = os.path.join(bin_path, "collectd", "sbin", "collectd")
         config_file_path = os.path.join(bin_path, "collectd", "etc")
         exit_status = connection.execute("which %s > /dev/null 2>&1" % collectd_path)[0]
@@ -251,9 +273,10 @@ class ResourceProfile(object):
             #     collectd_installer, http_proxy, https_proxy))
             return
         if "intel_pmu" in self.plugins:
-            LOG.debug("Downloading event list for pmu_stats plugin")
-            cmd = 'sudo bash -c \'cd /opt/tempT/pmu-tools/; python event_download_local.py\''
-            connection.execute(cmd)
+            self._setup_intel_pmu(connection, bin_path)
+        if "ovs_stats" in self.plugins:
+            self._setup_ovs_stats(connection)
+
         LOG.debug("Starting collectd to collect NFVi stats")
         # ensure collectd.conf.d exists to avoid error/warning
         connection.execute("sudo mkdir -p /etc/collectd/collectd.conf.d")