blog:vcenter_vm_monitoring_with_graphite

This is an old revision of the document!


vCenter VM monitoring with Graphite

This was done on a CentOS 6.3 server your mileage may vary on another platform.

You will need to have a version of collectd compiled that has the python plugin enabled. This can be down by downloading the collectd source and building it, making sure to have python-devel package installed.

We don't use the collectd RPM from the EPEL repository as its too old and does not have the graphite_write plugin.

Mathew has a good write on the graphite / collectd compilation and configuration for graphite. http://blog.matthewdfuller.com/2014/06/sending-collectd-metrics-to-graphite.html

Be sure to have this installed before run “./configure”

yum install python-devel
<code>

The configuration of /opt/collectd/etc/collectd.conf requires the following entries.  Adjust the Username, Vcenter and Password to suit your environment.
<code>
<LoadPlugin python>
  Globals true
</LoadPlugin>

<Plugin python>
        # vcenter.py is at /usr/lib/python2.6/site-packages
        LogTraces true
        Interactive false
        Import vcenter
        <Module vcenter>
             Username "root"
             Vcenter "vc.local"
             Password "vmware"
             Verbose false
        </Module>
</Plugin>

This works fine in my lab where I have a single vCenter instance.

#!/usr/bin/python
# Collect basic stats about power on VM's on a single vCenter
# Brett England - 1-Oct-2014
 
import collectd
from pysphere import VIServer
NAME = 'vCenter'   # Plugin name
 
# Metric and reporting type as a value
METRIC={"name":None,
        "runtime.powerState":None,
        "summary.quickStats.overallCpuUsage":"gauge",
        "summary.quickStats.uptimeSeconds":"gauge",
        "summary.quickStats.guestMemoryUsage":"bytes",
        "summary.quickStats.hostMemoryUsage":"bytes",
        "summary.quickStats.overallCpuUsage":"gauge",
        "config.hardware.memoryMB":"bytes"}
 
def connect():
    server = VIServer()
    try:
        server.connect(VCENTER, USERNAME, PASSWORD)
    except:
        logger('warn', "failed to connect to %s" % (VCENTER))
        return None
    return server
 
def get_stats():
    server = connect()
    if server is None:
        return []
    ret = []
    props = server._retrieve_properties_traversal(property_names=METRIC.keys(),
                                                  obj_type="VirtualMachine")
    for obj in props:
        skip_vm = False
        d={}
        for vm_property in obj.PropSet:
            if vm_property.Name == "runtime.powerState":
                if vm_property.Val != "poweredOn":
                    skip_vm = True
                    break
                continue
 
            d[vm_property.Name] = vm_property.Val
 
        if not skip_vm:
            ret.append(d)
    server.disconnect()
    return ret
 
# callback configuration for module
def configure_callback(conf):
  global VCENTER, USERNAME, PASSWORD, VERBOSE_LOGGING
  VCENTER = ''
  USERNAME = ''
  PASSWORD = ''
  VERBOSE_LOGGING = False
 
  for node in conf.children:
    if node.key == "Vcenter":
      VCENTER = node.values[0]
    elif node.key == "Username":
      USERNAME = node.values[0]
    elif node.key == "Password":
      PASSWORD = node.values[0]
    elif node.key == "Verbose":
      VERBOSE_LOGGING = bool(node.values[0])
    else:
      logger('warn', 'Unknown config key: %s' % node.key)
 
# https://collectd.org/wiki/index.php/Naming_schema
# The serialized form of the identifier is:
# host "/" plugin ["-" plugin instance] "/" type ["-" type instance]
#
# We want:   VCENTER / VMNAME / type...
def dispatch_value(vmname, value, key, type):
 
    logger('verb','%s: Sending value: %s=%s' % (vmname, key, value))
    # This is not intuitive but its what we want.
    val = collectd.Values()
    val.host = VCENTER
    val.plugin = vmname
    val.type = type
    val.type_instance = key
    val.values = [value]
    val.dispatch()
 
def read_callback():
  logger('verb', "beginning read_callback")
  info = get_stats()
 
  if not info:
    logger('warn', "No data received")
    return
 
  for vm in info:
      vmname = vm['name']
      for key,value in vm.items():
          type = METRIC[key]
          if type:
              dispatch_value(vmname, value, key, type)
 
# logging function
def logger(t, msg):
    if t == 'err':
        collectd.error('%s: %s' % (NAME, msg))
    elif t == 'warn':
        collectd.warning('%s: %s' % (NAME, msg))
    elif t == 'verb':
        if VERBOSE_LOGGING:
            collectd.info('%s: %s' % (NAME, msg))
    else:
        collectd.notice('%s: %s' % (NAME, msg))
 
# main
collectd.register_config(configure_callback)
collectd.register_read(read_callback)
  • blog/vcenter_vm_monitoring_with_graphite.1412131457.txt.gz
  • Last modified: 2014/10/01 02:44
  • by brett