Revision 2439c9d6

b/snf-cyclades-gtools/collectd/conf/ganeti-stats.conf
5 5
	ModulePath "/usr/lib/snf-cyclades-gtools/collectd/"
6 6
	LogTraces true
7 7
	Interactive false
8
	Import "ganeti-stats"
8
	Import "ganeti-cpustats"
9
	Import "ganeti-netstats"
9 10
</Plugin>
b/snf-cyclades-gtools/collectd/examples/ganeti-stats-collectd.conf
25 25
	ModulePath "/usr/lib/snf-cyclades-gtools/collectd/"
26 26
	LogTraces true
27 27
	Interactive false
28
	Import "ganeti-stats"
28
	Import "ganeti-cpustats"
29
	Import "ganeti-netstats"
29 30
</Plugin>
30 31

  
31 32
Include "/etc/collectd/filters.conf"
b/snf-cyclades-gtools/collectd/plugins/ganeti-cpustats.py
1
#!/usr/bin/env python
2

  
3
import os
4
import collectd
5

  
6
from glob import glob
7

  
8

  
9
def get_vcpus(pid):
10
    """Get a KVM instance vCPU count by looking at its fd's"""
11
    vcpus = 0
12
    for fd in glob("/proc/%d/fd/*" % pid):
13
        # XXX: sad but trueeeeeeeeeeee
14
        if os.readlink(fd) == "anon_inode:kvm-vcpu":
15
            vcpus += 1
16
    return vcpus
17

  
18

  
19
def cpustats(data=None):
20
    for file in glob("/var/run/ganeti/kvm-hypervisor/pid/*"):
21
        instance = os.path.basename(file)
22
        try:
23
            pid = int(open(file, "r").read())
24
            proc = open("/proc/%d/stat" % pid, "r")
25
            cputime = [int(proc.readline().split()[42])]
26
        except EnvironmentError:
27
            continue
28
        vcpus = get_vcpus(pid)
29
        proc.close()
30

  
31
        vl = collectd.Values(type="derive")
32
        vl.host = instance
33
        vl.plugin = "cpu"
34
        vl.type = "virt_cpu_total"
35
        total = sum(cputime) * 100 / (vcpus * os.sysconf("SC_CLK_TCK"))
36
        vl.dispatch(values=[total])
37

  
38
collectd.register_read(cpustats)
39

  
40
# vim: set ts=4 sts=4 et sw=4 :
b/snf-cyclades-gtools/collectd/plugins/ganeti-netstats.py
1
#!/usr/bin/env python
2

  
3
import os
4
import collectd
5

  
6
from glob import glob
7

  
8

  
9
def read_int(file):
10
    f = open(file, "r")
11
    try:
12
        val = int(f.read())
13
    except ValueError:
14
        val = None
15
    finally:
16
        f.close()
17

  
18
    return val
19

  
20

  
21
def netstats(data=None):
22
    for dir in glob("/var/run/ganeti/kvm-hypervisor/nic/*"):
23
        if not os.path.isdir(dir):
24
            continue
25

  
26
        hostname = os.path.basename(dir)
27

  
28
        for nic in glob(os.path.join(dir, "*")):
29
            idx = int(os.path.basename(nic))
30
            with open(nic) as nicfile:
31
                try:
32
                    iface = nicfile.readline().strip()
33
                except EnvironmentError:
34
                    continue
35

  
36
            if not os.path.isdir("/sys/class/net/%s" % iface):
37
                continue
38

  
39
            bytes_in = read_int("/sys/class/net/%s/statistics/rx_bytes"
40
                                % iface)
41
            bytes_out = read_int("/sys/class/net/%s/statistics/tx_bytes"
42
                                 % iface)
43

  
44
            vl = collectd.Values(type="derive")
45
            vl.host = hostname
46
            vl.plugin = "interface"
47
            vl.type = "if_octets"
48
            vl.type_instance = "eth%d" % idx
49
            vl.dispatch(values=[bytes_out, bytes_in])
50

  
51
collectd.register_read(netstats)
52

  
53
# vim: set ts=4 sts=4 et sw=4 :
/dev/null
1
#!/usr/bin/env python
2

  
3
import os
4
import collectd
5

  
6
from hashlib import md5
7

  
8
from glob import glob
9

  
10

  
11
def read_int(file):
12
    f = open(file, "r")
13
    try:
14
        val = int(f.read())
15
    except ValueError:
16
        val = None
17
    finally:
18
        f.close()
19

  
20
    return val
21

  
22

  
23
def anonymize_hostname(hostname):
24
    #return md5(hostname).hexdigest()
25
    return hostname
26

  
27

  
28
def get_vcpus(pid):
29
    """Get a KVM instance vCPU count by looking at its fd's"""
30
    vcpus = 0
31
    for fd in glob("/proc/%d/fd/*" % pid):
32
        # XXX: sad but trueeeeeeeeeeee
33
        if os.readlink(fd) == "anon_inode:kvm-vcpu":
34
            vcpus += 1
35
    return vcpus
36

  
37

  
38
def netstats(data=None):
39
    for dir in glob("/var/run/ganeti/kvm-hypervisor/nic/*"):
40
        if not os.path.isdir(dir):
41
            continue
42

  
43
        hostname = os.path.basename(dir)
44

  
45
        for nic in glob(os.path.join(dir, "*")):
46
            idx = int(os.path.basename(nic))
47
            with open(nic) as nicfile:
48
                try:
49
                    iface = nicfile.readline().strip()
50
                except EnvironmentError:
51
                    continue
52

  
53
            if not os.path.isdir("/sys/class/net/%s" % iface):
54
                continue
55
            
56
            bytes_in = read_int("/sys/class/net/%s/statistics/rx_bytes" % iface)
57
            bytes_out = read_int("/sys/class/net/%s/statistics/tx_bytes" % iface)
58

  
59
            vl = collectd.Values(type="counter")
60
            vl.host = anonymize_hostname(hostname)
61
            vl.plugin = "interface"
62
            vl.type = "if_octets"
63
            vl.type_instance = "eth%d" % idx
64
            vl.dispatch(values=[bytes_out, bytes_in])
65

  
66

  
67
def cpustats(data=None):
68
    for file in glob("/var/run/ganeti/kvm-hypervisor/pid/*"):
69
        instance = os.path.basename(file)
70
        try:
71
            pid = int(open(file, "r").read())
72
            proc = open("/proc/%d/stat" % pid, "r")
73
            cputime = [int(proc.readline().split()[42])]
74
        except EnvironmentError:
75
            continue
76
        vcpus = get_vcpus(pid)
77
        proc.close()
78

  
79
        vl = collectd.Values(type="counter")
80
        vl.host = anonymize_hostname(instance)
81
        vl.plugin = "cpu"
82
        vl.type = "virt_cpu_total"
83
        total = sum(cputime) * 100 / (vcpus * os.sysconf("SC_CLK_TCK"))
84
        vl.dispatch(values=[total])
85

  
86
collectd.register_read(netstats)
87
collectd.register_read(cpustats)
88

  
89
# vim: set ts=4 sts=4 et sw=4 :
b/snf-stats-app/synnefo_stats/grapher.py
35 35

  
36 36
import gd
37 37
import os
38
import sys
39
import subprocess
40 38

  
41
from cgi import escape
42 39
from cStringIO import StringIO
43 40

  
44 41
import rrdtool
......
72 69

  
73 70
    try:
74 71
        values = rrdtool.fetch(fname, "AVERAGE")[2][-20:]
75
    except rrdtool.error, e:
72
    except rrdtool.error:
76 73
        values = [(0.0, )]
77 74

  
78 75
    v = [x[0] for x in values if x[0] is not None]
......
119 116

  
120 117
    try:
121 118
        values = rrdtool.fetch(fname, "AVERAGE")[2][-20:]
122
    except rrdtool.error, e:
119
    except rrdtool.error:
123 120
        values = [(0.0, 0.0)]
124 121

  
125 122
    v = [x for x in values if x[0] is not None and x[1] is not None]
......
175 172
                  #"-t", "CPU usage",
176 173
                  "-v", "%",
177 174
                  #"--lazy",
178
                  "DEF:cpu=%s:ns:AVERAGE" % fname,
175
                  "DEF:cpu=%s:value:AVERAGE" % fname,
179 176
                  "LINE1:cpu#00ff00:")
180 177

  
181 178
    return read_file(outfname)
......
189 186
                  #"-t", "CPU usage",
190 187
                  "-v", "%",
191 188
                  #"--lazy",
192
                  "DEF:cpu=%s:ns:AVERAGE" % fname,
189
                  "DEF:cpu=%s:value:AVERAGE" % fname,
193 190
                  "LINE1:cpu#00ff00:")
194 191

  
195 192
    return read_file(outfname)
......
200 197
    outfname += "-net.png"
201 198

  
202 199
    rrdtool.graph(outfname, "-s", "-1d", "-e", "-20s",
203
              "--units", "si",
204
              "-v", "Bits/s",
205
              "COMMENT:\t\t\tAverage network traffic\\n",
206
              "DEF:rx=%s:rx:AVERAGE" % fname,
207
              "DEF:tx=%s:tx:AVERAGE" % fname,
208
              "CDEF:rxbits=rx,8,*",
209
              "CDEF:txbits=tx,8,*",
210
              "LINE1:rxbits#00ff00:Incoming",
211
              "GPRINT:rxbits:AVERAGE:\t%4.0lf%sbps\t\g",
212
              "LINE1:txbits#0000ff:Outgoing",
213
              "GPRINT:txbits:AVERAGE:\t%4.0lf%sbps\\n")
200
                  "--units", "si",
201
                  "-v", "Bits/s",
202
                  "COMMENT:\t\t\tAverage network traffic\\n",
203
                  "DEF:rx=%s:rx:AVERAGE" % fname,
204
                  "DEF:tx=%s:tx:AVERAGE" % fname,
205
                  "CDEF:rxbits=rx,8,*",
206
                  "CDEF:txbits=tx,8,*",
207
                  "LINE1:rxbits#00ff00:Incoming",
208
                  "GPRINT:rxbits:AVERAGE:\t%4.0lf%sbps\t\g",
209
                  "LINE1:txbits#0000ff:Outgoing",
210
                  "GPRINT:txbits:AVERAGE:\t%4.0lf%sbps\\n")
214 211

  
215 212
    return read_file(outfname)
216 213

  
......
220 217
    outfname += "-net-weekly.png"
221 218

  
222 219
    rrdtool.graph(outfname, "-s", "-1w", "-e", "-20s",
223
              "--units", "si",
224
              "-v", "Bits/s",
225
              "COMMENT:\t\t\tAverage network traffic\\n",
226
              "DEF:rx=%s:rx:AVERAGE" % fname,
227
              "DEF:tx=%s:tx:AVERAGE" % fname,
228
              "CDEF:rxbits=rx,8,*",
229
              "CDEF:txbits=tx,8,*",
230
              "LINE1:rxbits#00ff00:Incoming",
231
              "GPRINT:rxbits:AVERAGE:\t%4.0lf%sbps\t\g",
232
              "LINE1:txbits#0000ff:Outgoing",
233
              "GPRINT:txbits:AVERAGE:\t%4.0lf%sbps\\n")
220
                  "--units", "si",
221
                  "-v", "Bits/s",
222
                  "COMMENT:\t\t\tAverage network traffic\\n",
223
                  "DEF:rx=%s:rx:AVERAGE" % fname,
224
                  "DEF:tx=%s:tx:AVERAGE" % fname,
225
                  "CDEF:rxbits=rx,8,*",
226
                  "CDEF:txbits=tx,8,*",
227
                  "LINE1:rxbits#00ff00:Incoming",
228
                  "GPRINT:rxbits:AVERAGE:\t%4.0lf%sbps\t\g",
229
                  "LINE1:txbits#0000ff:Outgoing",
230
                  "GPRINT:txbits:AVERAGE:\t%4.0lf%sbps\\n")
234 231

  
235 232
    return read_file(outfname)
236 233

  
......
243 240
    return aes.decrypt(urlsafe_b64decode(secret)).rstrip('\x00')
244 241

  
245 242

  
246
available_graph_types = {
247
        'cpu-bar': draw_cpu_bar,
248
        'net-bar': draw_net_bar,
249
        'cpu-ts': draw_cpu_ts,
250
        'net-ts': draw_net_ts,
251
        'cpu-ts-w': draw_cpu_ts_w,
252
        'net-ts-w': draw_net_ts_w,
253
        }
243
available_graph_types = {'cpu-bar': draw_cpu_bar,
244
                         'net-bar': draw_net_bar,
245
                         'cpu-ts': draw_cpu_ts,
246
                         'net-ts': draw_net_ts,
247
                         'cpu-ts-w': draw_cpu_ts_w,
248
                         'net-ts-w': draw_net_ts_w
249
                         }
254 250

  
255 251

  
256 252
@api_method(http_method='GET', token_required=False, user_required=False,

Also available in: Unified diff