-
Notifications
You must be signed in to change notification settings - Fork 15
/
check_es_insert.py
executable file
·161 lines (148 loc) · 6.9 KB
/
check_es_insert.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
#!/usr/bin/python
from __future__ import division
import sys,time,argparse
from elasticsearch import Elasticsearch
###CONSTANTS###
OK=0
WARNING=1
CRITICAL=2
UNKNOWN=3
###END CONSTANTS###
class Calculator():
'''This is our main class. It takes results from Elasticsearch and from what was previously recorded
and can give the text to be printed and the exit code'''
def __init__(self,warn,crit,myfile='/tmp/check_es_insert',myaddress='localhost:9200',threshold='lt',index='', minutes = False):
self.warn = warn
self.crit = crit
self.my_elasticsearcher = Elasticsearcher(address=myaddress)
self.my_disker = Disker(file=myfile)
self.threshold = threshold
self.index = index
self.minutes = minutes
def calculate(self,old_value,new_value,old_time,new_time):
'''Calculates the number of inserts per second or minute since the last recording'''
if self.minutes:
return (new_value - old_value)/(new_time - old_time) * 60
else:
return (new_value - old_value) / (new_time - old_time)
def getPrevious(self):
'''Gets the previously recorded number of documents and UNIX time'''
try:
previous = self.my_disker.getPrevious()
except:
#-2 is an error code. In case shit goes wrong while accessing the file
return (-2,0)
#return the result and time
return (previous[0],previous[1])
def getCurrent(self):
'''Gets current number of documents and current UNIX time'''
try:
current_result = self.my_elasticsearcher.getCurrent(self.index)
except:
#-1 is an error code. In case shit goes wrong while interrogating Elasticsearch
return (-1,0)
current_time = timer()
return (current_result,current_time)
def printandexit(self,result):
'''Given the number of inserts per second, it gives the formatted text and the exit code'''
if self.minutes:
text="Number of documents inserted per minute (index: %s) is %f | 'es_insert'=%f;%d;%d;;" % (self.index if self.index != '' else 'all', result,result,self.warn,self.crit)
else:
text = "Number of documents inserted per second (index: %s) is %f | 'es_insert'=%f;%d;%d;;" % (self.index if self.index != '' else 'all', result, result, self.warn, self.crit)
if self.threshold == 'lt':
if result<self.warn:
return (text,OK)
if result<self.crit:
return (text,WARNING)
else:
return (text,CRITICAL)
elif self.threshold == 'gt':
if result<self.crit:
return (text,CRITICAL)
if result<self.warn:
return (text,WARNING)
else:
return (text,OK)
else:
return ('Unknown threshold value',UNKNOWN)
def run(self):
'''This does everything, and returns the text to be printed and the exit code'''
#get the current number of documents and time
(new_value, new_time) = self.getCurrent()
#check if the result is a known error code
if new_value == -1:
text = "There was an issue getting the status - and number of docs - from Elasticsearch. Check that ES is running and you have elasticsearch python module installed"
return (text,UNKNOWN)
#get the previous number of documents and time
(old_value, old_time) = self.getPrevious()
#if the new value could be retrieved, try to write it to a file
try:
self.my_disker.writeCurrent(new_value,new_time)
except:
#if that failed, return UNKNOWN
text = "There was an issue writing the current results to file."
return (text,UNKNOWN)
#check if the old value result is a known error code
if old_value == -2:
text = "There was an issue getting the previous results from file."
return (text,UNKNOWN)
result = self.calculate(old_value,new_value,old_time,new_time)
(text,exitcode) = self.printandexit(result)
return (text,exitcode)
def timer():
'''Interface for time.time(). Good for testing'''
return time.time()
def opener(file='/tmp/check_es_insert', mode="r"):
'''Interface for open(). Good for testing'''
return open(file,mode)
def printer(text):
'''interface for print()'''
print text
def exiter(code):
'''interface for exit()'''
exit(code)
class Disker():
def __init__(self,file='/tmp/check_es_insert'):
self.file = file
def getPrevious(self):
myfile = opener(self.file)
mydata = myfile.readline()
numdocs = int(mydata.split(" ")[0])
time = float(mydata.split(" ")[1])
return (numdocs,time)
def writeCurrent(self,value,time):
myfile = opener(self.file,"w")
myfile.write("%d %f" % (value,time))
class Elasticsearcher():
def __init__(self,address='localhost:9200'):
self.address = address
self.mysum = 0
def getCurrent(self, index=''):
(esaddress, esport) = self.address.split(':')
conn = Elasticsearch([{'host': esaddress, 'port': esport, 'timeout': 30}])
res = conn.search(index=index)
return res['hits']['total']
def getArgs(helptext):
'''Here's where we get our command line arguments'''
parser = argparse.ArgumentParser(description=helptext)
parser.add_argument('-c','--critical', type=float, help='Critical value', action='store',required=True)
parser.add_argument('-w','--warning', type=float, help='Warning value', action='store',required=True)
parser.add_argument('-t','--threshold', choices=['lt','gt'], type=str, help='Check result less than (lt) or greater than (gt) the warning/critcal values', action='store',default='lt')
parser.add_argument('-a','--address', type=str, help='Elasticsearch address', action='store',default='localhost:9200')
parser.add_argument('-i','--index', type=str, help='Elasticsearch index', action='store',default='')
parser.add_argument('-f','--file', type=str, help='Where to store gathered data', action='store',default='/tmp/check_es_insert')
parser.add_argument('-m','--minutes', help='Calc events by per minute', action='store_true' , default=False)
return vars(parser.parse_args())
def main():
'''The main function'''
cmdline = getArgs('Nagios plugin for checking the number of inserts per second in Elasticsearch')
if cmdline['file'] == '/tmp/check_es_insert' and cmdline['index'] != '':
cmdline['file'] = '/tmp/check_es_insert_' + cmdline['index']
#print cmdline
#exit()
my_calculator = Calculator(warn=cmdline['warning'],crit=cmdline['critical'],myfile=cmdline['file'],myaddress=cmdline['address'],threshold=cmdline['threshold'],index=cmdline['index'],minutes=cmdline['minutes'])
(text,exitcode) = my_calculator.run()
printer(text)
exiter(exitcode)
if __name__ == '__main__':
main()