-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrawCountersMetrics.py
executable file
·173 lines (141 loc) · 5.75 KB
/
rawCountersMetrics.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
__author__="mcanuto"
__date__ ="$Feb 13, 2014 6:11:42 PM$"
#from subprocess import call, Popen
import subprocess
import re
import gmetric
import threading
from gmetric import GmetricConf
from time import sleep
from logging import handlers
import logging
import os
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
# create a file handler
handler = handlers.RotatingFileHandler('extraMetrics.log', maxBytes=1024*1024*10) #max size = 10 MB
handler.setLevel(logging.INFO)
# create a logging format
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
# add the handlers to the logger
logger.addHandler(handler)
raw_counters_filename = "host_raw_counters_events.data"
def check_pid(pid):
""" Check For the existence of a unix pid. """
try:
os.kill(int(pid), 0)
except OSError:
return False
else:
return True
def getPerfPath():
with open("extraMetrics.conf", 'r') as f:
for line in f:
if line.startswith('perf_tool'):
items = line.split("=")
key, value = items[0].strip(), items[1].strip()
if not value:
perf_cmd = 'perf'
else:
perf_cmd = value
return perf_cmd
class RawCountersMetrics:
def __init__(self, counters_directory, counters_interval, raw_counters_list, mconf, gconf, vm_pid, vm_name):
self.counters_interval = counters_interval
self.raw_counters_list = raw_counters_list
self.mconf = mconf
self.gconf = gconf
self.counters_directory = counters_directory
if vm_pid is None:
self.vm_pid = None
else:
self.vm_pid = vm_pid
if vm_name is not None:
self.vm_name = vm_name
else:
self.vm_name = None
self._stopevent = threading.Event()
def stopThreads(self):
logger.info("stopping threads...")
self._stopevent.set()
def collectCountersMetrics(self):
separator = '|'
vm_raw_counters_file = ""
perf_cmd = getPerfPath()
gmetric_obj = gmetric.Gmetric(self.gconf.host, self.gconf.port, self.gconf.protocol)
while not self._stopevent.isSet():
list_metrics = {}
# commands = [ "perf stat -a -e cpu-cycles sleep 1" ]
if self.vm_pid is None:
# get system wide counters metrics
raw_counters_file = self.counters_directory + raw_counters_filename
cmd = [perf_cmd + " stat -o "+ raw_counters_file +" -x "+ separator +" -a -e "+ self.raw_counters_list +" sleep "+ self.counters_interval]
try:
programs = [ subprocess.call(c.split()) for c in cmd ]
except Exception, e:
logger.error("%s",e)
# parse metrics
regex = re.compile("^[0-9.,]+")
with open(raw_counters_file) as f:
for line in f:
#print line
if re.match(regex, line.strip()):
a = line.split(separator)
list_metrics[a[1].strip()] = a[0].strip()
else:
# get raw counters metrics for the VM PID
if check_pid(self.vm_pid):
vm_raw_counters_file = self.counters_directory+ "raw_counters_events_"+ self.vm_name +".data"
cmd = [perf_cmd + " kvm stat -o "+ vm_raw_counters_file +" -x "+ separator +" -p "+ self.vm_pid +" -e "+ self.raw_counters_list +" sleep "+ self.counters_interval]
try:
programs = [ subprocess.call(c.split()) for c in cmd ]
except Exception, e:
logger.error("%s",e)
# parse metrics
regex = re.compile("^[0-9.,]+")
with open(vm_raw_counters_file) as f:
for line in f:
#print line
if re.match(regex, line.strip()):
a = line.split(separator)
list_metrics[a[1].strip()] = a[0].strip()
if vm_raw_counters_file:
try:
os.remove(vm_raw_counters_file)
except:
pass
else:
logger.info("Counters PID %s: %s has been destroyed", self.vm_pid, self.vm_name)
if vm_raw_counters_file:
try:
os.remove(vm_raw_counters_file)
except:
pass
break
#send metrics
self.sendCountersMetrics(list_metrics, gmetric_obj, self.vm_name)
def sendCountersMetrics(self, list_metrics, gmetric_obj, vm_name):
#send metric
if vm_name is not None:
logger.info("%s: sending VM (%s) Raw counters metrics", threading.currentThread().name, vm_name)
else:
logger.info("%s: sending host Raw counters metrics", threading.currentThread().name)
for key,value in list_metrics.items():
if key in self.mconf:
if vm_name is not None:
n = vm_name +"." + self.mconf[key]["name"]
else:
n = self.mconf[key]["name"]
if self.mconf[key]["spoof"].lower() == "yes":
if vm_name is not None:
vm_group = "vm " + self.mconf[key]["group"]
gmetric_obj.send(n, value, self.mconf[key]["type"], self.mconf[key]["units"], self.gconf.slope, self.mconf[key]["tmax"], self.mconf[key]["dmax"], vm_group, self.gconf.spoof)
else:
gmetric_obj.send(n, value, self.mconf[key]["type"], self.mconf[key]["units"], self.gconf.slope, self.mconf[key]["tmax"], self.mconf[key]["dmax"], self.mconf[key]["group"], self.gconf.spoof)
else:
if vm_name is not None:
vm_group = "vm " + self.mconf[key]["group"]
gmetric_obj.send(n , value, self.mconf[key]["type"], self.mconf[key]["units"], self.gconf.slope, self.mconf[key]["tmax"], self.mconf[key]["dmax"], vm_group)
else:
gmetric_obj.send(n , value, self.mconf[key]["type"], self.mconf[key]["units"], self.gconf.slope, self.mconf[key]["tmax"], self.mconf[key]["dmax"], self.mconf[key]["group"])