<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>服务器安全维护工作室 &#187; 【zabbix】使用zabbix_sender主动发送监控数据到zabbix server</title>
	<atom:link href="https://www.fuwuqiok.com/tag/%e3%80%90zabbix%e3%80%91%e4%bd%bf%e7%94%a8zabbix_sender%e4%b8%bb%e5%8a%a8%e5%8f%91%e9%80%81%e7%9b%91%e6%8e%a7%e6%95%b0%e6%8d%ae%e5%88%b0zabbix-server/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.fuwuqiok.com</link>
	<description></description>
	<lastBuildDate>Sun, 01 Mar 2020 07:28:40 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.2.26</generator>
	<item>
		<title>使用zabbix_sender主动发送监控数据到zabbix server</title>
		<link>https://www.fuwuqiok.com/%e4%bd%bf%e7%94%a8zabbix_sender%e4%b8%bb%e5%8a%a8%e5%8f%91%e9%80%81%e7%9b%91%e6%8e%a7%e6%95%b0%e6%8d%ae%e5%88%b0zabbix-server/</link>
		<comments>https://www.fuwuqiok.com/%e4%bd%bf%e7%94%a8zabbix_sender%e4%b8%bb%e5%8a%a8%e5%8f%91%e9%80%81%e7%9b%91%e6%8e%a7%e6%95%b0%e6%8d%ae%e5%88%b0zabbix-server/#comments</comments>
		<pubDate>Wed, 17 Feb 2016 13:53:22 +0000</pubDate>
		<dc:creator><![CDATA[admin]]></dc:creator>
				<category><![CDATA[linux代维]]></category>
		<category><![CDATA[linux服务器代维]]></category>
		<category><![CDATA[linux服务器代维护]]></category>
		<category><![CDATA[linux系统代维]]></category>
		<category><![CDATA[代维]]></category>
		<category><![CDATA[服务器代维]]></category>
		<category><![CDATA[网站代维]]></category>
		<category><![CDATA[【zabbix】使用zabbix_sender主动发送监控数据到zabbix server]]></category>

		<guid isPermaLink="false">https://www.fuwuqiok.com/?p=2896</guid>
		<description><![CDATA[<p>通常来讲，大部分的zabbix key都是预先在server端定义好抓取数据的行为（比如抓取脚本，时间间隔，单 [&#8230;]</p>
<p><a rel="nofollow" href="https://www.fuwuqiok.com/%e4%bd%bf%e7%94%a8zabbix_sender%e4%b8%bb%e5%8a%a8%e5%8f%91%e9%80%81%e7%9b%91%e6%8e%a7%e6%95%b0%e6%8d%ae%e5%88%b0zabbix-server/">使用zabbix_sender主动发送监控数据到zabbix server</a>，首发于<a rel="nofollow" href="https://www.fuwuqiok.com">服务器安全维护工作室</a>。</p>
]]></description>
				<content:encoded><![CDATA[<section class="context">通常来讲，大部分的zabbix key都是预先在server端定义好抓取数据的行为（比如抓取脚本，时间间隔，单位），然后由server端按照这个行为去向agent索要数据，或者 由agent按照这个行为往server端发送数据，但都逃不开“定时”这个概念，即抓取数据的时间间隔是固定的。有一种场景，需要监控的数据不是随时 （比如cpu，load）都能拿到的，而是由某些程序不定时的产生（比如crontab，某些用户触发的数据），这时候再用常规的zabbix key解决起来就不是那么的优雅，而且很难做到实时，理想的做法应该是<strong>程序产生监控数据的同时便将数据发送到zabbix server</strong>，这种做法类似于大名鼎鼎的<a href="https://newrelic.com/" target="_blank" rel="nofollow">newrelic</a>，通过在程序端部署agent，然后发送数据到newrelic服务器。甚幸，zabbix提供类似的功能来帮助我们完成这种需求。<br />
<strong>zabbix_sender:</strong><br />
zabbix提供的二进制程序，可以用来发送数据到zabbix server，具体用法如下：</p>
<pre class="wp-code-highlight prettyprint prettyprinted"><span class="pun">&gt;&gt;&gt;</span><span class="pln"> zabbix_sender </span><span class="pun">-</span><span class="pln">z </span><span class="lit">10.0</span><span class="pun">.</span><span class="lit">0.1</span> <span class="pun">-</span><span class="pln">p </span><span class="lit">10051</span> <span class="pun">-</span><span class="pln">s </span><span class="str">"rs_solrmaster"</span> <span class="pun">-</span><span class="pln">k </span><span class="str">"get_number_of_solr_index_update"</span> <span class="pun">-</span><span class="pln">o </span><span class="lit">4</span>
<span class="pun">需要注意的是</span><span class="pln">get_number_of_solr_index_update</span><span class="pun">这个</span><span class="pln">key</span><span class="pun">是需要事先创建在</span><span class="pln">rs_solrmaster</span><span class="pun">这台主机上的，并且是</span><span class="pln">zabbix trapper</span><span class="pun">类型的，并且是</span><span class="pln">zabbix trapper</span><span class="pun">类型的，并且是</span><span class="pln">zabbix trapper</span><span class="pun">类型的。</span>
<span class="com">#usage: zabbix_sender [-Vhv] {[-zpsI] -ko | [-zpI] -T -i  -r} [-c ]</span>
<span class="com">#Options:</span>
<span class="com">#  -c --config                    配置文件的绝对路径</span>
<span class="com">#  -z --zabbix-server             zabbix server或者zabbix proxy的ip地址</span>
<span class="com">#  -p --port                      zabbix server或者zabbix proxy的端口，默认是10051</span>
<span class="com">#  -s --host                      主机名，指的是zabbix里配制的主机名</span>
<span class="com">#  -I --source-address            源ip，干嘛使得</span>
<span class="com">#  -k --key                       zabbix trapper key名字</span>
<span class="com">#  -o --value                     需要发送的监控项值</span>
<span class="com">#  -i --input-file &lt;input type="text" /&gt;   通过文件的方式批量发送数据，每行一个纪录，格式为hostname,key,value,使用空格分割，如果hostname有空格，使用双引号。</span>
<span class="pun">&gt;&gt;&gt;</span><span class="pln"> cat trapper_key</span><span class="pun">.</span><span class="pln">txt
</span><span class="str">"zabbix server"</span><span class="pln"> key1 </span><span class="lit">10</span>
<span class="str">"zabbix proxy"</span><span class="pln"> key2 </span><span class="lit">20</span>
<span class="lit">10.0</span><span class="pun">.</span><span class="lit">0.2</span><span class="pln"> key3 </span><span class="lit">30</span>
<span class="pun">&gt;&gt;&gt;</span><span class="pln"> zabbix_sender </span><span class="pun">-</span><span class="pln">z </span><span class="lit">10.0</span><span class="pun">.</span><span class="lit">0.1</span> <span class="pun">-</span><span class="pln">i trapper_key</span><span class="pun">.</span><span class="pln">txt</span></pre>
<p>如此，我们便可以随时随地的向zabbix发送监控数据了，由于zabbix只提供了zabbix_sender这个二进制程序来发送数据，如果要 在程序中调用，直接调用一个二进程程序是一种很丑陋的做法，那么有没有更优雅的办法呢（zabbix的api部分并没有trapper key的相关说明）。有，注意前方高能。<br />
zabbix_sender跟zabbix_server的通信方式是tcp协议的，也就是说zabbix_sender发送给一个DATA段为固定格式 的tcp数据包给zabbix_server,然后server端解析并处理请求。所以这个DATA段的数据格式如果能确定，那我们就可以使用程序来模拟 zabbix_sender了。<br />
先来看两篇文章：<br />
<a href="http://itnihao.blog.51cto.com/1741976/1343670" target="_blank" rel="nofollow">zabbix sender协议的研究 | itnihao</a><br />
<a href="https://www.zabbix.org/wiki/Docs/protocols/zabbix_sender/2.0" target="_blank" rel="nofollow">zabbix sender 2.0 协议文档</a><br />
从中可以整理出一个完整的zabbix_sender请求包的格式如下：</p>
<table id="tablepress-1" class="tablepress tablepress-id-1">
<tbody class="row-hover">
<tr class="row-1 odd">
<td class="column-1" colspan="16">源端口</td>
<td class="column-17" colspan="16">目标端口</td>
</tr>
<tr class="row-2 even">
<td class="column-1" colspan="32">32位序列号</td>
</tr>
<tr class="row-3 odd">
<td class="column-1" colspan="32">32位确认号</td>
</tr>
<tr class="row-4 even">
<td class="column-1" colspan="4">4位首部长度</td>
<td class="column-5" colspan="6">保留(6位)</td>
<td class="column-11">URG</td>
<td class="column-12">ACK</td>
<td class="column-13">PSH</td>
<td class="column-14">PST</td>
<td class="column-15">SYN</td>
<td class="column-16">FIN</td>
<td class="column-17" colspan="16">16位窗口大小</td>
</tr>
<tr class="row-5 odd">
<td class="column-1" colspan="16">16位校验和</td>
<td class="column-17" colspan="16">16位紧急指针</td>
</tr>
<tr class="row-6 even">
<td class="column-1" colspan="32">可选项</td>
</tr>
<tr class="row-7 odd">
<td class="column-1">Z</td>
<td class="column-2">B</td>
<td class="column-3">X</td>
<td class="column-4">D</td>
<td class="column-5">协议版本</td>
<td class="column-6" colspan="8">8位数据长度</td>
<td class="column-14" colspan="19">请求或者响应的json数据</td>
</tr>
</tbody>
</table>
<p>可以看到基本的zabbix_sender数据协议即为&#8217;Z&#8221;B&#8221;X&#8221;D&#8217; ＋ 1位的协议版本号 ＋ 8位的数据长度 ＋ json数据组成，如文档，请求的json数据格式为：</p>
<pre class="wp-code-highlight prettyprint prettyprinted"><span class="pun">{</span>
        <span class="str">"request"</span><span class="pun">:</span><span class="str">"sender data"</span><span class="pun">,</span>
        <span class="str">"data"</span><span class="pun">:[</span>
                <span class="pun">{</span>
                        <span class="str">"host"</span><span class="pun">:</span><span class="str">"Host name 1"</span><span class="pun">,</span>
                        <span class="str">"key"</span><span class="pun">:</span><span class="str">"item_key"</span><span class="pun">,</span>
                        <span class="str">"value"</span><span class="pun">:</span><span class="str">"33"</span><span class="pun">},</span>
                <span class="pun">{</span>
                        <span class="str">"host"</span><span class="pun">:</span><span class="str">"Host name 2"</span><span class="pun">,</span>
                        <span class="str">"key"</span><span class="pun">:</span><span class="str">"item_key"</span><span class="pun">,</span>
                        <span class="str">"value"</span><span class="pun">:</span><span class="str">"55"</span>
                <span class="pun">}</span>
        <span class="pun">]</span>
<span class="pun">}</span></pre>
<p>这样，基本的程序逻辑就出来了,即为：<br />
♠ 构建符合zabbix_sender协议的数据包，格式为 &#8216;4sBq<em>n</em>s&#8217; (n为json串的长度)<br />
♠ 发送数据包至zabbix_server的端口<br />
♠ 处理响应<br />
如下为一个python的实现示例:</p>
<pre class="wp-code-highlight prettyprint prettyprinted"><span class="com">#!/usr/bin/env python</span>

<span class="kwd">import</span> <span class="kwd">struct</span>
<span class="kwd">import</span><span class="pln"> json
</span><span class="kwd">import</span><span class="pln"> socket


</span><span class="kwd">class</span><span class="pln"> zabbix_sender</span><span class="pun">:</span>
        <span class="kwd">def</span><span class="pln"> __init__</span><span class="pun">(</span><span class="kwd">self</span><span class="pun">,</span><span class="pln">zbx_server_host</span><span class="pun">,</span><span class="pln">zbx_server_port</span><span class="pun">):</span>
                <span class="kwd">self</span><span class="pun">.</span><span class="pln">zbx_server_host</span><span class="pun">=</span><span class="pln">zbx_server_host
                </span><span class="kwd">self</span><span class="pun">.</span><span class="pln">zbx_server_port</span><span class="pun">=</span><span class="pln">zbx_server_port
                </span><span class="kwd">self</span><span class="pun">.</span><span class="pln">zbx_header</span><span class="pun">=</span><span class="str">'ZBXD'</span>
                <span class="kwd">self</span><span class="pun">.</span><span class="pln">zbx_protocols_version</span><span class="pun">=</span><span class="lit">1</span>
                <span class="kwd">self</span><span class="pun">.</span><span class="pln">zbx_send_value</span><span class="pun">={</span><span class="str">'request'</span><span class="pun">:</span><span class="str">'sender data'</span><span class="pun">,</span><span class="str">'data'</span><span class="pun">:[]}</span>
        <span class="kwd">def</span><span class="pln"> adddata</span><span class="pun">(</span><span class="kwd">self</span><span class="pun">,</span><span class="pln">host</span><span class="pun">,</span><span class="pln">key</span><span class="pun">,</span><span class="pln">value</span><span class="pun">):</span><span class="pln">
                add_data</span><span class="pun">={</span><span class="str">'host'</span><span class="pun">:</span><span class="pln">host</span><span class="pun">,</span><span class="str">'key'</span><span class="pun">:</span><span class="pln">key</span><span class="pun">,</span><span class="str">'value'</span><span class="pun">:</span><span class="pln">value</span><span class="pun">}</span>
                <span class="kwd">self</span><span class="pun">.</span><span class="pln">zbx_send_value</span><span class="pun">[</span><span class="str">'data'</span><span class="pun">].</span><span class="pln">append</span><span class="pun">(</span><span class="pln">add_data</span><span class="pun">)</span>
        <span class="com">#按照协议封装数据包</span>
        <span class="kwd">def</span><span class="pln"> makesenddata</span><span class="pun">(</span><span class="kwd">self</span><span class="pun">):</span><span class="pln">
                zbx_send_json</span><span class="pun">=</span><span class="pln">json</span><span class="pun">.</span><span class="pln">dumps</span><span class="pun">(</span><span class="kwd">self</span><span class="pun">.</span><span class="pln">zbx_send_value</span><span class="pun">)</span><span class="pln">
                zbx_send_json_len</span><span class="pun">=</span><span class="pln">len</span><span class="pun">(</span><span class="pln">zbx_send_json</span><span class="pun">)</span>
                <span class="kwd">self</span><span class="pun">.</span><span class="pln">zbx_send_data</span><span class="pun">=</span><span class="kwd">struct</span><span class="pun">.</span><span class="pln">pack</span><span class="pun">(</span><span class="str">"&lt;4sBq"</span><span class="pun">+</span><span class="pln">str</span><span class="pun">(</span><span class="pln">zbx_send_json_len</span><span class="pun">)+</span><span class="str">"s"</span><span class="pun">,</span><span class="str">'ZBXD'</span><span class="pun">,</span><span class="lit">1</span><span class="pun">,</span><span class="pln">zbx_send_json_len</span><span class="pun">,</span><span class="pln">zbx_send_json</span><span class="pun">)</span>
        <span class="kwd">def</span><span class="pln"> send</span><span class="pun">(</span><span class="kwd">self</span><span class="pun">):</span>
                <span class="kwd">self</span><span class="pun">.</span><span class="pln">makesenddata</span><span class="pun">()</span><span class="pln">
                zbx_server_socket</span><span class="pun">=</span><span class="pln">socket</span><span class="pun">.</span><span class="pln">socket</span><span class="pun">()</span><span class="pln">
                zbx_server_socket</span><span class="pun">.</span><span class="pln">connect</span><span class="pun">((</span><span class="kwd">self</span><span class="pun">.</span><span class="pln">zbx_server_host</span><span class="pun">,</span><span class="kwd">self</span><span class="pun">.</span><span class="pln">zbx_server_port</span><span class="pun">))</span><span class="pln">
                zbx_server_write_df</span><span class="pun">=</span><span class="pln">zbx_server_socket</span><span class="pun">.</span><span class="pln">makefile</span><span class="pun">(</span><span class="str">'wb'</span><span class="pun">)</span><span class="pln">
                zbx_server_write_df</span><span class="pun">.</span><span class="pln">write</span><span class="pun">(</span><span class="kwd">self</span><span class="pun">.</span><span class="pln">zbx_send_data</span><span class="pun">)</span><span class="pln">
                zbx_server_write_df</span><span class="pun">.</span><span class="pln">close</span><span class="pun">()</span><span class="pln">
                zbx_server_read_df</span><span class="pun">=</span><span class="pln">zbx_server_socket</span><span class="pun">.</span><span class="pln">makefile</span><span class="pun">(</span><span class="str">'rb'</span><span class="pun">)</span><span class="pln">
                zbx_response_package</span><span class="pun">=</span><span class="pln">zbx_server_read_df</span><span class="pun">.</span><span class="pln">read</span><span class="pun">()</span><span class="pln">
                zbx_server_read_df</span><span class="pun">.</span><span class="pln">close</span><span class="pun">()</span>
                <span class="com">#按照协议解数据包</span><span class="pln">
                zbx_response_data</span><span class="pun">=</span><span class="kwd">struct</span><span class="pun">.</span><span class="pln">unpack</span><span class="pun">(</span><span class="str">"&lt;4sBq"</span><span class="pun">+</span><span class="pln">str</span><span class="pun">(</span><span class="pln">len</span><span class="pun">(</span><span class="pln">zbx_response_package</span><span class="pun">)</span> <span class="pun">-</span> <span class="kwd">struct</span><span class="pun">.</span><span class="pln">calcsize</span><span class="pun">(</span><span class="str">"&lt;4sBq"</span><span class="pun">))+</span><span class="str">"s"</span><span class="pun">,</span><span class="pln">zbx_response_package</span><span class="pun">)</span>
                <span class="kwd">return</span><span class="pln"> zbx_response_data</span><span class="pun">[</span><span class="lit">3</span><span class="pun">]</span>

<span class="kwd">if</span><span class="pln"> __name__ </span><span class="pun">==</span> <span class="str">'__main__'</span><span class="pun">:</span><span class="pln">
        zabbix_sender</span><span class="pun">=</span><span class="pln">zabbix_sender</span><span class="pun">(</span><span class="str">'10.0.0.1'</span><span class="pun">,</span><span class="lit">10051</span><span class="pun">)</span><span class="pln">
        zabbix_sender</span><span class="pun">.</span><span class="pln">adddata</span><span class="pun">(</span><span class="str">'solrmaster'</span><span class="pun">,</span><span class="str">'get_number_of_solr_index_update'</span><span class="pun">,</span><span class="lit">60</span><span class="pun">)</span><span class="pln">
        response</span><span class="pun">=</span><span class="pln">zabbix_sender</span><span class="pun">.</span><span class="pln">send</span><span class="pun">()</span>
        <span class="kwd">print</span><span class="pln"> response</span></pre>
</section>
<p><a rel="nofollow" href="https://www.fuwuqiok.com/%e4%bd%bf%e7%94%a8zabbix_sender%e4%b8%bb%e5%8a%a8%e5%8f%91%e9%80%81%e7%9b%91%e6%8e%a7%e6%95%b0%e6%8d%ae%e5%88%b0zabbix-server/">使用zabbix_sender主动发送监控数据到zabbix server</a>，首发于<a rel="nofollow" href="https://www.fuwuqiok.com">服务器安全维护工作室</a>。</p>
]]></content:encoded>
			<wfw:commentRss>https://www.fuwuqiok.com/%e4%bd%bf%e7%94%a8zabbix_sender%e4%b8%bb%e5%8a%a8%e5%8f%91%e9%80%81%e7%9b%91%e6%8e%a7%e6%95%b0%e6%8d%ae%e5%88%b0zabbix-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
