Table of Contents

Xen Monitor

Author Andrew Rankin
Compatibility Xymon 4.2
Requirements Python, Python-libvirt, Xen, Linux
Download http://eiknet.com/mi-vt.py.bz2
Last Update 2007-09-25

Description

Xen Monitoring script - This script is handy in that it sends information from the Dom0 on behalf of the DomUs. This way VM data shows up in hobbit with the rest of the DomU host information, giving you an easy way to keep tabs on where a VM lives if you move/migrate it. It also gives you information about all the DomUs on a Dom0 under the Dom0 in hobbit.

Installation

Client side

On the Dom0:

  1. Install mi-vt.py into the <client_root>/ext/ directory
  2. Modify mi-vt.py setting the bbhome, domain & hobbit_server variables
  3. Modify your clientlaunch.cfg, adding:
  # data from libvirt for virtual machines
  [vt]
          ENVFILE $HOBBITCLIENTHOME/etc/hobbitclient.cfg
          CMD $HOBBITCLIENTHOME/ext/mi-vt.py
          LOGFILE $HOBBITCLIENTHOME/logs/hobbitclient.log
          INTERVAL 5m

Server side

Source

mi-vt.py

Show Code ⇲

Hide Code ⇱

#!/usr/bin/python -u
#####
#
# Created by Andrew Rankin (andrew [at] eiknet.com).
# Monitors current virtual machines on a Dom0 using libvirt and relays its findings to hobbit.
#
# Parts of this script were borrowed from libvirt example python scripts.
# 
#####
 
import libvirt
import sys
import os
import time
import socket
 
# Test to see if we are running xen.
if not os.access("/proc/xen", os.R_OK):
    sys.exit(1)
 
###############
 
bbhome = '/home/hobbit/client'
bbtest = 'vt'
domain = ',domain,com'
hobbit_server = 'server.domain.com'
test_explanation = 'Virtual Machine Status'
status = {}
color = {}
hobbittime = time.strftime("%a %b %e %T %Z %Y", time.localtime())
domains = []
DATA = {}
status_info = {}
 
###############
 
# Connect to hypervisor
conn = libvirt.openReadOnly(None)
if conn == None:
    print 'Failed to open connection to the hypervisor'
    sys.exit(1)
 
# Get a list of Domains
try:
    domains = conn.listDomainsID()
except:
    print 'Failed to list domains'
    sys.exit(1)
 
# Get Physical systems specs
try:
    (model, memory, cores, mhz, nodes, sockets, cpus, threads) = conn.getInfo()
except:
    print 'Failed to extract the current node information'
    sys.exit(1)
 
DATA[socket.gethostname()] = "Host Server Specs\nMB Memory: %s\nNum CPUs: %s\nNum Cores: %s\nCPU MHz: %s\n\n" \
    %( memory, cpus, cores, mhz )
 
for dom in domains:
    info = conn.lookupByID(dom).info()
    hostname = conn.lookupByID(dom).name()
    dom_hostname = socket.gethostname()
    percentmem = float()
    state = str()
 
    if hostname == "Domain-0":
        hostname = dom_hostname
 
    # Warn on states
    if info[0] == 1:
        status[hostname] = bbtest + " OK"
        color[hostname] = "green"
        state = "Running"
    elif info[0] == 2:
        status[hostname] = bbtest + " OK"
        color[hostname] = "green"
        state = "Blocked"
    elif info[0] == 3:
        status[hostname] = bbtest + " Domain Paused"
        color[hostname] = "yellow"
        state = "Paused"
    elif info[0] == 4:
        status[hostname] = bbtest + " Domain Crashed"
        color[hostname] = "red"
        state = "Crashed"
    elif info[0] == 5:
        status[hostname] = bbtest + " Domain Dying"
        color[hostname] = "red"
        state = "Dying"
    elif info[0] == 6:
        status[hostname] = bbtest + " Domain Shutdown"
        color[hostname] = "red"
        state = "Shutdown"
 
    # more obvious explanation of colors
    if color[hostname] != "green":
        status_info[hostname] = "\n\n&"+color[hostname]+" "+hostname+" Domain State is "+state
 
        # Dom0 to carry warnings from its DomUs
        if status_info[dom_hostname] == "": status_info[dom_hostname] = "\n"
        status_info[dom_hostname] += "&"+color[hostname]+" "+hostname+" Domain State is "+state+"\n"
        status[dom_hostname] = status[hostname] 
        color[dom_hostname] = color[hostname]
    else:
        status_info[hostname] = ""
 
    # Convert to MB
    info[1] = info[1] / 1024
    info[2] = info[2] / 1024
 
    # Either Figure % memory or if less than 0, set to no max
    if info[1] >= 0:
        percentmem = ((float(info[2]) / memory) * 100)
    else:
        percentmem = ((float(info[2]) / memory) * 100)
        info[1] = memory
 
    if conn.lookupByID(dom).name() != "Domain-0":
        # Create our hobbit data for this host    
        DATA[hostname] = "State: %s\nHostServerMemUsed: %.2f%%\nMaxMemSet: %s MB\nCurMemSet: %s MB\nVCPUs: %d" \
	    %( state, percentmem, info[1], info[2], info[3] )
        # Create our hobbit data for the Dom0, this contains all data from all Virts
        DATA[dom_hostname] += hostname+"\n" + DATA[hostname] + "\n\n"
 
        # Push the dom0 name back on the end.
        DATA[hostname] += "\nDom0: " + dom_hostname
 
# Send away!
for key in DATA.keys():
    command = "%s/bin/bb %s 'status %s%s.%s %s %s - %s%s\n\n%s\n\n%s'\n" \
	%( bbhome, hobbit_server, key, domain, bbtest, color[key], hobbittime, status[key], status_info[key], test_explanation, DATA[key] )
 
    try:
        os.system(command)
    except:
        print "Failed to send data to hobbit"
 
sys.exit(0)

Known Bugs and Issues

To Do

Credits

Changelog