Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / libvirt / kvm_cpu @ bde90ba9

Historique | Voir | Annoter | Télécharger (3,2 ko)

1 bde90ba9 Lars Kruse
#!/usr/bin/env python3
2
"""
3
=encoding utf8
4
5
=head1 NAME
6
7
kvm_cpu - show CPU usage of VM
8
9
10
=head1 CONFIGURATION
11
12
Parsed environment variables:
13
14
 vmsuffix: part of VM name to be removed
15
16
17
=head1 LICENSE
18
19
GPLv3
20
21
SPDX-License-Identifier: GPL-3.0-only
22
23
24
=head1 AUTHORS
25
26
Maxence Dunnewind
27
28
Rodolphe Quiédeville
29
30
31
=head1 MAGIC MARKERS
32
33
 #%# capabilities=autoconf
34
 #%# family=contrib
35
36
=cut
37
"""
38
39
import os
40
import re
41
import sys
42 dda92e9b Rodolphe Qui?deville
from subprocess import Popen, PIPE
43
44 bde90ba9 Lars Kruse
45 dda92e9b Rodolphe Qui?deville
def config(vm_names):
46
    ''' Print the plugin's config
47
    @param vm_names : a list of "cleaned" vms' name
48
    '''
49 bde90ba9 Lars Kruse
    percent = 100 * len(
50
        filter(lambda x: x[0:3] == 'cpu' and x[3] != ' ', open('/proc/stat', 'r').readlines()))
51 e78a1590 loic
52 dda92e9b Rodolphe Qui?deville
    base_config = """graph_title KVM Virtual Machine CPU usage
53 e78a1590 loic
graph_vlabel %%
54 33e95e6f Lars Kruse
graph_category virtualization
55 e78a1590 loic
graph_scale no
56
graph_period second
57 dda92e9b Rodolphe Qui?deville
graph_info This graph shows the current CPU used by virtual machines
58 e78a1590 loic
graph_args --base 1000 -r --lower-limit 0 --upper-limit %d""" % percent
59 bde90ba9 Lars Kruse
    print(base_config)
60 dda92e9b Rodolphe Qui?deville
    for vm in vm_names:
61 bde90ba9 Lars Kruse
        print("%s_cpu.label %s" % (vm, vm))
62
        print("%s_cpu.min 0" % vm)
63
        print("%s_cpu.type DERIVE" % vm)
64
        print("%s_cpu.draw AREASTACK" % vm)
65
        print("%s_cpu.info percent of cpu time used by virtual machine" % vm)
66 dda92e9b Rodolphe Qui?deville
67
68
def clean_vm_name(vm_name):
69
    ''' Replace all special chars
70
    @param vm_name : a vm's name
71
    @return cleaned vm's name
72
    '''
73
    # suffix part defined in conf
74
    suffix = os.getenv('vmsuffix')
75
    if suffix:
76 bde90ba9 Lars Kruse
        vm_name = re.sub(suffix, '', vm_name)
77 225a9156 Bianco Veigel
    # proxmox uses kvm with -name parameter
78 113008b0 Bianco Veigel
    parts = vm_name.split('\x00')
79 bde90ba9 Lars Kruse
    if parts[0].endswith('kvm'):
80 113008b0 Bianco Veigel
        try:
81 bde90ba9 Lars Kruse
            return parts[parts.index('-name') + 1]
82 113008b0 Bianco Veigel
        except ValueError:
83
            pass
84 dda92e9b Rodolphe Qui?deville
    return re.sub(r"[^a-zA-Z0-9_]", "_", vm_name)
85
86 bde90ba9 Lars Kruse
87 dda92e9b Rodolphe Qui?deville
def detect_kvm():
88 bde90ba9 Lars Kruse
    ''' Check if kvm is installed '''
89 dda92e9b Rodolphe Qui?deville
    kvm = Popen("which kvm", shell=True, stdout=PIPE)
90
    kvm.communicate()
91
    return not bool(kvm.returncode)
92
93 bde90ba9 Lars Kruse
94 dda92e9b Rodolphe Qui?deville
def find_vm_names(pids):
95
    '''Find and clean vm names from pids
96 8713eb37 Lars Kruse
    @return a dictionary of {pids : cleaned vm name}
97 dda92e9b Rodolphe Qui?deville
    '''
98
    result = {}
99
    for pid in pids:
100
        cmdline = open("/proc/%s/cmdline" % pid, "r")
101 bde90ba9 Lars Kruse
        result[pid] = clean_vm_name(
102
            re.sub(r"^.*guest=([a-zA-Z0-9.-_-]*).*$", r"\1", cmdline.readline()))
103 dda92e9b Rodolphe Qui?deville
    return result
104 17f78427 Lars Kruse
105 bde90ba9 Lars Kruse
106 dda92e9b Rodolphe Qui?deville
def list_pids():
107
    ''' Find the pid of kvm processes
108
    @return a list of pids from running kvm
109
    '''
110 621744a6 Jan Egil Vestbø
    pid = Popen("pidof qemu-kvm qemu-system-x86_64 kvm", shell=True, stdout=PIPE)
111 dda92e9b Rodolphe Qui?deville
    return pid.communicate()[0].split()
112
113 bde90ba9 Lars Kruse
114 dda92e9b Rodolphe Qui?deville
def fetch(vms):
115
    ''' Fetch values for a list of pids
116 8713eb37 Lars Kruse
    @param dictionary {kvm_pid: cleaned vm name}
117 dda92e9b Rodolphe Qui?deville
    '''
118 bde90ba9 Lars Kruse
    for pid, name in vms.items():
119
        user, system = open("/proc/%s/stat" % pid, 'r').readline().split(' ')[13:15]
120
        print('%s_cpu.value %d' % (name, int(user) + int(system)))
121
122 17f78427 Lars Kruse
123 dda92e9b Rodolphe Qui?deville
if __name__ == "__main__":
124
    if len(sys.argv) > 1:
125
        if sys.argv[1] in ['autoconf', 'detect']:
126
            if detect_kvm():
127 bde90ba9 Lars Kruse
                print("yes")
128 dda92e9b Rodolphe Qui?deville
            else:
129 bde90ba9 Lars Kruse
                print("no")
130 dda92e9b Rodolphe Qui?deville
        elif sys.argv[1] == "config":
131
            config(find_vm_names(list_pids()).values())
132
        else:
133
            fetch(find_vm_names(list_pids()))
134
    else:
135
        fetch(find_vm_names(list_pids()))