-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmetric.py.bak
147 lines (126 loc) · 5 KB
/
metric.py.bak
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
# coding=utf-8
import time
import re
import logging
from error import DiamondException
class Metric(object):
_METRIC_TYPES = ['COUNTER', 'GAUGE']
def __init__(self, path, value, raw_value=None, timestamp=None, precision=0,
host=None, metric_type='COUNTER', ttl=None):
"""
Create new instance of the Metric class
Takes:
path=string: string the specifies the path of the metric
value=[float|int]: the value to be submitted
timestamp=[float|int]: the timestamp, in seconds since the epoch
(as from time.time()) precision=int: the precision to apply.
Generally the default (2) should work fine.
"""
# Validate the path, value and metric_type submitted
if (None in [path, value] or metric_type not in self._METRIC_TYPES):
raise DiamondException(("Invalid parameter when creating new "
"Metric with path: %r value: %r "
"metric_type: %r")
% (path, value, metric_type))
# If no timestamp was passed in, set it to the current time
if timestamp is None:
timestamp = int(time.time())
else:
# If the timestamp isn't an int, then make it one
if not isinstance(timestamp, int):
try:
timestamp = int(timestamp)
except ValueError, e:
raise DiamondException(("Invalid timestamp when "
"creating new Metric %r: %s")
% (path, e))
# The value needs to be a float or an int. If it is, great. If not,
# try to cast it to one of those.
if not isinstance(value, (int, float)):
try:
if precision == 0:
value = round(float(value))
else:
value = float(value)
except ValueError, e:
raise DiamondException(("Invalid value when creating new "
"Metric %r: %s") % (path, e))
self.path = path
self.value = value
self.raw_value = raw_value
self.timestamp = timestamp
self.precision = precision
self.host = host
self.metric_type = metric_type
self.ttl = ttl
def __repr__(self):
"""
Return the Metric as a string
"""
if not isinstance(self.precision, (int, long)):
log = logging.getLogger('diamond')
log.warn('Metric %s does not have a valid precision', self.path)
self.precision = 0
# Set the format string
fstring = "%%s %%0.%if %%i\n" % self.precision
# Return formated string
return fstring % (self.path, self.value, self.timestamp)
@classmethod
def parse(cls, string):
"""
Parse a string and create a metric
"""
match = re.match(r'^(?P<name>[A-Za-z0-9\.\-_]+)\s+'
+ '\(?P<value>[0-9\.]+)\s+'
+ '(?P<timestamp>[0-9\.]+)(\n?)$',
string)
try:
groups = match.groupdict()
# TODO: get precision from value string
return Metric(groups['name'],
groups['value'],
float(groups['timestamp']))
except:
raise DiamondException(
"Metric could not be parsed from string: %s." % string)
def getPathPrefix(self):
"""
Returns the path prefix path
servers.host.cpu.total.idle
return "servers"
"""
# If we don't have a host name, assume it's just the first part of the
# metric path
if self.host is None:
return self.path.split('.')[0]
offset = self.path.index(self.host) - 1
return self.path[0:offset]
def getCollectorPath(self):
"""
Returns collector path
servers.host.cpu.total.idle
return "cpu"
"""
# If we don't have a host name, assume it's just the third part of the
# metric path
if self.host is None:
return self.path.split('.')[2]
offset = self.path.index(self.host)
offset += len(self.host) + 1
endoffset = self.path.index('.', offset)
return self.path[offset:endoffset]
def getMetricPath(self):
"""
Returns the metric path after the collector name
servers.host.cpu.total.idle
return "total.idle"
"""
# If we don't have a host name, assume it's just the fourth+ part of the
# metric path
if self.host is None:
path = self.path.split('.')[3:]
return '.'.join(path)
prefix = '.'.join([self.getPathPrefix(), self.host,
self.getCollectorPath()])
offset = len(prefix) + 1
return self.path[offset:]