mirror of
https://github.com/munin-monitoring/contrib.git
synced 2025-07-21 18:41:03 +00:00
fixed graphing failures for VM deployed on legacy Centos 6.9 virtualization platforms (script uses the Proxmox entries), in the case of VM domain names beggining with digits (first field name character must be [a-ZA-Z_]) used "Validate field names" Python stanza from documentation ("How to write plugins", "Notes on field names") to improve the clean_vm_name function, thus munin kvm graph creation succeeded for VM with names starting with digits, like "150-121-Apache", deployed on Centos 6.9 virtualization platforms.
110 lines
3.3 KiB
Python
Executable file
110 lines
3.3 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
# vim: set fileencoding=utf-8
|
|
#
|
|
# Munin plugin to show amount of memory used by vm
|
|
#
|
|
# Copyright Maxence Dunnewind, Rodolphe Quiédeville, Adrien Pujol
|
|
#
|
|
# License : GPLv3
|
|
#
|
|
# parsed environment variables:
|
|
# vmsuffix: part of vm name to be removed
|
|
#
|
|
#%# capabilities=autoconf
|
|
#%# family=contrib
|
|
|
|
import re, os, sys
|
|
from subprocess import Popen, PIPE
|
|
|
|
def config(vm_names):
|
|
''' Print the plugin's config
|
|
@param vm_names : a list of "cleaned" vms' name
|
|
'''
|
|
base_config = """graph_title KVM Virtual Machine Memory usage
|
|
graph_vlabel Bytes
|
|
graph_category virtualization
|
|
graph_info This graph shows the current amount of memory used by virtual machines
|
|
graph_args --base 1024 -l 0"""
|
|
print(base_config)
|
|
for vm in vm_names:
|
|
print("%s_mem.label %s" % (vm, vm))
|
|
print("%s_mem.type GAUGE" % vm)
|
|
print("%s_mem.draw %s" % (vm, "AREASTACK"))
|
|
print("%s_mem.info memory used by virtual machine %s" % (vm, vm))
|
|
|
|
|
|
def clean_vm_name(vm_name):
|
|
''' Replace all special chars
|
|
@param vm_name : a vm's name
|
|
@return cleaned vm's name
|
|
'''
|
|
# suffix part defined in conf
|
|
suffix = os.getenv('vmsuffix')
|
|
if suffix:
|
|
vm_name = re.sub(suffix,'',vm_name)
|
|
|
|
# proxmox uses kvm with -name parameter
|
|
parts = vm_name.split('\x00')
|
|
if (parts[0].endswith('kvm')):
|
|
try:
|
|
return re.sub(r"(^[^A-Za-z_]|[^A-Za-z0-9_])", "_", parts[parts.index('-name')+1])
|
|
except ValueError:
|
|
pass
|
|
return re.sub(r"(^[^A-Za-z_]|[^A-Za-z0-9_])", "_", vm_name)
|
|
|
|
|
|
def fetch(vms):
|
|
''' Fetch values for a list of pids
|
|
@param dictionary {kvm_pid: cleaned vm name}
|
|
'''
|
|
res = {}
|
|
for pid in vms:
|
|
try:
|
|
cmdline = open("/proc/%s/cmdline" % pid, "r")
|
|
amount = re.sub(r"^.*-m\x00(.*)\x00-smp.*$",r"\1", cmdline.readline())
|
|
amount = int(amount) * 1024 * 1024
|
|
print("%s_mem.value %s" % (vms[pid], amount))
|
|
except:
|
|
cmdline = open("/proc/%s/cmdline" % pid, "r")
|
|
amount = re.sub(r"^.*-m\x00(\d+).*$",r"\1", cmdline.readline())
|
|
amount = int(amount) * 1024 * 1024
|
|
print("%s_mem.value %s" % (vms[pid], amount))
|
|
|
|
def detect_kvm():
|
|
''' Check if kvm is installed
|
|
'''
|
|
kvm = Popen("which kvm", shell=True, stdout=PIPE)
|
|
kvm.communicate()
|
|
return not bool(kvm.returncode)
|
|
|
|
def find_vm_names(pids):
|
|
'''Find and clean vm names from pids
|
|
@return a dictionary of {pids : cleaned vm name}
|
|
'''
|
|
result = {}
|
|
for pid in pids:
|
|
cmdline = open("/proc/%s/cmdline" % pid, "r")
|
|
result[pid] = clean_vm_name(re.sub(r"^.*guest=([a-zA-Z0-9.-_-]*).*$",r"\1", cmdline.readline()))
|
|
return result
|
|
|
|
def list_pids():
|
|
''' Find the pid of kvm processes
|
|
@return a list of pids from running kvm
|
|
'''
|
|
pid = Popen("pidof qemu-kvm qemu-system-x86_64 kvm", shell=True, stdout=PIPE, text=True)
|
|
return pid.communicate()[0].split()
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) > 1:
|
|
if sys.argv[1] in ['autoconf', 'detect']:
|
|
if detect_kvm():
|
|
print("yes")
|
|
else:
|
|
print("no")
|
|
elif sys.argv[1] == "config":
|
|
config(find_vm_names(list_pids()).values())
|
|
else:
|
|
fetch(find_vm_names(list_pids()))
|
|
else:
|
|
fetch(find_vm_names(list_pids()))
|