Projet

Général

Profil

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

root / plugins / libvirt / kvm_net @ 3267bbd0

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

1 3267bbd0 Lars Kruse
#!/usr/bin/python3
2 82242a42 Rodolphe Qui?deville
# vim: set fileencoding=utf-8
3
#
4
# Munin plugin to show the network I/O per vm
5
#
6 6bc704a1 Igor Borodikhin
# Copyright Igor Borodikhin
7 82242a42 Rodolphe Qui?deville
#
8
# License : GPLv3
9
#
10
#
11
# parsed environment variables:
12
# vmsuffix: part of vm name to be removed
13
#
14
#%# capabilities=autoconf
15
#%# family=contrib
16
17
import re, os, sys
18
from subprocess import Popen, PIPE
19
20 f6080f5f Lars Kruse
21 82242a42 Rodolphe Qui?deville
def config(vm_names):
22 7f98e21f Lars Kruse
    """ Print the plugin's config
23
24 82242a42 Rodolphe Qui?deville
    @param vm_names : a list of "cleaned" vms' name
25 7f98e21f Lars Kruse
    """
26 82242a42 Rodolphe Qui?deville
    base_config = """graph_title KVM Network I/O
27
graph_vlabel Bytes rx(-)/tx(+) per second
28 81db94e2 Gabriele Pohl
graph_category Virtualization
29 82242a42 Rodolphe Qui?deville
graph_info This graph shows the network I/O of the virtual machines
30
graph_args --base 1024
31
    """
32 67cc769c Lars Kruse
    print(base_config)
33 82242a42 Rodolphe Qui?deville
    for vm in vm_names:
34 67cc769c Lars Kruse
        print("%s_in.label %s" % (vm, vm))
35
        print("%s_in.type COUNTER" % vm)
36
        print("%s_in.min 0" % vm)
37
        print("%s_in.draw LINE2" % vm)
38
        print("%s_out.negative %s_in" % (vm, vm))
39
        print("%s_out.label %s" % (vm, vm))
40
        print("%s_out.type COUNTER" % vm)
41
        print("%s_out.min 0" % vm)
42
        print("%s_out.draw LINE2" % vm)
43 82242a42 Rodolphe Qui?deville
44 f6080f5f Lars Kruse
45 82242a42 Rodolphe Qui?deville
def clean_vm_name(vm_name):
46 7f98e21f Lars Kruse
    """ Replace all special chars
47
48 82242a42 Rodolphe Qui?deville
    @param vm_name : a vm's name
49
    @return cleaned vm's name
50 7f98e21f Lars Kruse
    """
51 82242a42 Rodolphe Qui?deville
    # suffix part defined in conf
52 7f98e21f Lars Kruse
    suffix = os.getenv("vmsuffix")
53 82242a42 Rodolphe Qui?deville
    if suffix:
54 7f98e21f Lars Kruse
        vm_name = re.sub(suffix, "", vm_name)
55 82242a42 Rodolphe Qui?deville
    return re.sub(r"[^a-zA-Z0-9_]", "_", vm_name)
56 f6080f5f Lars Kruse
57
58 82242a42 Rodolphe Qui?deville
def fetch(vms):
59 7f98e21f Lars Kruse
    """ Fetch values for a list of pids
60
61 82242a42 Rodolphe Qui?deville
    @param dictionnary {kvm_pid: cleaned vm name}
62 7f98e21f Lars Kruse
    """
63 82242a42 Rodolphe Qui?deville
    res = {}
64
    for pid in vms:
65 6bc704a1 Igor Borodikhin
        tap = get_vm_mac(pid)
66 82242a42 Rodolphe Qui?deville
        try:
67 6bc704a1 Igor Borodikhin
            f = open("/proc/net/dev", "r")
68
            for line in f.readlines():
69
                if tap in line:
70 67cc769c Lars Kruse
                    print("%s_in.value %s" % (vms[pid], line.split()[1]))
71
                    print("%s_out.value %s" % (vms[pid], line.split()[9]))
72 6bc704a1 Igor Borodikhin
                    break
73
        except Exception as inst:
74 67cc769c Lars Kruse
            print(inst)
75 82242a42 Rodolphe Qui?deville
            continue
76
77 f6080f5f Lars Kruse
78 82242a42 Rodolphe Qui?deville
def detect_kvm():
79 7f98e21f Lars Kruse
    """ Check if kvm is installed """
80 82242a42 Rodolphe Qui?deville
    kvm = Popen("which kvm", shell=True, stdout=PIPE)
81
    kvm.communicate()
82
    return not bool(kvm.returncode)
83
84 f6080f5f Lars Kruse
85 82242a42 Rodolphe Qui?deville
def find_vm_names(pids):
86 7f98e21f Lars Kruse
    """Find and clean vm names from pids
87
88 82242a42 Rodolphe Qui?deville
    @return a dictionnary of {pids : cleaned vm name}
89 7f98e21f Lars Kruse
    """
90 82242a42 Rodolphe Qui?deville
    result = {}
91
    for pid in pids:
92
        cmdline = open("/proc/%s/cmdline" % pid, "r")
93 f6080f5f Lars Kruse
        result[pid] = clean_vm_name(re.sub(r"^.*-name\x00([a-zA-Z0-9.-_-]*)\x00\-.*$",r"\1", cmdline.readline()))
94 82242a42 Rodolphe Qui?deville
    return result
95 f6080f5f Lars Kruse
96
97 82242a42 Rodolphe Qui?deville
def get_vm_mac(pid):
98 7f98e21f Lars Kruse
    """Find and clean vm names from pids
99
100 82242a42 Rodolphe Qui?deville
    @return the mac address for a specified pid
101 7f98e21f Lars Kruse
    """
102 82242a42 Rodolphe Qui?deville
    cmdline = open("/proc/%s/cmdline" % pid, "r")
103 6bc704a1 Igor Borodikhin
    line = cmdline.readline()
104
    mac = re.sub(r"^.*ifname=(tap[^,]+),.*$",r"\1", line)
105 82242a42 Rodolphe Qui?deville
    return mac
106
107 f6080f5f Lars Kruse
108 82242a42 Rodolphe Qui?deville
def list_pids():
109 7f98e21f Lars Kruse
    """ Find the pid of kvm processes
110
111 82242a42 Rodolphe Qui?deville
    @return a list of pids from running kvm
112 7f98e21f Lars Kruse
    """
113 621744a6 Jan Egil Vestbø
    pid = Popen("pidof qemu-kvm qemu-system-x86_64 kvm", shell=True, stdout=PIPE)
114 3267bbd0 Lars Kruse
    return pid.communicate()[0].decode().split()
115 82242a42 Rodolphe Qui?deville
116 6bc704a1 Igor Borodikhin
117 82242a42 Rodolphe Qui?deville
if __name__ == "__main__":
118
    if len(sys.argv) > 1:
119 7f98e21f Lars Kruse
        if sys.argv[1] in ["autoconf", "detect"]:
120 82242a42 Rodolphe Qui?deville
            if detect_kvm():
121 67cc769c Lars Kruse
                print("yes")
122 82242a42 Rodolphe Qui?deville
            else:
123 67cc769c Lars Kruse
                print("no")
124 82242a42 Rodolphe Qui?deville
        elif sys.argv[1] == "config":
125
            config(find_vm_names(list_pids()).values())
126
        else:
127
            fetch(find_vm_names(list_pids()))
128
    else:
129
        fetch(find_vm_names(list_pids()))