1
0
Fork 0
mirror of https://github.com/munin-monitoring/contrib.git synced 2025-07-21 18:41:03 +00:00
Munin-Contrib/plugins/libvirt/kvm_mem
Steve Baroti cc5e06ec15 kvm_*: improve field names for Proxmox, Centos
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.
2022-08-27 11:48:42 -04:00

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()))