]> git.uio.no Git - uio-zabbix.git/blame - zabbix_elk_container.py
Add zabbix autodiscovery script for rabbitmq
[uio-zabbix.git] / zabbix_elk_container.py
CommitLineData
bfda2ced
MO
1#!/usr/bin/env python
2#
3# Authors:
4# Mustafa Ocak
5# muo@uio.no
6#
7# Copyright (c) 2016 USIT-University of Oslo
8#
9# zabbix_elk_container.py: Used by zabbix_agent to pull kibana and logstash
10# service information from consul key-value db.
11# Service information from consul is used to low-level discovery of logstash
12# instanses and building url of kibana instanses.
13# Logstash instanses are monitored by net.tcp.service and Kibana web services
14# are monitored by this script.
15#
16# zabbix_elk_container.py is free software: you can
17# redistribute it and/or modify it under the terms of the GNU General
18# Public License as published by the Free Software Foundation, either
19# version 3 of the License, or (at your option) any later version.
20#
21# zabbix_elk_container.py is distributed in the hope
22# that it will be useful, but WITHOUT ANY WARRANTY; without even the
23# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
24# PURPOSE. See the GNU General Public License for more details.
25#
26# You should have received a copy of the GNU General Public License
27# along with sms_send. If not, see <http://www.gnu.org/licenses/>.
28#
29
30import requests
31import re
32import json
33import socket
34import sys
35
36
37
38# ##########################################################
39# Getting the list of all the services registred in consul.
40# ##########################################################
41
42def get_services(consul_catalog_url):
43
44 # list of all the registred services in consul
45 servicefqdnlist=[]
46
47 try:
48 response = requests.get(consul_catalog_url)
49
50 if (response.status_code == 200):
51 jsonout=response.json()
52 for servicename_fqdn in jsonout:
53
54 # finding all the logstash service fqdn entries.
55 matchobj = re.search(r'logstash',servicename_fqdn,re.IGNORECASE)
56 if (matchobj):
57 servicefqdnlist.append(servicename_fqdn)
58 return servicefqdnlist
59 except Exception as e:
60 print e
61 sys.exit(1)
62
63# ##########################################################
64# Getting the list of all the logowners registred in consul.
65# ##########################################################
66
67def get_logowners (consul_kv_url,servicetype):
68 '''
69 Get logowners from consul. Consul url structure is as follows:
70 http://localhost:8500/v1/kv/uio-elk/services/<servicetype>/<logowner>
71 '''
72 logowners=[]
73 try:
74 response = requests.get(consul_kv_url+servicetype+'?recurse')
75 if (response.status_code == 200):
76 jsonout = response.json()
77 for jsonelement in jsonout:
78
79 # jsonelement['Key']= "uio-elk/services/kibana/usit-gid/host"
80 # value[3]="usit-gid"
81 value = jsonelement['Key'].split("/")
82 if value[3] not in logowners:
83 logowners.append(value[3])
84 return logowners
85 except Exception as e:
86 print e
87 sys.exit(1)
88
89# ######################################################################
90# Get list of all logstash instanses for low-level discovery in zabbix.
91# ######################################################################
92
93def get_logstash_instanses (consul_kv_url,servicetype,servicefqdnlist,logowners):
94 '''
95 Pipelines for windows logs are as follows
96
97 --> |nxlog-server|--> |logstash-instanse| --> |ELK|
98 or
99 --> |logstash-instanse| --> |ELK|
100
101 This function finds whether there is a nxlog-server or not in front of logstash-instanse
102 and builds a list of dictionary
103
104 logstash_instanse = {
105 'logowner':..,
106 'type':..,
107 'service':..,
108 'port':..,
109 'host':..,
110 'nxlog':true|false
111 }
112 logstash_service_list = [ logstash_instanse,...]
113 '''
114
115 serviceadded=[]
116 logstash_lld=[]
117
118 try:
119
120 for logowner in logowners:
121 response = requests.get(consul_kv_url+servicetype+'/'+logowner+'?recurse')
122 nxlog = "false"
123
124 if response.status_code == 200:
125 jsonout = response.json()
126 for jsonelement in jsonout:
127 templist=[]
128
129 # uio-elk/services/logstash/usit-gsd/tcp/host
130 # value[4] = "tcp"
131
132 value = jsonelement['Key'].split("/")
133 host = requests.get(consul_kv_url+servicetype+'/'+logowner+'/'+value[4]+'/host?raw')
134 port = requests.get(consul_kv_url+servicetype+'/'+logowner+'/'+value[4]+'/port?raw')
135
136 #
137 # Find out logstash instanses which has a nxlog-server in front.
138 # nxlog=true if not false.
139 #
140
141 for servicefqdn in servicefqdnlist:
142 matchobj = re.search(value[3]+'-nxlog-tcp',servicefqdn,re.IGNORECASE)
143 if matchobj:
144 nxlog="true"
145 fqdn=servicefqdn+".service.consul"
146 templist.append(fqdn)
147 fqdn = host.text+"-"+value[3]+"-"+value[4]+".service.consul"
148 if fqdn not in serviceadded:
149 templist.append(fqdn)
150
151 logstash_instanse = {'logowner':value[3],'type':value[4],'service':templist,'port':port.text,'host':host.text,'nxlog':nxlog}
152 logstash_lld.append(logstash_instanse)
153 serviceadded = serviceadded+templist
154 templist=[]
155 nxlog="false"
156
157 return logstash_lld
158
159 except Exception as e:
160 print e
161 sys.exit(1)
162
163# #########################
164# Monitor kibana instanses
165# #########################
166
167def monitor_kibana_instanse(kibanaurl):
168 '''
169 If http response status code is 200 and responce content have
170 key words like "Username" and "Password" then the web service is
171 considered up.
172 status
173 0 for UP
174 1 for DOWN
175 is returned.
176 '''
177 status=1
178 try:
179 response = requests.get(kibanaurl)
180 if (response.status_code == 200):
181 if (re.search("username",response.content,re.IGNORECASE)):
182 if (re.search("password",response.content,re.IGNORECASE)):
183 status = 0
184 else:
185 status = 1
186 else:
187 status = 1
188 else:
189 status = 1
190 return status
191 except Exception as e:
192 print e
193 sys.exit(1)
194
195def print_usage():
196 print "Error: Wrong number of parameters"
197 print 'Format: ' + sys.argv[0] + ' logstashlld'
198 print 'Format: ' + sys.argv[0] + ' kibanalld'
199 print 'Format: ' + sys.argv[0] + ' <kibana_url> monitorkibana'
200
201def print_zabbix_lld_json(lld_data):
202 '''
203 Print low level discovery json for Zabbix
204 '''
205
206 zabbixstr = { "data":lld_data}
207
208 zabbixjson = json.dumps(zabbixstr, indent=4, sort_keys=True)
209 print zabbixjson
210
211
212# ############################################
213# Main
214# ############################################
215
216if __name__ == '__main__':
217
218 consul_catalog_url="http://localhost:8500/v1/catalog/services?recurse"
219 consul_kv_url="http://localhost:8500/v1/kv/uio-elk/services/"
220
221 lld_data=[]
222
223 #
224 # find which machine the script is running on
225 #
226
227 machine = socket.gethostname()
228 machinename = machine.split(".")[0]
229
230 if len(sys.argv) == 2:
231
232 # ###############################
233 # Logstash low level discovery
234 # ###############################
235
236 if sys.argv[1] == "logstashlld":
237 servicetype = "logstash"
238 servicefqdnlist = get_services(consul_catalog_url)
239 logowners = get_logowners(consul_kv_url,servicetype)
240 logstash_lld = get_logstash_instanses (consul_kv_url,servicetype,servicefqdnlist,logowners)
241 for logstashinstanse in logstash_lld:
242
243 if logstashinstanse['nxlog'] == "true":
244 for k in logstashinstanse['service']:
245 matchobj = re.search('nxlog',k,re.IGNORECASE)
246 if matchobj:
247 containerfqdn = k
248 containerport = logstashinstanse['port']
249 else:
250 containerfqdn = logstashinstanse['service'][0]
251 containerport = logstashinstanse['port']
252
253 # ##############################################################
254 # Get only the containers running on the machine where this
255 # script is run.
256 # ##############################################################
257
258 matchobj = re.search(machinename,containerfqdn,re.IGNORECASE)
259 if matchobj:
260 containerdic = {"{#CONTAINER}":containerfqdn,"{#CONTAINER_PORT}":containerport}
261 lld_data.append(containerdic)
262
263 print_zabbix_lld_json(lld_data)
264
265 # ###############################
266 # Kibana low level discovery
267 # ###############################
268
269 elif sys.argv[1] == "kibanalld":
270
271 servicetype = "kibana"
272 logowners = get_logowners(consul_kv_url,servicetype)
273 for logowner in logowners:
274
275 host = requests.get(consul_kv_url+servicetype+'/'+logowner+'/host?raw')
276
277 # ##############################################################
278 # Get only the kibana containers running on the machine
279 # where this script is run.
280 # ##############################################################
281
282 if (host.text.lower() == machinename.lower()):
283 kibanaurl = "https://"+logowner+".logs.uio.no"
284 kibanadic = {"{#KIBANAURL}":kibanaurl}
285 lld_data.append(kibanadic)
286
287 print_zabbix_lld_json(lld_data)
288 else:
289 print_usage()
290
291 # ###############################
292 # Kibana monitoring
293 # ###############################
294
295 elif len(sys.argv) == 3:
296 if sys.argv[2] == "monitorkibana":
297 kibanaurl = sys.argv[1]
298 status=monitor_kibana_instanse(kibanaurl)
299 print status
300 else:
301 print_usage()
302
303 else:
304 print_usage()