Commit 657217cb authored by Stratos Psomadakis's avatar Stratos Psomadakis
Browse files

stats: Wheezy and collectd v5 compat

Make the necessary changes to the collectd Ganeti plugin and the
snf-stats-app grapher to make them work with the Debian Wheezy version
of collectd (and the new v5 rrd format).
parent 1ee608c4
......@@ -5,5 +5,6 @@
ModulePath "/usr/lib/snf-cyclades-gtools/collectd/"
LogTraces true
Interactive false
Import "ganeti-stats"
Import "ganeti-cpustats"
Import "ganeti-netstats"
</Plugin>
......@@ -25,7 +25,8 @@ LoadPlugin network
ModulePath "/usr/lib/snf-cyclades-gtools/collectd/"
LogTraces true
Interactive false
Import "ganeti-stats"
Import "ganeti-cpustats"
Import "ganeti-netstats"
</Plugin>
Include "/etc/collectd/filters.conf"
......
#!/usr/bin/env python
import os
import collectd
from glob import glob
def get_vcpus(pid):
"""Get a KVM instance vCPU count by looking at its fd's"""
vcpus = 0
for fd in glob("/proc/%d/fd/*" % pid):
# XXX: sad but trueeeeeeeeeeee
if os.readlink(fd) == "anon_inode:kvm-vcpu":
vcpus += 1
return vcpus
def cpustats(data=None):
for file in glob("/var/run/ganeti/kvm-hypervisor/pid/*"):
instance = os.path.basename(file)
try:
pid = int(open(file, "r").read())
proc = open("/proc/%d/stat" % pid, "r")
cputime = [int(proc.readline().split()[42])]
except EnvironmentError:
continue
vcpus = get_vcpus(pid)
proc.close()
vl = collectd.Values(type="derive")
vl.host = instance
vl.plugin = "cpu"
vl.type = "virt_cpu_total"
total = sum(cputime) * 100 / (vcpus * os.sysconf("SC_CLK_TCK"))
vl.dispatch(values=[total])
collectd.register_read(cpustats)
# vim: set ts=4 sts=4 et sw=4 :
......@@ -3,8 +3,6 @@
import os
import collectd
from hashlib import md5
from glob import glob
......@@ -20,21 +18,6 @@ def read_int(file):
return val
def anonymize_hostname(hostname):
#return md5(hostname).hexdigest()
return hostname
def get_vcpus(pid):
"""Get a KVM instance vCPU count by looking at its fd's"""
vcpus = 0
for fd in glob("/proc/%d/fd/*" % pid):
# XXX: sad but trueeeeeeeeeeee
if os.readlink(fd) == "anon_inode:kvm-vcpu":
vcpus += 1
return vcpus
def netstats(data=None):
for dir in glob("/var/run/ganeti/kvm-hypervisor/nic/*"):
if not os.path.isdir(dir):
......@@ -52,38 +35,19 @@ def netstats(data=None):
if not os.path.isdir("/sys/class/net/%s" % iface):
continue
bytes_in = read_int("/sys/class/net/%s/statistics/rx_bytes" % iface)
bytes_out = read_int("/sys/class/net/%s/statistics/tx_bytes" % iface)
vl = collectd.Values(type="counter")
vl.host = anonymize_hostname(hostname)
bytes_in = read_int("/sys/class/net/%s/statistics/rx_bytes"
% iface)
bytes_out = read_int("/sys/class/net/%s/statistics/tx_bytes"
% iface)
vl = collectd.Values(type="derive")
vl.host = hostname
vl.plugin = "interface"
vl.type = "if_octets"
vl.type_instance = "eth%d" % idx
vl.dispatch(values=[bytes_out, bytes_in])
def cpustats(data=None):
for file in glob("/var/run/ganeti/kvm-hypervisor/pid/*"):
instance = os.path.basename(file)
try:
pid = int(open(file, "r").read())
proc = open("/proc/%d/stat" % pid, "r")
cputime = [int(proc.readline().split()[42])]
except EnvironmentError:
continue
vcpus = get_vcpus(pid)
proc.close()
vl = collectd.Values(type="counter")
vl.host = anonymize_hostname(instance)
vl.plugin = "cpu"
vl.type = "virt_cpu_total"
total = sum(cputime) * 100 / (vcpus * os.sysconf("SC_CLK_TCK"))
vl.dispatch(values=[total])
collectd.register_read(netstats)
collectd.register_read(cpustats)
# vim: set ts=4 sts=4 et sw=4 :
......@@ -35,10 +35,7 @@ from django.http import HttpResponse
import gd
import os
import sys
import subprocess
from cgi import escape
from cStringIO import StringIO
import rrdtool
......@@ -72,7 +69,7 @@ def draw_cpu_bar(fname, outfname=None):
try:
values = rrdtool.fetch(fname, "AVERAGE")[2][-20:]
except rrdtool.error, e:
except rrdtool.error:
values = [(0.0, )]
v = [x[0] for x in values if x[0] is not None]
......@@ -119,7 +116,7 @@ def draw_net_bar(fname, outfname=None):
try:
values = rrdtool.fetch(fname, "AVERAGE")[2][-20:]
except rrdtool.error, e:
except rrdtool.error:
values = [(0.0, 0.0)]
v = [x for x in values if x[0] is not None and x[1] is not None]
......@@ -175,7 +172,7 @@ def draw_cpu_ts(fname, outfname):
#"-t", "CPU usage",
"-v", "%",
#"--lazy",
"DEF:cpu=%s:ns:AVERAGE" % fname,
"DEF:cpu=%s:value:AVERAGE" % fname,
"LINE1:cpu#00ff00:")
return read_file(outfname)
......@@ -189,7 +186,7 @@ def draw_cpu_ts_w(fname, outfname):
#"-t", "CPU usage",
"-v", "%",
#"--lazy",
"DEF:cpu=%s:ns:AVERAGE" % fname,
"DEF:cpu=%s:value:AVERAGE" % fname,
"LINE1:cpu#00ff00:")
return read_file(outfname)
......@@ -200,17 +197,17 @@ def draw_net_ts(fname, outfname):
outfname += "-net.png"
rrdtool.graph(outfname, "-s", "-1d", "-e", "-20s",
"--units", "si",
"-v", "Bits/s",
"COMMENT:\t\t\tAverage network traffic\\n",
"DEF:rx=%s:rx:AVERAGE" % fname,
"DEF:tx=%s:tx:AVERAGE" % fname,
"CDEF:rxbits=rx,8,*",
"CDEF:txbits=tx,8,*",
"LINE1:rxbits#00ff00:Incoming",
"GPRINT:rxbits:AVERAGE:\t%4.0lf%sbps\t\g",
"LINE1:txbits#0000ff:Outgoing",
"GPRINT:txbits:AVERAGE:\t%4.0lf%sbps\\n")
"--units", "si",
"-v", "Bits/s",
"COMMENT:\t\t\tAverage network traffic\\n",
"DEF:rx=%s:rx:AVERAGE" % fname,
"DEF:tx=%s:tx:AVERAGE" % fname,
"CDEF:rxbits=rx,8,*",
"CDEF:txbits=tx,8,*",
"LINE1:rxbits#00ff00:Incoming",
"GPRINT:rxbits:AVERAGE:\t%4.0lf%sbps\t\g",
"LINE1:txbits#0000ff:Outgoing",
"GPRINT:txbits:AVERAGE:\t%4.0lf%sbps\\n")
return read_file(outfname)
......@@ -220,17 +217,17 @@ def draw_net_ts_w(fname, outfname):
outfname += "-net-weekly.png"
rrdtool.graph(outfname, "-s", "-1w", "-e", "-20s",
"--units", "si",
"-v", "Bits/s",
"COMMENT:\t\t\tAverage network traffic\\n",
"DEF:rx=%s:rx:AVERAGE" % fname,
"DEF:tx=%s:tx:AVERAGE" % fname,
"CDEF:rxbits=rx,8,*",
"CDEF:txbits=tx,8,*",
"LINE1:rxbits#00ff00:Incoming",
"GPRINT:rxbits:AVERAGE:\t%4.0lf%sbps\t\g",
"LINE1:txbits#0000ff:Outgoing",
"GPRINT:txbits:AVERAGE:\t%4.0lf%sbps\\n")
"--units", "si",
"-v", "Bits/s",
"COMMENT:\t\t\tAverage network traffic\\n",
"DEF:rx=%s:rx:AVERAGE" % fname,
"DEF:tx=%s:tx:AVERAGE" % fname,
"CDEF:rxbits=rx,8,*",
"CDEF:txbits=tx,8,*",
"LINE1:rxbits#00ff00:Incoming",
"GPRINT:rxbits:AVERAGE:\t%4.0lf%sbps\t\g",
"LINE1:txbits#0000ff:Outgoing",
"GPRINT:txbits:AVERAGE:\t%4.0lf%sbps\\n")
return read_file(outfname)
......@@ -243,14 +240,13 @@ def decrypt(secret):
return aes.decrypt(urlsafe_b64decode(secret)).rstrip('\x00')
available_graph_types = {
'cpu-bar': draw_cpu_bar,
'net-bar': draw_net_bar,
'cpu-ts': draw_cpu_ts,
'net-ts': draw_net_ts,
'cpu-ts-w': draw_cpu_ts_w,
'net-ts-w': draw_net_ts_w,
}
available_graph_types = {'cpu-bar': draw_cpu_bar,
'net-bar': draw_net_bar,
'cpu-ts': draw_cpu_ts,
'net-ts': draw_net_ts,
'cpu-ts-w': draw_cpu_ts_w,
'net-ts-w': draw_net_ts_w
}
@api_method(http_method='GET', token_required=False, user_required=False,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment