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_cpu
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

137 lines
3.3 KiB
Python
Executable file

#!/usr/bin/env python3
"""
=encoding utf8
=head1 NAME
kvm_cpu - show CPU usage of VM
=head1 CONFIGURATION
Parsed environment variables:
vmsuffix: part of VM name to be removed
=head1 LICENSE
GPLv3
SPDX-License-Identifier: GPL-3.0-only
=head1 AUTHORS
Maxence Dunnewind
Rodolphe Quiédeville
=head1 MAGIC MARKERS
#%# capabilities=autoconf
#%# family=contrib
=cut
"""
import os
import re
import sys
from subprocess import Popen, PIPE
def config(vm_names):
''' Print the plugin's config
@param vm_names : a list of "cleaned" vms' name
'''
percent = 100 * len(
list(
filter(
lambda x: x[0:3] == 'cpu' and x[3] != ' ', open('/proc/stat', 'r').readlines())))
base_config = """graph_title KVM Virtual Machine CPU usage
graph_vlabel %%
graph_category virtualization
graph_scale no
graph_period second
graph_info This graph shows the current CPU used by virtual machines
graph_args --base 1000 -r --lower-limit 0 --upper-limit %d""" % percent
print(base_config)
for vm in vm_names:
print("%s_cpu.label %s" % (vm, vm))
print("%s_cpu.min 0" % vm)
print("%s_cpu.type DERIVE" % vm)
print("%s_cpu.draw AREASTACK" % vm)
print("%s_cpu.info percent of cpu time used by virtual machine" % 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 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)
return pid.communicate()[0].decode().split()
def fetch(vms):
''' Fetch values for a list of pids
@param dictionary {kvm_pid: cleaned vm name}
'''
for pid, name in vms.items():
user, system = open("/proc/%s/stat" % pid, 'r').readline().split(' ')[13:15]
print('%s_cpu.value %d' % (name, int(user) + int(system)))
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()))