]>
Commit | Line | Data |
---|---|---|
753b94ce | 1 | #!/usr/bin/env python |
d0022abf RM |
2 | # |
3 | # Authors: | |
4 | # rafael@postgresql.org.es / http://www.postgresql.org.es/ | |
5 | # | |
6 | # Copyright (c) 2016 USIT-University of Oslo | |
7 | # | |
8 | # zabbix_elasticsearch_cluster_health.py: Used by zabbix_agent to pull | |
9 | # elasticsearch cluster health information from an ES cluster and send | |
10 | # this information to Zabbix via trappers. | |
11 | # | |
12 | # zabbix_elasticsearch_cluster_health.py is free software: you can | |
13 | # redistribute it and/or modify it under the terms of the GNU General | |
14 | # Public License as published by the Free Software Foundation, either | |
15 | # version 3 of the License, or (at your option) any later version. | |
16 | # | |
17 | # zabbix_elasticsearch_cluster_health.py is distributed in the hope | |
18 | # that it will be useful, but WITHOUT ANY WARRANTY; without even the | |
19 | # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |
20 | # PURPOSE. See the GNU General Public License for more details. | |
21 | # | |
22 | # You should have received a copy of the GNU General Public License | |
23 | # along with sms_send. If not, see <http://www.gnu.org/licenses/>. | |
24 | # | |
25 | ||
26 | # | |
27 | # This script gets ES cluster health information from the ES rest API, | |
28 | # extracts the parameters we have defined in health_keys{} and sends | |
29 | # data back to zabbix via zabbix_sender to defined trap-items. | |
30 | # | |
31 | # The script is executed via zabbix_agent and is defined in an | |
32 | # UserParameter that will return 0 (execution OK) or 1 (execution | |
33 | # ERROR) so zabbix can register if it cannot get data from ES. | |
34 | # | |
35 | # UserParameter=get.es.cluster.health[*],/usr/bin/zabbix_elasticsearch_cluster_health.py $1 | |
36 | # | |
37 | ||
38 | import requests | |
39 | import json | |
40 | import sys | |
41 | import os | |
42 | import time | |
43 | import tempfile | |
44 | ||
45 | # Zabbix proxy | |
b5316abe | 46 | zabbix_proxy = ['zabbix-proxy-prod03.uio.no','zabbix-proxy-prod04.uio.no'] |
d0022abf RM |
47 | |
48 | # Path to zabbix_sender | |
49 | zabbix_sender = '/usr/bin/zabbix_sender' | |
50 | ||
51 | # Temp file with full json output | |
52 | tmp_stat_file = tempfile.NamedTemporaryFile(delete=False,dir='/tmp') | |
53 | ||
54 | ||
55 | # Item prefix | |
56 | item_prefix = 'es.cluster.' | |
57 | ||
58 | # keys for health page | |
59 | health_keys = { | |
60 | "cluster_name", | |
61 | "status", | |
62 | "timed_out", | |
63 | "number_of_nodes", | |
64 | "number_of_data_nodes", | |
65 | "active_primary_shards", | |
66 | "active_shards", | |
67 | "relocating_shards", | |
68 | "initializing_shards", | |
69 | "unassigned_shards", | |
70 | "delayed_unassigned_shards", | |
71 | "number_of_pending_tasks", | |
72 | "number_of_in_flight_fetch", | |
73 | "task_max_waiting_in_queue_millis", | |
74 | "active_shards_percent_as_number" | |
75 | } | |
76 | ||
77 | # ############################################ | |
78 | # getKeys() | |
79 | # ############################################ | |
80 | ||
81 | def getKeys(json_data,keys,node_fqdn): | |
82 | result='' | |
83 | ||
84 | for key in keys: | |
85 | attributes=key.split('.') | |
86 | value=json_data | |
87 | ||
88 | for index in range(len(attributes)): | |
89 | value=value.get(attributes.pop(0),{}) | |
90 | ||
91 | if value=={}: | |
92 | continue | |
93 | ||
94 | result += node_fqdn + ' ' + item_prefix + "{0} {1}\n".format(key,value) | |
95 | ||
96 | return result | |
97 | ||
98 | ||
99 | # ############################################ | |
100 | # get_cluster_health_data() | |
101 | # ############################################ | |
102 | ||
103 | def get_cluster_health_data(node_fqdn): | |
104 | """ | |
105 | Get ES cluster health data | |
106 | """ | |
107 | ||
108 | ||
109 | try: | |
110 | request_data = requests.get("http://" + node_fqdn + ":9200/_cluster/health") | |
111 | health_data = request_data.json() | |
112 | ||
113 | result = getKeys(health_data,health_keys,node_fqdn) | |
114 | ||
753b94ce RMG |
115 | except Exception as e: |
116 | print ("1") | |
d0022abf RM |
117 | sys.exit(1) |
118 | ||
119 | return result | |
120 | ||
121 | # ############################################ | |
122 | # Main | |
123 | # ############################################ | |
124 | ||
125 | if __name__ == '__main__': | |
126 | ||
127 | try: | |
128 | ||
129 | if len(sys.argv) == 2: | |
130 | ||
131 | node_fqdn = sys.argv[1].lower() | |
132 | result = get_cluster_health_data(node_fqdn) | |
133 | ||
134 | # | |
135 | # We create a file with the data that zabbix_sender will | |
136 | # send in a bulk execution. | |
137 | # | |
138 | ||
139 | with open(tmp_stat_file.name,'w') as f: | |
140 | f.write(result) | |
141 | ||
142 | # | |
143 | # The monitoring of this host can be done by any of the | |
144 | # zabbix proxyer defined in zabbix_proxy[]. We try all of | |
145 | # them until one of them accepts our data | |
146 | # | |
147 | ||
148 | for proxy in zabbix_proxy: | |
149 | returncode = os.system(zabbix_sender + ' -z ' + proxy + ' -i ' + tmp_stat_file.name + ' > /dev/null 2>&1') | |
150 | ||
151 | if returncode == 0: | |
152 | break | |
153 | ||
154 | if returncode != 0: | |
753b94ce | 155 | print ("1") |
d0022abf RM |
156 | sys.exit(1) |
157 | ||
158 | else: | |
753b94ce | 159 | print ("1") |
d0022abf RM |
160 | sys.exit(1) |
161 | ||
753b94ce RMG |
162 | except Exception as e: |
163 | print ("1") | |
d0022abf RM |
164 | sys.exit(1) |
165 | ||
166 | # Delete temp file with zabbix_sender data | |
167 | os.remove(tmp_stat_file.name) | |
168 | ||
169 | # Return value 0 = execution OK | |
753b94ce | 170 | print ("0") |