-
Notifications
You must be signed in to change notification settings - Fork 16
/
graphite.py
executable file
·135 lines (103 loc) · 3.79 KB
/
graphite.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
#!/usr/bin/env python
import sys
import urllib
# Alert off of Graphite metrics.
REVERSE = True # Alert when the value is UNDER warn/crit instead of OVER'
HW = False
CRIT = 23000
WARN = 24000
CRITUPPER = ''
CRITLOWER = ''
DIFF1 = ''
DIFF2 = ''
SECONDS = 60
URL = ''
# Nagios exit codes
STATE_OK = 0
STATE_WARNING = 1
STATE_CRITICAL = 2
STATE_UNKNOWN = 3
STATE_DEPENDENT = 4
def pull_graphite_data(url):
"""Pull down raw data from Graphite"""
# Make sure the url ends with '&rawData'
if not url.endswith('&rawData'):
url += '&rawData'
data = urllib.urlopen(url).read()
return data
def eval_graphite_data(data, seconds):
"""Get the most recent correct value from the data"""
sample_period = int(data.split('|')[0].split(',')[-1])
all_data_points = data.split('|')[-1].split(',')
# Evaluate what graphite returned, should either be a float, or None
# First, if the number of seconds of data we want to examine is smaller or
# equals the graphite sample period, just grab the latest data point.
# If that data point is None, grab the one before it.
# If that is None too, return 0.0.
if seconds <= sample_period:
if eval(all_data_points[-1]):
data_value = float(all_data_points[-1])
elif eval(all_data_points[-2]):
data_value = float(all_data_points[-2])
else:
data_value = 0.0
else:
# Second, if we requested more than on graphite sample period, work out how
# many sample periods we wanted (python always rounds division *down*)
data_points = (seconds / sample_period)
data_set = [float(x) for x in all_data_points[-data_points:]
if eval(x)]
if data_set:
data_value = float(sum(data_set) / len(data_set))
else:
data_value = 0.0
return data_value
def get_hw_value(url, seconds=0):
"""Get the Holt-Winters value from a Graphite graph"""
data = pull_graphite_data(url)
for line in data.split():
if line.startswith('holtWintersConfidenceUpper'):
graphite_upper = eval_graphite_data(line, seconds)
elif line.startswith('holtWintersConfidenceLower'):
graphite_lower = eval_graphite_data(line, seconds)
else:
graphite_data = eval_graphite_data(line, seconds)
return graphite_data, graphite_lower, graphite_upper
def get_value(url, seconds=0):
"""Get the value from a Graphite graph"""
data = pull_graphite_data(url)
data_value = eval_graphite_data(data, seconds)
return data_value
def main():
if HW:
graphite_data, graphite_lower, graphite_upper = get_hw_value(URL, SECONDS)
print 'Current value: %s, lower band: %s, upper band: %s' % (graphite_data, graphite_lower, graphite_upper)
if (graphite_data > graphite_upper) or (graphite_data < graphite_lower):
if CRITUPPER or CRITLOWER:
sys.exit(STATE_CRITICAL)
else:
sys.exit(STATE_WARNING)
else:
sys.exit(STATE_OK)
if DIFF1:
graphite_data1 = get_value(DIFF1, SECONDS)
graphite_data2 = get_value(DIFF2, SECONDS)
graphite_data = abs(graphite_data1 - graphite_data2)
else:
graphite_data = get_value(URL, SECONDS)
print 'Current value: %s, warn threshold: %s, crit threshold: %s | hubs=%s' % (graphite_data, WARN, CRIT, graphite_data)
if REVERSE is True:
if CRIT >= graphite_data:
sys.exit(STATE_CRITICAL)
elif WARN >= graphite_data:
sys.exit(STATE_WARNING)
else:
sys.exit(STATE_OK)
else:
if graphite_data >= CRIT:
sys.exit(STATE_CRITICAL)
elif graphite_data >= WARN:
sys.exit(STATE_WARNING)
else:
sys.exit(STATE_OK)
main()