Projet

Général

Profil

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

root / plugins / libvirt / kvm_cpu @ b6912e76

Historique | Voir | Annoter | Télécharger (3,24 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 b6912e76 Alois
        list(
51
            filter(
52
                lambda x: x[0:3] == 'cpu' and x[3] != ' ', open('/proc/stat', 'r').readlines())))
53 e78a1590 loic
54 dda92e9b Rodolphe Qui?deville
    base_config = """graph_title KVM Virtual Machine CPU usage
55 e78a1590 loic
graph_vlabel %%
56 33e95e6f Lars Kruse
graph_category virtualization
57 e78a1590 loic
graph_scale no
58
graph_period second
59 dda92e9b Rodolphe Qui?deville
graph_info This graph shows the current CPU used by virtual machines
60 e78a1590 loic
graph_args --base 1000 -r --lower-limit 0 --upper-limit %d""" % percent
61 bde90ba9 Lars Kruse
    print(base_config)
62 dda92e9b Rodolphe Qui?deville
    for vm in vm_names:
63 bde90ba9 Lars Kruse
        print("%s_cpu.label %s" % (vm, vm))
64
        print("%s_cpu.min 0" % vm)
65
        print("%s_cpu.type DERIVE" % vm)
66
        print("%s_cpu.draw AREASTACK" % vm)
67
        print("%s_cpu.info percent of cpu time used by virtual machine" % vm)
68 dda92e9b Rodolphe Qui?deville
69
70
def clean_vm_name(vm_name):
71
    ''' Replace all special chars
72
    @param vm_name : a vm's name
73
    @return cleaned vm's name
74
    '''
75
    # suffix part defined in conf
76
    suffix = os.getenv('vmsuffix')
77
    if suffix:
78 bde90ba9 Lars Kruse
        vm_name = re.sub(suffix, '', vm_name)
79 225a9156 Bianco Veigel
    # proxmox uses kvm with -name parameter
80 113008b0 Bianco Veigel
    parts = vm_name.split('\x00')
81 bde90ba9 Lars Kruse
    if parts[0].endswith('kvm'):
82 113008b0 Bianco Veigel
        try:
83 bde90ba9 Lars Kruse
            return parts[parts.index('-name') + 1]
84 113008b0 Bianco Veigel
        except ValueError:
85
            pass
86 dda92e9b Rodolphe Qui?deville
    return re.sub(r"[^a-zA-Z0-9_]", "_", vm_name)
87
88 bde90ba9 Lars Kruse
89 dda92e9b Rodolphe Qui?deville
def detect_kvm():
90 bde90ba9 Lars Kruse
    ''' Check if kvm is installed '''
91 dda92e9b Rodolphe Qui?deville
    kvm = Popen("which kvm", shell=True, stdout=PIPE)
92
    kvm.communicate()
93
    return not bool(kvm.returncode)
94
95 bde90ba9 Lars Kruse
96 dda92e9b Rodolphe Qui?deville
def find_vm_names(pids):
97
    '''Find and clean vm names from pids
98 8713eb37 Lars Kruse
    @return a dictionary of {pids : cleaned vm name}
99 dda92e9b Rodolphe Qui?deville
    '''
100
    result = {}
101
    for pid in pids:
102 b6912e76 Alois
        cmdline = open("/proc/%s/cmdline" % pid, "r")
103 bde90ba9 Lars Kruse
        result[pid] = clean_vm_name(
104
            re.sub(r"^.*guest=([a-zA-Z0-9.-_-]*).*$", r"\1", cmdline.readline()))
105 dda92e9b Rodolphe Qui?deville
    return result
106 17f78427 Lars Kruse
107 bde90ba9 Lars Kruse
108 dda92e9b Rodolphe Qui?deville
def list_pids():
109
    ''' Find the pid of kvm processes
110
    @return a list of pids from running kvm
111
    '''
112 621744a6 Jan Egil Vestbø
    pid = Popen("pidof qemu-kvm qemu-system-x86_64 kvm", shell=True, stdout=PIPE)
113 b6912e76 Alois
    return pid.communicate()[0].decode().split()
114 dda92e9b Rodolphe Qui?deville
115 bde90ba9 Lars Kruse
116 dda92e9b Rodolphe Qui?deville
def fetch(vms):
117
    ''' Fetch values for a list of pids
118 8713eb37 Lars Kruse
    @param dictionary {kvm_pid: cleaned vm name}
119 dda92e9b Rodolphe Qui?deville
    '''
120 bde90ba9 Lars Kruse
    for pid, name in vms.items():
121 b6912e76 Alois
        user, system = open("/proc/%s/stat" % pid, 'r').readline().split(' ')[13:15]
122 bde90ba9 Lars Kruse
        print('%s_cpu.value %d' % (name, int(user) + int(system)))
123
124 17f78427 Lars Kruse
125 dda92e9b Rodolphe Qui?deville
if __name__ == "__main__":
126
    if len(sys.argv) > 1:
127
        if sys.argv[1] in ['autoconf', 'detect']:
128
            if detect_kvm():
129 bde90ba9 Lars Kruse
                print("yes")
130 dda92e9b Rodolphe Qui?deville
            else:
131 bde90ba9 Lars Kruse
                print("no")
132 dda92e9b Rodolphe Qui?deville
        elif sys.argv[1] == "config":
133
            config(find_vm_names(list_pids()).values())
134
        else:
135
            fetch(find_vm_names(list_pids()))
136
    else:
137
        fetch(find_vm_names(list_pids()))