A description of the application scenario:
The front-end uses tengine as the load balancer, which requires monitoring the health of the Tengine to the backend server, using the interface provided by the Tengine to get the status of each backend host, whether up or down.
Two writing Zabbix monitoring scripts
The Tengine ngx_http_upstream_check_module module provides back-end monitoring and inspection capabilities. Back-end host status can be viewed using Html,csv,json three formats, where we use JSON format for scripting purposes
/status?format=html/status?format=csv/status?format=json
{"Servers": {"Total": 1, "Generation": 3, "server": [{"index": 0, "upstream": "Backend", "name": "106.187.48.116:80", " Status ":" Up "," Rise ":" Fall ": 0," type ":" http "," Port ": 80}]}}
tengine_status.py
#!/usr/bin/env /usr/bin/python ' curl 127.0.0.1/up_status?format=json ' Import jsonimport optparseimport socketimport urllib2import subprocessimport tempfileimport osimport logginglogging.basicconfig (filename= '/opt/logs/ Zabbix/tengine_zabbix.log ', level=logging. warning, format= '% (asctime) s % (levelname) s: % (message) s ') #logging. Basicconfig (filename= '/tmp/ Tengine_zabbix.log ', level=logging.info, format= '% (asctime) s % (levelname) s: % (message) s ') Class tengine (object): "Class for tengine management api" def __init__ (self,host_name= ', conf= '/opt/app/zabbix/conf/zabbix_agentd.conf ', senderhostname=none): self.host_name = host_ Name or socket.gethostname () self.conf = conf or '/opt/app/zabbix/conf/zabbix_agentd.conf ' self.senderhostname = senderhostname if senderhostname else Host_name def call_api (self,tmpfile=none,write= ' no '): ##### change url here url = ' Http://127.0.0.1/up_status?format=json ' Logging.debug (' Get tengine upstream status ') up_ Status=json.loads (Urllib2.urlopen (URL). Read ()) upstreams = [] for upserver in up_status[' Servers ' [' Server ']: logging.debug ("Discovered upserver " + upserver[' upstream '] + upserver[' name '] + str (upserver[' index ')) element = {' {#UPSTREAM} ': upserver[' Upstream '], ' {#UPNAME} ': upserver[' name '], ' { #UPINDEX} ': upserver[' index '] } upstreams.append (Element) if write is ' yes ' and tmpfile is not None: for item in [ ' status ', ' Rise ', ' fall ', ' type ' ]: key = ' tengine.upstream_status[{0},{1},{2},{3}] '. Format (upserver[' index '], upserver[' upstream '], upserver[' name '],item) value = upserver[item] #print key + ":" + str (value) logging.debug ("SENDER_DATA: - %s %s " % (key,value) tmpfile.write ("- %s %s\n" % (key, value)) &nBSP; #print upstreams return upstreams def check_data (self): return_code = 0 #### use tempfile module to Create a file on memory, will not be deleted when it is closed , because ' Delete ' argument is set to False rdatafile = tempfile. Namedtemporaryfile (Delete=false) self.call_api (rdatafile,write= ' Yes ') rdatafile.close () return_code = self._send_status_data (Rdatafile) #### os.unlink is used to remove a file os.unlink (Rdatafile.name) return return_code def _send_status_data (Self, tmpfile): "Send the status data to zabbix. " ' Get key value from temp file. ' args = '/opt/app/zabbix/sbin/zabbix_sender -c {0} -i {1} ' if self.senderhostname : args = args + " -s " + self.senderhostname return_code = 0 process = subprocess. Popen (Args.format (self.conf, tmpfile.name), shell=true, stdout=subprocess. pipe, stderr=subprocess. PIPE) out, err = process.communicate () logging.debug ("Finished sending data") return_code = process.wait () logging.info ("found return code of " + str (reTurn_code)) if return_code != 0: logging.warning (out) logging.warning (ERR) Else: logging.debug (ERR) logging.debug (out) return return_codedef main (): choices=[' list_upservers ', ' Upstream_status '] parser = optparse. Optionparser () parser.add_option ('--hostname ', help= ' tengine server Hostname ', default=socket.gethostname ()) parser.add_option ('--conf ', default= '/opt/app/zabbix/conf/zabbix_agentd.conf ') parser.add_option ('--senderhostname ', default= ', help= ' Allows including a sender parameter on calls to zabbix_sender ') Parser.add_option ('--check ', type= ' Choice ', choices=choices,help= ' Type of check ') (Options, args) = parser.parse_args () logging.debug ("Started trying to process data ") if not options.check: parser.error (' At least one check should be specified ') logging.debug ("Started trying to process data") api = tengine (host_name=options.hostname,conf=options.conf, Senderhostname=options.senderhostname) if options.check == ' List_upservers ': print json.dumps ({' Data ': api.call_api (tmpfile=none,write= ' no ')},indent=4, Separators= (', ', ': ') elif options.check == ' Upstream_status ': print api.check_data () if __name__ == ' __main__ ': main ()
Tengine_status.conf
userparameter=tengine.discovery_upstream,/usr/bin/python/opt/app/zabbix/sbin/tengine_status.py--check= ' List_ Upservers ' userparameter=tengine.upstream_status[*],/usr/bin/python/opt/app/zabbix/sbin/tengine_status.py-- check= ' Upstream_status '
The URL of the script is modified according to its own situation, and the script uses Zabbix_sender to send the monitoring data, Zabbix_sender the host name that needs to be specified when sending the data and the host name of the monitored host on the Zabbix will be sent successfully.
If the parameter of the--check option is list_upservers, only the respective upstream backend hosts are listed, and the corresponding Zabbix key is Tengine.discovery_upstream
{ "Data":[ { "{#UPNAME}": "172.28.16.140:80", "{#UPSTREAM}": "Test", "{#UPINDEX}":0 }, { " {#UPNAME} ":" 172.28.16.143:80 ", " {# UPSTREAM} ":" Test ", " {#UPINDEX} ":1 }, { "{#UPNAME}": "172.28.16.144:80", "{#UPSTREAM}": "Test", "{#UPINDEX}":2 }, { "{#UPNAME}": " 172.28.16.158:80 ", " {#UPSTREAM} ":" Test " , "{#UPINDEX}":3 } ]}
If the--check parameter is Upstream_status, the key,value pair in a temporary file Rdatafile will be sent to Zabbix proxy or Zabbix server via Zabbix_sender. Note here that Zabbix_sender is not actively sending data past, need to have an action trigger Zabbix_sender will be sent, that is
/usr/bin/python/opt/app/zabbix/sbin/tengine_status.py--check= ' Upstream_status '
This execution requires timed task execution or trigger execution via Zabbix agent or Zabbix agent (active)
The various file paths in the script are modified according to their own circumstances.
Use a key of type Zabbix agent (active) in the template to execute the script on a regular basis, and the other monitoring data is escalated to Zabbix proxy or Zabbix server via Zabbix_sender
Tengine.upstream_status[send_data]
tengine.upstream_status[{#UPINDEX},{#UPSTREAM},{#UPNAME},fall]
tengine.upstream_status[{#UPINDEX},{#UPSTREAM},{#UPNAME},rise] |
tengine.upstream_status[{#UPINDEX},{#UPSTREAM},{#UPNAME},status]
tengine.upstream_status[{#UPINDEX},{#UPSTREAM},{#UPNAME},type] |
These key types are all Zabbix trapper
Add an alarm when the status value of the backend host is down
{Template tengine status:tengine.upstream_status[{#UPINDEX},{#UPSTREAM},{#UPNAME},status].str (down)}=1
When testing a script, it is best to use Zabbix_get to test Zabbix proxy on the latter Zabbix server
Zabbix_get-s 172.28.16.139-k Tengine.discovery_upstream
Returned data is OK Test succeeded
Zabbix_get-s 172.28.16.139-k Tengine.upstream_status[send_data]
A return value of 0 sends the data successfully, and the data can be viewed on the Zabbix page
A return value of 0 fails to send data, you need to check the Url,zabbix_sender,conf profile path in the script, log file permissions, host name matching, etc.
Three Production Zabbix monitor template
Templates See Accessories
Reference Documentation:
http://tengine.taobao.org/
Http://tengine.taobao.org/document_cn/http_upstream_check_cn.html
This article is from the Linux SA John blog, so be sure to keep this source http://john88wang.blog.51cto.com/2165294/1879127
Zabbix monitoring Tengine Back-end server Health Check