]>
Commit | Line | Data |
---|---|---|
ad51e17e | 1 | #!/usr/bin/python2 |
0e4eed3a RM |
2 | # |
3 | ||
4 | # | |
5 | # Authors: | |
6 | # rafael@E-MC2.NET / https://e-mc2.net/ | |
7 | # | |
8 | # Copyright (c) 2018 USIT-University of Oslo | |
9 | # | |
10 | # zabbix_get_haproxy_stats.py is free software: you can | |
11 | # redistribute it and/or modify it under the terms of the GNU General | |
12 | # Public License as published by the Free Software Foundation, either | |
13 | # version 3 of the License, or (at your option) any later version. | |
14 | # | |
15 | # zabbix_get_haproxy_stats.py is distributed in the hope that it | |
16 | # will be useful, but WITHOUT ANY WARRANTY; without even the implied | |
17 | # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
18 | # See the GNU General Public License for more details. | |
19 | # | |
20 | # You should have received a copy of the GNU General Public License | |
21 | # along with sms_send. If not, see <http://www.gnu.org/licenses/>. | |
22 | # | |
23 | ||
24 | import os | |
25 | import sys | |
26 | import tempfile | |
27 | ||
28 | from io import StringIO | |
29 | import errno | |
30 | import socket | |
e272304d | 31 | import subprocess |
0e4eed3a RM |
32 | |
33 | # Zabbix proxy | |
34 | zabbix_proxy = ['zabbix-proxy-prod03.uio.no','zabbix-proxy-prod04.uio.no'] | |
35 | ||
36 | # Path to zabbix_sender | |
37 | zabbix_sender = '/usr/bin/zabbix_sender' | |
38 | ||
39 | # Temp file with full json output | |
40 | tmp_stat_file = tempfile.NamedTemporaryFile(delete=False,dir='/tmp') | |
41 | ||
42 | # Socket parameters | |
43 | SOCKET_HOSTNAME = socket.gethostname() | |
44 | SOCKET_BUFFER_SIZE = 1024 | |
45 | SOCKET_PATH = "/var/lib/haproxy/stats" | |
46 | ||
47 | parameters = "pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,comp_in,comp_out,comp_byp,comp_rsp,lastsess,last_chk,last_agt,qtime,ctime,rtime,ttime".split(",") | |
48 | ||
49 | ||
50 | # ############################################ | |
51 | # get_haproxy_stats_data() | |
52 | # ############################################ | |
53 | ||
54 | def get_haproxy_stats_data(command): | |
55 | ||
56 | try: | |
57 | ||
58 | sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) | |
59 | sock.connect(SOCKET_PATH) | |
60 | ||
61 | sock.sendall((command + "\n").encode()) | |
62 | buff = StringIO() | |
63 | ||
64 | while True: | |
65 | chunk = sock.recv(SOCKET_BUFFER_SIZE) | |
66 | ||
67 | if chunk: | |
68 | buff.write(chunk.decode("ascii")) | |
69 | else: | |
70 | break | |
71 | ||
72 | sock.close() | |
73 | ||
74 | response = buff.getvalue() | |
75 | buff.close() | |
76 | ||
77 | return response.rstrip("\n") | |
78 | ||
79 | except Exception as e: | |
80 | raise Exception("[ERROR]: %s\n" % e) | |
81 | ||
82 | ||
83 | # ############################################ | |
84 | # generate_zabbix_autodiscovery() | |
85 | # ############################################ | |
86 | ||
87 | def generate_zabbix_sender_data(stats): | |
88 | ||
89 | try: | |
90 | ||
91 | result = "" | |
92 | ||
93 | lines = stats.split("\n") | |
a1192166 RM |
94 | |
95 | # Generate a dynamic list with all the metrics delivered by | |
96 | # haproxy stats | |
97 | ||
98 | lines[0] = lines[0].replace("# ","") | |
0e4eed3a RM |
99 | fields = lines.pop(0).split(",") |
100 | ||
101 | for line in lines: | |
102 | values = line.split(",") | |
103 | ||
0e4eed3a RM |
104 | if values[1] == 'FRONTEND': |
105 | ||
106 | for loop in xrange(2,len(values)-1): | |
107 | if values[loop] != '': | |
a1192166 | 108 | result += SOCKET_HOSTNAME + " haproxy.frontend.stats[" + values[0] + "," + fields[loop] + "] " + values[loop] + "\n" |
0e4eed3a RM |
109 | |
110 | if values[1] == 'BACKEND': | |
111 | ||
112 | for loop in xrange(2,len(values)-1): | |
113 | if values[loop] != '': | |
a1192166 | 114 | result += SOCKET_HOSTNAME + " haproxy.backend.stats[" + values[0] + "," + fields[loop] + "] " + values[loop] + "\n" |
0e4eed3a RM |
115 | |
116 | if values[1] not in ['FRONTEND','BACKEND']: | |
117 | ||
118 | for loop in xrange(2,len(values)-1): | |
119 | if values[loop] != '': | |
a1192166 | 120 | result += SOCKET_HOSTNAME + " haproxy.server.stats[" + values[0] + "/" + values[1] + "," + fields[loop] + "] " + values[loop] + "\n" |
0e4eed3a RM |
121 | |
122 | ||
123 | return result | |
124 | ||
125 | except Exception as e: | |
126 | raise Exception("[ERROR]: %s\n" % e) | |
127 | ||
128 | ||
129 | if __name__ == '__main__': | |
130 | ||
131 | try: | |
132 | ||
133 | stats = get_haproxy_stats_data("show stat") | |
134 | result = generate_zabbix_sender_data(stats) | |
135 | ||
136 | # | |
137 | # We create a file with the data that zabbix_sender will | |
138 | # send in a bulk execution. | |
139 | # | |
140 | ||
141 | with open(tmp_stat_file.name,'w') as f: | |
142 | f.write(result) | |
a1192166 | 143 | |
0e4eed3a RM |
144 | # |
145 | # The monitoring of this host can be done by any of the | |
e272304d | 146 | # zabbix proxies defined in zabbix_proxy[]. We try all of |
0e4eed3a RM |
147 | # them until one of them accepts our data |
148 | # | |
149 | ||
150 | for proxy in zabbix_proxy: | |
0e4eed3a | 151 | |
e272304d RM |
152 | command = zabbix_sender + ' -z ' + proxy + ' -i ' + tmp_stat_file.name + ' > /dev/null 2>&1' |
153 | ||
154 | proc = subprocess.Popen([command],shell=True) | |
155 | proc.wait() | |
156 | ||
157 | if proc.returncode == 0: | |
0e4eed3a | 158 | break |
0e4eed3a | 159 | |
0e4eed3a RM |
160 | # Delete temp file with zabbix_sender data |
161 | os.remove(tmp_stat_file.name) | |
a1192166 | 162 | |
0e4eed3a RM |
163 | # Return value 0 = execution OK |
164 | print("0") | |
165 | ||
166 | except Exception, e: | |
167 | print("1") | |
168 | sys.exit(1) |