<?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>joemiller.me</title>
	<atom:link href="http://joemiller.me/feed/" rel="self" type="application/rss+xml" />
	<link>http://joemiller.me</link>
	<description>$ cat /dev/mem</description>
	<lastBuildDate>Thu, 25 Oct 2012 15:36:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Speeding up Vagrant with parallel&#160;provisioning</title>
		<link>http://joemiller.me/2012/04/26/speeding-up-vagrant-with-parallel-provisioning/</link>
		<comments>http://joemiller.me/2012/04/26/speeding-up-vagrant-with-parallel-provisioning/#comments</comments>
		<pubDate>Thu, 26 Apr 2012 15:15:40 +0000</pubDate>
		<dc:creator>jmiller</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[sensu]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[vagrant]]></category>

		<guid isPermaLink="false">http://joemiller.me/?p=541</guid>
		<description><![CDATA[Vagrant is an amazing tool. It&#39;s quite substantially changed my workflows in a variety of areas. It&#39;s a particularly interesting tool for building packages or running tests across multiple OS&#39;s or distributions from a single set of scripts. A recent example of the usefulness of Vagrant is the new packaging and testing work undertaken in [...]]]></description>
			<content:encoded><![CDATA[<p>Vagrant is an amazing tool. It&#39;s quite substantially changed my workflows in a variety of areas. It&#39;s a particularly interesting tool for building packages or running tests across multiple OS&#39;s or distributions from a single set of scripts.</p>
<p>A recent example of the usefulness of Vagrant is the new packaging and testing work undertaken in the <a href="https://github.com/sensu/sensu">Sensu</a> project. The project set out to build a new set of native OS packages with a goal of making Sensu easy to deploy on a variety of platforms and without a lot of the friction that sometimes accompanies Ruby apps. As part of the packaging effort we needed a simple mechanism to build native packages on the relevant platforms, ie: .deb&#39;s on debian and .rpm on redhat/centos.</p>
<p>We ended up using a combination of Vagrant and some homegrown tools such as <a href="https://github.com/joemiller/bunchr">Bunchr</a>.</p>
<p>You can see the work in these 2 repos:</p>
<ul>
<li><a href="http://github.com/sensu/sensu-build">http://github.com/sensu/sensu-build</a></li>
<li><a href="http://github.com/joemiller/sensu-tests">http://github.com/joemiller/sensu-tests</a></li>
</ul>
<p>Both codebases contain a <code>para-vagrant.sh</code> script that is used in place of the normal <code>vagrant up</code> to kick off parallel provisioning tasks. <code>sensu-tests</code> is the more interesting example as it runs a set of rspec tests against Sensu across <em>14</em> VM&#39;s and this will likely grow to encompass other OS&#39;s in the future. The tests are executed as Vagrant provisioners (a combo of Chef and shell to call rspec).</p>
<p>The simplest way to use multi-VM&#39;s with Vagrant is the typical <code>vagrant up</code>. However, this will boot and run the provisioning tasks sequentially on each VM. With 14 VM&#39;s to test, this process can take a long time.</p>
<p>Can we speed this up? Yes. In fact we were able to reduce the time taken to run the <code>sensu-build</code> tasks from about 33 minutes to 12 minutes, and reduced <code>sensu-tasks</code> from almost 90 minutes to 15! </p>
<p>Here was the first attempt at a parallelization script:</p>
<p><span id="more-541"></span></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># concurrency is hard, let's have a beer</span>
&nbsp;
<span style="color: #007800;">MAX_PROCS</span>=<span style="color: #000000;">4</span>
&nbsp;
parallel_provision<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">while</span> <span style="color: #c20cb9; font-weight: bold;">read</span> box; <span style="color: #000000; font-weight: bold;">do</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Provisioning '<span style="color: #007800;">$box</span>'. Output will be in: <span style="color: #007800;">$box</span>.out.txt&quot;</span> <span style="color: #000000;">1</span><span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">2</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$box</span>
    <span style="color: #000000; font-weight: bold;">done</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">xargs</span> <span style="color: #660033;">-P</span> <span style="color: #007800;">$MAX_PROCS</span> <span style="color: #660033;">-I</span><span style="color: #ff0000;">&quot;BOXNAME&quot;</span> \
        <span style="color: #c20cb9; font-weight: bold;">sh</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">'vagrant provision BOXNAME &gt;BOXNAME.out.txt 2&gt;&amp;1 || echo &quot;Error Occurred: BOXNAME&quot;'</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">## -- main -- ##</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># start boxes sequentially to avoid vbox explosions</span>
vagrant up <span style="color: #660033;">--no-provision</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># but run provision tasks in parallel</span>
<span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: #000000; font-weight: bold;">&lt;&lt;</span>EOF <span style="color: #000000; font-weight: bold;">|</span> parallel_provision
centos_5_64
centos_5_32
ubuntu_1004_32
ubuntu_1004_64
EOF</pre></div></div>

<p>There are 2 steps to the process:</p>
<ul>
<li>
<p>Sequentially boot each VM listed in the Vagrantfile, but without running provisioners (<code>vagrant up --no-provision</code>). The reason we do the bootups sequentially is to avoid potential kernel panics that VirtualBox is prone to do, at least on OSX.</p>
</li>
<li>
<p>Feed a list of VM&#39;s into <code>xargs</code> to execute $MAX_PROCS <code>vagrant provision $BOXNAME</code> processes in parallel. <code>xargs</code> will manage the concurrency for us.</p>
</li>
</ul>
<p>The final script we used with the sensu-tests repo is a little different than the above example, which can be viewed here: <a href="https://github.com/joemiller/sensu-tests/blob/master/para-vagrant.sh">para-vagrant.sh</a>. This script reduced the time it takes to run the full test suite from over 90 minutes to 15 minutes. The differences in this final version of the script:</p>
<ul>
<li>
<p>uses GNU parallel instead of xargs for better handling/grouping of the output from the <code>vagrant provision</code> processes.</p>
</li>
<li>
<p>reads the list of VM&#39;s from a JSON file (the Vagrantfile also uses this JSON file). To add/remove new VM&#39;s, you only need to edit one file now.</p>
</li>
</ul>
<h3>Future?</h3>
<p>It should be possible to make the process go even faster by parallelizing the bootup phase, but I have not tried this yet because I&#39;m worried about VirtualBox stability. </p>
<p>Also, I&#39;m sure there&#39;s a more polished script/utility that can be written to parallelize any multi-VM Vagrantfile.</p>
<h3>Alternatives?</h3>
<p>As <a href="https://twitter.com/vvuksan">@vvuksan</a> correctly points out, doing such short tasks with Vagrant is probably always going to be a little slow due to the overhead in spinning up VM&#39;s, so a possible alternative maybe LXC. There&#39;s already a Vagrant-like tool for LXC called <a href="https://github.com/exceedhl/toft">toft</a>. LXC should work fine for workflows that include only various Linux distributions, but won&#39;t help if you need to test other OS&#39;s like FreeBSD or Solaris.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemiller.me/2012/04/26/speeding-up-vagrant-with-parallel-provisioning/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sensu handler&#160;sets</title>
		<link>http://joemiller.me/2012/02/27/sensu-handler-sets/</link>
		<comments>http://joemiller.me/2012/02/27/sensu-handler-sets/#comments</comments>
		<pubDate>Mon, 27 Feb 2012 18:06:38 +0000</pubDate>
		<dc:creator>jmiller</dc:creator>
				<category><![CDATA[devOps]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[sensu]]></category>

		<guid isPermaLink="false">http://joemiller.me/?p=519</guid>
		<description><![CDATA[In past articles we have covered some of basics of Sensu handlers. A nice feature we haven&#39;t touched on yet is handler &#34;sets&#34;. Handler sets were added around v0.9.2 and can be quite useful for saving time when modifying your handler. For example, consider you have a standard set of handlers that you assign to [...]]]></description>
			<content:encoded><![CDATA[<p>In past articles we have covered some of basics of Sensu handlers. A nice feature we haven&#39;t touched on yet is handler &quot;sets&quot;. Handler sets were added around v0.9.2 and can be quite useful for saving time when modifying your handler.</p>
<p>For example, consider you have a standard set of handlers that you assign to most of your checks &#8212; pagerduty, irc, campfire. Now, suppose you want to add the <a href="https://github.com/sonian/sensu-community-plugins/blob/master/handlers/notification/gelf.rb">GELF</a> (<a href="http://graylog2.org">graylog2</a>) handler to all of your monitors as well. If each of your checks is defined as such:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
  <span style="color: #3366CC;">&quot;checks&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;all_disk_check&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #3366CC;">&quot;notification&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Diskspace Too Low&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;command&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;PATH=$PATH:/usr/lib64/nagios/plugins:/usr/lib/nagios/plugins  check_disk -w 25% -c 15% /&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;subscribers&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span> <span style="color: #3366CC;">&quot;all&quot;</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;interval&quot;</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">60</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;handlers&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;pagerduty&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;irc&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;campfire&quot;</span><span style="color: #009900;">&#93;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>&#8230; you would need to modify every check&#39;s &quot;handlers&quot; attribute to include your new &quot;gelf&quot; handler. If you have a lot of checks this can be a little bit of a burden.</p>
<p><span id="more-519"></span></p>
<p>Handler sets save a lot of time in this situation. If you instead define your checks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
  <span style="color: #3366CC;">&quot;checks&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;all_disk_check&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #3366CC;">&quot;notification&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Diskspace Too Low&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;command&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;PATH=$PATH:/usr/lib64/nagios/plugins:/usr/lib/nagios/plugins  check_disk -w 25% -c 15% /&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;subscribers&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span> <span style="color: #3366CC;">&quot;all&quot;</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;interval&quot;</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">60</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;handlers&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;default&quot;</span><span style="color: #009900;">&#93;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>And then define your handlers on your Sensu server like the following. Notice we have converted the &#39;default&#39; handler to a set.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #3366CC;">&quot;handlers&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #3366CC;">&quot;default&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;set&quot;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;handlers&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;pagerduty&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;irc&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;campfire&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;gelf&quot;</span><span style="color: #009900;">&#93;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;pagerduty&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;pipe&quot;</span><span style="color: #339933;">,</span> 
        <span style="color: #3366CC;">&quot;command&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/etc/sensu/handlers/pagerduty&quot;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;irc&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;pipe&quot;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;command&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/etc/sensu/handlers/irc&quot;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;campfire&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;pipe&quot;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;command&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/etc/sensu/handlers/campfire&quot;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;gelf&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;pipe&quot;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;command&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/etc/sensu/handlers/gelf.rb&quot;</span>
      <span style="color: #009900;">&#125;</span>   
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></pre></div></div>

<p>You only need to modify the &quot;default&quot; handler set to add the new &quot;gelf&quot; handler and no need to change any of your check definitions.</p>
<p>It&#39;s a simple feature, but it can save a bunch of time. You could also setup a handler set specifically for metrics and another set for notifications. In the case of metrics, you could easily ship metrics to multiple systems &#8211; Graphite, Librato, Cube, etc. And adding a new system would be as simple as creating the handler and adding it to the handler set. Happy Sensu&#39;ing.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemiller.me/2012/02/27/sensu-handler-sets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AMQPcat, a netcat-like tool for messaging&#160;fun</title>
		<link>http://joemiller.me/2012/02/08/amqpcat-a-netcat-like-tool-for-messaging-fun/</link>
		<comments>http://joemiller.me/2012/02/08/amqpcat-a-netcat-like-tool-for-messaging-fun/#comments</comments>
		<pubDate>Wed, 08 Feb 2012 23:30:02 +0000</pubDate>
		<dc:creator>jmiller</dc:creator>
				<category><![CDATA[messaging]]></category>
		<category><![CDATA[rabbitmq]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://joemiller.me/?p=501</guid>
		<description><![CDATA[If you have read @ripienaar&#39;s excellent series of articles on common messaging patterns you probably noticed a handy CLI tool for working with STOMP queues called stompcat. I looked around for something similar for AMQP brokers but couldn&#39;t find anything quite the same. There is amqp-utils but I had some issues with these and the [...]]]></description>
			<content:encoded><![CDATA[<p>If you have read <a href="http://www.devco.net/">@ripienaar&#39;s</a> excellent series of <a href="http://www.devco.net/archives/2011/12/11/common-messaging-patterns-using-stomp.php">articles</a> on common messaging patterns you probably noticed a handy CLI tool for working with STOMP queues called <code>stompcat</code>. I looked around for something similar for AMQP brokers but couldn&#39;t find anything quite the same. There is <a href="https://github.com/dougbarth/amqp-utils">amqp-utils</a> but I had some issues with these and the tools didn&#39;t work quite like I was hoping. So I wrote <code>amqpcat</code> with the idea of providing a similar tool to <code>stompcat</code>. </p>
<p>Available on github and rubygems.org: <a href="https://github.com/joemiller/amqpcat">https://github.com/joemiller/amqpcat</a></p>
<p><span id="more-501"></span></p>
<p>Installation is easy:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> gem <span style="color: #c20cb9; font-weight: bold;">install</span> amqpcat <span style="color: #660033;">--no-rdoc</span> <span style="color: #660033;">--no-ri</span></pre></div></div>

<h2>1:1 Messaging demonstration</h2>
<p>Publish a message:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;hello there&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> amqpcat amqp:<span style="color: #000000; font-weight: bold;">//</span>guest:guest<span style="color: #000000; font-weight: bold;">@</span>rabbitmq <span style="color: #660033;">-t</span> direct <span style="color: #660033;">-n</span> test.direct <span style="color: #660033;">--publisher</span></pre></div></div>

<p>Receive the message:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ amqpcat amqp:<span style="color: #000000; font-weight: bold;">//</span>guest:guest<span style="color: #000000; font-weight: bold;">@</span>rabbitmq <span style="color: #660033;">-t</span> direct <span style="color: #660033;">-n</span> test.direct <span style="color: #660033;">--consumer</span>
hello there</pre></div></div>

<p>Pretty simple. There are various other options, run with <code>-h</code> to see them all. You can easily load-balance amongst multiple consumers by starting multiple consumers with the same url and options. See the <a href="https://github.com/joemiller/amqpcat/blob/master/examples/test_direct.sh">test_direct.sh</a> example for a demo of this.</p>
<h2>1:N / PubSub Messaging</h2>
<p>Start 2 (or more) consumers:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ amqpcat amqp:<span style="color: #000000; font-weight: bold;">//</span>rabbitmq <span style="color: #660033;">-t</span> fanout <span style="color: #660033;">-n</span> test.fanout <span style="color: #660033;">-s</span> <span style="color: #ff0000;">&quot;Consumer-1: &quot;</span> <span style="color: #660033;">--consumer</span> <span style="color: #000000; font-weight: bold;">&amp;</span>
$ amqpcat amqp:<span style="color: #000000; font-weight: bold;">//</span>rabbitmq <span style="color: #660033;">-t</span> fanout <span style="color: #660033;">-n</span> test.fanout <span style="color: #660033;">-s</span> <span style="color: #ff0000;">&quot;Consumer-2: &quot;</span> <span style="color: #660033;">--consumer</span> <span style="color: #000000; font-weight: bold;">&amp;</span></pre></div></div>

<p>Publish a message:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;hello there&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> amqpcat amqp:<span style="color: #000000; font-weight: bold;">//</span>guest:guest<span style="color: #000000; font-weight: bold;">@</span>rabbitmq <span style="color: #660033;">-t</span> fanout <span style="color: #660033;">-n</span> test.fanout <span style="color: #660033;">--publisher</span></pre></div></div>

<p>You should see both consumers receive the message, ie:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">Consumer-<span style="color: #000000;">1</span>: hello there
Consumer-<span style="color: #000000;">2</span>: hello there</pre></div></div>

<p>See <a href="https://github.com/joemiller/amqpcat/blob/master/examples/test_fanout.sh">test_fanout.sh</a> for a similar example.</p>
<h2>SSL support</h2>
<p>SSL support (server verification, and client certs) has been written into the tool but I have not been able to test it to a working state yet.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemiller.me/2012/02/08/amqpcat-a-netcat-like-tool-for-messaging-fun/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sensu and&#160;Graphite</title>
		<link>http://joemiller.me/2012/02/02/sensu-and-graphite/</link>
		<comments>http://joemiller.me/2012/02/02/sensu-and-graphite/#comments</comments>
		<pubDate>Thu, 02 Feb 2012 21:18:52 +0000</pubDate>
		<dc:creator>jmiller</dc:creator>
				<category><![CDATA[devOps]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[sensu]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://joemiller.me/?p=477</guid>
		<description><![CDATA[Updated October 16, 2012: Removed &#8220;passive&#8221;:&#8221;true&#8221; from the graphite amqp handler definition in Sensu. This is too brittle. Sensu will fail to start unless graphite has started first and created the exchange on the RabbitMQ server. By matching the &#8220;durable&#8221;:&#8221;true&#8221; setting that graphite expects, then we can start either service in any order. Updated October [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>
<strong>Updated October 16, 2012</strong>: Removed &#8220;passive&#8221;:&#8221;true&#8221; from the graphite amqp handler definition in Sensu. This is too brittle. Sensu will fail to start unless graphite has started first and created the exchange on the RabbitMQ server. By matching the &#8220;durable&#8221;:&#8221;true&#8221; setting that graphite expects, then we can start either service in any order.</p>
<p><strong>Updated October 16, 2012</strong>: Updated graphite amqp handler definition to use the new &#8220;mutator&#8221;&#8216;s in Sensu 0.9.7. See the <a href="https://github.com/sensu/sensu/blob/master/CHANGELOG.md" title="CHANGELOG"></a> for details on backwards-incompatible changes as Sensu moves towards a 1.0.0 release.
</p></blockquote>
<p>It&#39;s been pretty exciting to see the number of folks getting involved with <a href="http://www.sonian.com/cloud-tools/cloud-monitoring-sensu/">Sensu</a> lately, as judging by the increased activity on the #sensu channel on Freenode. One of the most common questions is how to integrate Sensu and Graphite. In this article I&#39;ll cover two approaches for pushing metrics from Sensu to Graphite.</p>
<p>Remember: think of Sensu as the &quot;monitoring router&quot;. While we are going to show how to push metrics to Graphite, it is just as easy to push metrics to any other system &#8211; Librato, Cube, OpenTSDB, etc. In fact, it would not be difficult at all to push metrics to multiple graphing backends in a fanout manner.</p>
<p><span id="more-477"></span></p>
<h3>Install vmstat-metrics plugin</h3>
<p>For this example, we&#39;re going to use the <code>vmstat-metrics</code> plugin which can be found in the <a href="https://github.com/sonian/sensu-community-plugins">sensu-community-plugins</a> repository on github. The plugins in this repo are meant to be cherry-picked, so let&#39;s just grab the one we&#39;re interested in:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>sensu<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">wget</span> https:<span style="color: #000000; font-weight: bold;">//</span>raw.github.com<span style="color: #000000; font-weight: bold;">/</span>sonian<span style="color: #000000; font-weight: bold;">/</span>sensu-community-plugins<span style="color: #000000; font-weight: bold;">/</span>master<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>system<span style="color: #000000; font-weight: bold;">/</span>vmstat-metrics.rb
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">chmod</span> +x vmstat-metrics.rb</pre></div></div>

<p>Most, but not all, of the plugins in the sensu-community-plugins repository use helper classes from the <a href="https://github.com/sonian/sensu-plugin">sensu-plugin</a>, so we&#39;ll need to install that gem on the nodes that will be running the <code>vmstat-metrics</code> plugin.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> gem <span style="color: #c20cb9; font-weight: bold;">install</span> sensu-plugin <span style="color: #660033;">--no-rdoc</span> <span style="color: #660033;">--no-ri</span></pre></div></div>

<p>Open up <code>vmstat-metrics.rb</code> and we see that it inherits a lot of plumbing from the <code>Sensu::Plugin::Metric::CLI::Graphite</code> class. Keep this in mind when writing your own metrics-gathering plugins, it can save you some time.</p>
<p>Let&#39;s run the plugin manually so we can see the output.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>vmstat-metrics.rb 
stats.swap.in   <span style="color: #000000;">0</span>   <span style="color: #000000;">1328153991</span>
stats.swap.out  <span style="color: #000000;">0</span>   <span style="color: #000000;">1328153991</span>
stats.memory.active <span style="color: #000000;">122160</span>  <span style="color: #000000;">1328153991</span>
stats.memory.swap_used  <span style="color: #000000;">8</span>   <span style="color: #000000;">1328153991</span>
stats.memory.free   <span style="color: #000000;">48556</span>   <span style="color: #000000;">1328153991</span>
stats.memory.inactive   <span style="color: #000000;">73704</span>   <span style="color: #000000;">1328153991</span>
stats.cpu.waiting   <span style="color: #000000;">1</span>   <span style="color: #000000;">1328153991</span>
stats.cpu.idle  <span style="color: #000000;">95</span>  <span style="color: #000000;">1328153991</span>
stats.cpu.system    <span style="color: #000000;">4</span>   <span style="color: #000000;">1328153991</span>
...</pre></div></div>

<p>We will want to customize the path before sending this data to Graphite, including adding a hostname to differentiate it from other hosts. This can be done with the &#8211;scheme switch:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>vmstats-metrics.rb <span style="color: #660033;">--scheme</span> stats.<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">hostname</span> -s<span style="color: #000000; font-weight: bold;">`</span>
stats.host01.swap.in    <span style="color: #000000;">0</span>   <span style="color: #000000;">1328155423</span>
stats.host01.swap.out   <span style="color: #000000;">0</span>   <span style="color: #000000;">1328155423</span>
stats.host01.memory.active  <span style="color: #000000;">122512</span>  <span style="color: #000000;">1328155423</span>
stats.host01.memory.swap_used   <span style="color: #000000;">8</span>   <span style="color: #000000;">1328155423</span>
stats.host01.memory.free    <span style="color: #000000;">43856</span>   <span style="color: #000000;">1328155423</span>
stats.host01.memory.inactive    <span style="color: #000000;">75120</span>   <span style="color: #000000;">1328155423</span>
stats.host01.cpu.waiting    <span style="color: #000000;">1</span>   <span style="color: #000000;">1328155423</span>
stats.host01.cpu.idle   <span style="color: #000000;">95</span>  <span style="color: #000000;">1328155423</span>
stats.host01.cpu.system <span style="color: #000000;">4</span>   <span style="color: #000000;">1328155423</span>
...</pre></div></div>

<p>If you&#39;re familiar with Graphite, this should look familiar. This data fits Graphite&#39;s &quot;stat.name value timestamp&quot; format and we can be feed it directly into Graphite via a couple different methods.</p>
<h3>Create a check .json</h3>
<p>Let&#39;s push out a check definition to our nodes running sensu-client and sensu-server nodes. Don&#39;t forget to install the plugin as well as the <code>sensu-plugin</code> gem.  </p>
<p>File: <code>/etc/sensu/conf.d/metrics_vmstat.json</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
  <span style="color: #3366CC;">&quot;checks&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;vmstat_metrics&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;metric&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;handlers&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;graphite&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> 
      <span style="color: #3366CC;">&quot;command&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/etc/sensu/plugins/vmstat-metrics.rb --scheme stats.:::name:::&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;interval&quot;</span><span style="color: #339933;">:</span> <span style="color: #CC0000;">60</span><span style="color: #339933;">,</span>
          <span style="color: #3366CC;">&quot;subscribers&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span> <span style="color: #3366CC;">&quot;webservers&quot;</span> <span style="color: #009900;">&#93;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>  
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>There are two new items in this check definition that we haven&#39;t covered yet:</p>
<ul>
<li>
<p>The first is a new attribute: &quot;type&quot;: &quot;metric&quot;. This is critical. It tells the sensu-server to send the output of every invocation of this check to the specified handlers. Normally, only checks that return a non-zero exit status indicating a failed check will be passed onto handlers. For metrics, however, we always want to send the output to the handlers.</p>
</li>
<li>
<p>The second is the use of a &quot;custom variable&quot; in the command: <code>:::name:::</code>. Sensu will replace this at execution time with the <code>name</code> attribute from the <code>client</code> section of the Sensu config. There&#39;s a lot of other stuff we can do with custom variables which will be covered in future blogs.</p>
</li>
</ul>
<p>Next, we need to create a handler to do something with this data. Since we&#39;re using Graphite in this example, we&#39;ll explore two methods for getting this data into graphite: direct TCP and AMQP.</p>
<h3>Method 1 &#8211; Direct TCP (via netcat) handler</h3>
<p>The first method will be to simply send this data to Graphite via TCP socket using netcat. This is a very simple approach and should work on most boxes (with netcat installed) and doesn&#39;t require configuring Graphite to use AMQP.</p>
<p>Fetch <code>graphite_tcp.rb</code> from the <a href="https://github.com/sonian/sensu-community-plugins/tree/master/handlers/metrics">sensu-community-plugins</a> repo and copy to <code>/etc/sensu/handlers</code>.</p>
<p>Next create <code>/etc/sensu/conf.d/graphite_tcp.json</code> config file:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
  <span style="color: #3366CC;">&quot;graphite&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;server&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;graphite.example.com&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #3366CC;">&quot;port&quot;</span><span style="color: #339933;">:</span><span style="color: #3366CC;">&quot;2003&quot;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Create <code>/etc/sensu/conf.d/handler_graphite.json</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
  <span style="color: #3366CC;">&quot;handlers&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;graphite&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;pipe&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;command&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;/etc/sensu/handlers/graphite_tcp.rb&quot;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Restart sensu-server and you should start seeing vmstat metrics show up in Graphite.</p>
<p>There is a downside to this approach, however, and that is scalability. For each metric that is received, sensu-server will fork and execute this handler. With many nodes, many checks generating metrics, and a low interval, this could quickly add up to dozens or hundreds of short-lived processes being forked on the sensu-server.</p>
<h3>Method 2 &#8211; integrated AMQP handler</h3>
<p>Remember that I keep calling Sensu &quot;the monitoring router&quot;? Because Sensu and Graphite both speak the AMQP messaging protocol, we can configure sensu-server to take the check output directly off of a rabbitmq queue and copy it to a new queue in a format for Graphite. This approach should be very fast and very scalable.</p>
<p>Configure Graphite&#39;s <code>carbon-cache</code> for AMQP:</p>
<p><code>/opt/graphite/conf/carbon.conf</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #000099;">ENABLE_AMQP</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> True</span>
# AMQP_VERBOSE <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> True</span>
<span style="color: #000099;">AMQP_HOST</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> sensu.example.com</span>
<span style="color: #000099;">AMQP_PORT</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 5672</span>
<span style="color: #000099;">AMQP_VHOST</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> /sensu</span>
<span style="color: #000099;">AMQP_USER</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> sensu</span>
<span style="color: #000099;">AMQP_PASSWORD</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> mypass</span>
<span style="color: #000099;">AMQP_EXCHANGE</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> metrics</span>
<span style="color: #000099;">AMQP_METRIC_NAME_IN_BODY</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> True</span></pre></div></div>

<p>An important part of this config is <code>AMQP_METRIC_NAME_IN_BODY = True</code> which means Graphite will determine the metric name from the contents of the message rather than via the routing key. See <a href="https://answers.launchpad.net/graphite/+question/163389">here</a> for more info.</p>
<p>Next, we configure a handler on the sensu-server that will send metrics to the queue Graphite is listening on:</p>
<p>Edit <code>/etc/sensu/conf.d/handler_graphite.json</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #009900;">&#123;</span>
  <span style="color: #3366CC;">&quot;handlers&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;graphite&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;amqp&quot;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;exchange&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;topic&quot;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;name&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;metrics&quot;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">&quot;durable&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;true&quot;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #3366CC;">&quot;mutator&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;only_check_output&quot;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>A few things to note here:</p>
<ul>
<li>&quot;type&quot;: &quot;amqp&quot; : We&#39;re telling sensu-server that this handler will re-route the check output to an AMQP exchange.</li>
<li>&quot;durable&quot;: &quot;true&quot; : Graphite (carbon-cache) creates the exchange as a durable exchange. We need to match this setting otherwise we will get an error from Rabbit and the connection will fail.</li>
<li>&quot;mutator&quot;: &quot;only_check_output&quot; : This instructs sensu-server to only send the raw <code>output</code> (from stdout) returned by the check to the AMQP exchange. By default, sensu-server would send the entire JSON doc with other metadata, but Graphite wouldn&#39;t know what to do with that data.</li>
</ul>
<h3>Debug tips:</h3>
<p>For debugging the Graphite side of things, it can be helpful to enable <code>AMQP_VERBOSE = True</code> in <code>carbon.conf</code>. With this enabled, the following will be visible in <code>listener.log</code> when a metric is successfully retrieved from rabbitmq by Graphite:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">02<span style="color: #000000; font-weight: bold;">/</span>02<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2012</span> <span style="color: #000000;">10</span>:<span style="color: #000000;">11</span>:<span style="color: #000000;">11</span> :: Message received: Method<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #007800;">name</span>=deliver, <span style="color: #007800;">id</span>=<span style="color: #000000;">60</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">'graphite_consumer'</span>, <span style="color: #000000;">8</span>, False, <span style="color: #ff0000;">'metrics'</span>, <span style="color: #ff0000;">''</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> content = <span style="color: #000000; font-weight: bold;">&lt;</span>Content instance: <span style="color: #007800;">body</span>=<span style="color: #ff0000;">'test.sensu-server.swap.in\t0\t1328195471\ntest.sensu-server.swap.out\t0\t1328195471\ntest.sensu-server.memory.active\t126856\t1328195471\ntest.sensu-server.memory.swap_used\t8\t1328195471\ntest.sensu-server.memory.free\t52528\t1328195471\ntest.sensu-server.memory.inactive\t57952\t1328195471\ntest.sensu-server.cpu.waiting\t1\t1328195471\ntest.sensu-server.cpu.idle\t95\t1328195471\ntest.sensu-server.cpu.system\t4\t1328195471\ntest.sensu-server.cpu.user\t0\t1328195471\ntest.sensu-server.system.interrupts_per_second\t89\t1328195471\ntest.sensu-server.system.context_switches_per_second\t476\t1328195471\ntest.sensu-server.io.received\t8\t1328195471\ntest.sensu-server.io.sent\t17\t1328195471\ntest.sensu-server.procs.waiting\t4\t1328195471\ntest.sensu-server.procs.uninterruptible\t0\t1328195471\n'</span>, <span style="color: #007800;">children</span>=<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #7a0874; font-weight: bold;">&#93;</span>, <span style="color: #007800;">properties</span>=<span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">'priority'</span>: <span style="color: #000000;">0</span>, <span style="color: #ff0000;">'content type'</span>: <span style="color: #ff0000;">'application/octet-stream'</span>, <span style="color: #ff0000;">'delivery mode'</span>: <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #000000; font-weight: bold;">&gt;</span>
02<span style="color: #000000; font-weight: bold;">/</span>02<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2012</span> <span style="color: #000000;">10</span>:<span style="color: #000000;">11</span>:<span style="color: #000000;">11</span> :: Metric posted: test.sensu-server.swap.in <span style="color: #000000;">0</span> <span style="color: #000000;">1328195471</span>
02<span style="color: #000000; font-weight: bold;">/</span>02<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2012</span> <span style="color: #000000;">10</span>:<span style="color: #000000;">11</span>:<span style="color: #000000;">11</span> :: Metric posted: test.sensu-server.swap.out <span style="color: #000000;">0</span> <span style="color: #000000;">1328195471</span>
02<span style="color: #000000; font-weight: bold;">/</span>02<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2012</span> <span style="color: #000000;">10</span>:<span style="color: #000000;">11</span>:<span style="color: #000000;">11</span> :: Metric posted: test.sensu-server.memory.active <span style="color: #000000;">126856</span> <span style="color: #000000;">1328195471</span>
...</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://joemiller.me/2012/02/02/sensu-and-graphite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Re-use Nagios plugins in Sensu for quick&#160;profit</title>
		<link>http://joemiller.me/2012/01/24/re-use-nagios-plugins-in-sensu-for-quick-profit/</link>
		<comments>http://joemiller.me/2012/01/24/re-use-nagios-plugins-in-sensu-for-quick-profit/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 02:22:17 +0000</pubDate>
		<dc:creator>jmiller</dc:creator>
				<category><![CDATA[devOps]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[sensu]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://joemiller.me/?p=454</guid>
		<description><![CDATA[In my previous article I mentioned a key strength of Sensu is the ability to re-use existing Nagios plugins. This is a powerful feature of Sensu. Nagios has been around for at least 1000 years according to most recent archaeological discoveries, which means a vast amount of human effort (and capital) has gone into creating [...]]]></description>
			<content:encoded><![CDATA[<p>In my previous <a href="http://joemiller.me/2012/01/19/getting-started-with-the-sensu-monitoring-framework/">article</a> I mentioned a key strength of <a href="https://github.com/sonian/sensu">Sensu</a> is the ability to re-use existing Nagios plugins. This is a powerful feature of Sensu. Nagios has been around for at least 1000 years according to most recent archaeological discoveries, which means a vast amount of human effort (and capital) has gone into creating Nagios plugins. Being able to leverage this prior effort is a <a href="http://www.youtube.com/watch?v=gS7KXhK3sro">huge</a> win. In this article I&#8217;ll demonstrate creating a Sensu check with the <a href="http://nagiosplugins.org/man/check_http">check_http</a> Nagios plugin. </p>
<p><span id="more-454"></span></p>
<h2>Install the check_http nagios plugin</h2>
<p>Following on the previous article, we&#8217;ll be doing this demo based off of CentOS 5 but it should not be difficult to find a build of check_http for your distribution.</p>
<p>First, Make sure you have the EPEL yum repo installed on your machine. Next, let&#8217;s install the <code>nagios-plugin-http</code> package onto our Sensu client node(s):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> yum <span style="color: #660033;">-y</span> <span style="color: #c20cb9; font-weight: bold;">install</span> nagios-plugins-http</pre></div></div>

<p>Let&#8217;s see where the <code>check_http</code> binary was installed (note the arch specific path):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ rpm <span style="color: #660033;">-ql</span> nagios-plugins-http
<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib64<span style="color: #000000; font-weight: bold;">/</span>nagios<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>check_http</pre></div></div>

<h2>Write the Sensu check definition</h2>
<p>Ok, now we are ready to create a check definition for Sensu.  We will create this file on the nodes running sensu-client as well as sensu-server (pro tip: this part is easier if you&#8217;re using a CM tool like Chef or Puppet.)</p>
<p><code>/etc/sensu/conf.d/check_google.json</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="json" style="font-family:monospace;">{
  &quot;checks&quot;: {
    &quot;check_google&quot;: {
      &quot;notification&quot;: &quot;Google HTTP failed&quot;,
      &quot;command&quot;: &quot;PATH=$PATH:/usr/lib64/nagios/plugins:/usr/lib/nagios/plugins check_http google.com -R 'search'&quot;,
      &quot;subscribers&quot;: [ &quot;webservers&quot; ],
      &quot;interval&quot;: 60,
      &quot;handlers&quot;: [&quot;default&quot;, &quot;pagerduty&quot;]
    }
  }
}</pre></div></div>

<p>Let&#8217;s look at each part of this check definition:</p>
<ul>
<li>
<code>notification</code>: This can be thought of as a &#8220;friendly message&#8221;. It&#8217;s most useful with handlers like Twitter or Pagerduty. For example, this will be what you hear when the creepy Pagerduty.com computer voice wakes you up at 3 AM. The full output from the check is also available to handlers in the <code>output</code> attribute.</li>
<li>
<code>command</code>: This is where we specify the <code>check_http</code> command we want to run and relevant options. Notice that we are adding both <code>/usr/lib64/...</code> and <code>/usr/lib/...</code> to the PATH. This is not required, but it is a nice way to make this check work on both i386 and x86_64 platforms for the EPEL-supplied version of <code>check_http</code>.</li>
<li>
<code>subscribers</code>: This is where we specify which sensu-client nodes should run this check. Recall that we defined <code>"subscriptions": "webservers"</code> in our <code>/etc/sensu/conf.d/client.json</code> in the previous <a href="http://joemiller.me/2012/01/19/getting-started-with-the-sensu-monitoring-framework/">article</a>.</li>
<li>
<code>interval</code>: How often this check should be executed.</li>
<li>
<code>handlers</code>: The handlers that should receive the output from this plugin. The handlers will be executed on the sensu-server node.</li>
</ul>
<h2>Turn a profit</h2>
<p>After we&#8217;ve created the json file on the clients and servers, we need to restart the sensu-client and sensu-server services so they pickup the new .json file.</p>
<p>In a couple minutes, you should see the following in <code>/var/log/sensu/sensu-server.log</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">I, <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2012</span>-01-23T19:<span style="color: #000000;">14</span>:<span style="color: #000000;">22.218301</span> <span style="color: #666666; font-style: italic;">#7397]  INFO -- : [publisher] -- publishing check request -- check_google -- webservers {&quot;message&quot;:&quot;[publisher] -- publishing check request -- check_google -- webservers&quot;,&quot;level&quot;:&quot;info&quot;,&quot;timestamp&quot;:&quot;2012-01-23T19:14:22.   %6N-0700&quot;}</span></pre></div></div>

<p>And on the client, in <code>/var/log/sensu/sensu-client.log</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">I, <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2012</span>-01-23T19:<span style="color: #000000;">15</span>:<span style="color: #000000;">22.224437</span> <span style="color: #666666; font-style: italic;">#18787]  INFO -- : [subscribe] -- received check request -- check_google {&quot;message&quot;:&quot;[subscribe] -- received check request -- check_google&quot;,&quot;level&quot;:&quot;info&quot;,&quot;timestamp&quot;:&quot;2012-01-23T19:15:22.   %6N-0700&quot;}</span>
I, <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2012</span>-01-23T19:<span style="color: #000000;">15</span>:<span style="color: #000000;">22.348884</span> <span style="color: #666666; font-style: italic;">#18787]  INFO -- : [result] -- publishing check result -- check_google -- 0 -- HTTP OK: HTTP/1.0 200 OK - 11294 bytes in 0.099 second response time |time=0.099463s;;;0.000000 size=11294B;;;0</span></pre></div></div>

<p>There we go. We have implemented a Sensu check using a Nagios plugin. There are quite a few <a href="http://nagiosplugins.org/">Nagios plugins</a> out there and we should be able to use most (all?) of them with Sensu. Go forth and profit.</p>
<p>For questions on using Sensu, stop by the #sensu channel on Freenode.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemiller.me/2012/01/24/re-use-nagios-plugins-in-sensu-for-quick-profit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting started with the Sensu monitoring&#160;framework</title>
		<link>http://joemiller.me/2012/01/19/getting-started-with-the-sensu-monitoring-framework/</link>
		<comments>http://joemiller.me/2012/01/19/getting-started-with-the-sensu-monitoring-framework/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 03:18:25 +0000</pubDate>
		<dc:creator>jmiller</dc:creator>
				<category><![CDATA[devOps]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[sensu]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://joemiller.me/?p=419</guid>
		<description><![CDATA[(5/15/2012) NOTE: This guide has been superseded by the official &#8216;Install Guide&#8216; doc on the Sensu wiki. The new process utilizes the simpler Omnibus-style Sensu packages and covers installation on Debian/Ubuntu platforms as well. Please use this guide instead of the instructions below. I&#8217;m excited about Sensu, a new open source monitoring framework, and I&#8217;d [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>
(5/15/2012) NOTE:  This guide has been superseded by the official &#8216;<a href="https://github.com/sensu/sensu/wiki/Install-Guide" title="Install Guide">Install Guide</a>&#8216; doc on the Sensu wiki. The new process utilizes the simpler Omnibus-style Sensu packages and covers installation on Debian/Ubuntu platforms as well. Please use this guide instead of the instructions below.
</p></blockquote>
<p>I&#8217;m excited about <a href="http://www.sonian.com/cloud-tools/cloud-monitoring-sensu/">Sensu</a>, a new open source monitoring framework, and I&#8217;d like to help others get started with it as well. So, after observing the frequent questions from new visitors to #sensu on Freenode I thought perhaps the best way to do that is to write a blog article to help folks get started. If you still have questions after reading this, feel free to come by #sensu on Freenode.</p>
<p>In this article I will provide a brief overview of Sensu with some background, walk through a client and server install, and then I will show you how to add a check and a handler. This should lay the groundwork for future articles with more examples on how to get the most value out of Sensu in your infrastructure.</p>
<p>Before we start, I owe a huge thanks to <a href="http://twitter.com/jeremy_carroll">@jeremy_carroll</a> for the many hours of work he put into building RPM&#8217;s for Sensu. His work on packaging will undoubtedly save many folks quite a bit of time.</p>
<h2>What is Sensu?</h2>
<p>Sensu is the creation of <a href="http://twitter.com/portertech">@portertech</a> and his colleagues at <a href="http://sonian.com">sonian.com</a>. They have graciously open-sourced the project and made it available to all of us searching for a modern monitoring platform (or anyone searching for an alternative to Nagios.)</p>
<p>Sensu is often described as the &#8220;monitoring router&#8221;. Put another way, Sensu connects the output from &#8220;check&#8221; scripts run across many nodes with &#8220;handler&#8221; scripts run on Sensu servers. Messages are passed via RabbitMQ. Checks are used, for example, to determine if Apache is up or down. Checks can also be used to collect metrics such as MySQL statistics. The output of checks is routed to one or more handlers. Handlers determine what to do with the results of checks. Handlers currently exist for sending alerts to Pagerduty, IRC, Twitter, etc. Handlers can also feed metrics into Graphite, Librato, etc. Writing checks and handlers is quite simple and can be done in any language.</p>
<p>Key details:</p>
<ul>
<li>Ruby 1.8.7+ (EventMachine, Sinatra, AMQP), RabbitMQ, Redis</li>
<li>Excellent test coverage with continuous integration (<a href="http://travis-ci.org/#!/sonian/sensu">travis-ci</a>)
</li>
<li>Messaging oriented architecture. Messages are JSON objects.</li>
<li>Ability to re-use existing Nagios plugins</li>
<li>Plugins and handlers (think notifications) can be written in any language</li>
<li>Supports sending metrics into various backends (Graphite, Librato, etc)</li>
<li>Designed with modern configuration management systems such as Chef or Puppet in mind</li>
<li>Designed for cloud environments</li>
<li>Lightweight, less than 1200 lines of code</li>
</ul>
<p><span id="more-419"></span></p>
<h2>Components</h2>
<p>Sensu is made up of several small components. I won&#8217;t go into too much detail about each of them here, as their purpose will become obvious when we get started, so here a few short descriptions:</p>
<h3>sensu-server</h3>
<p>The server initiates checks on clients, receives the output of the checks feeds them to handlers. (As of version 0.9.2, clients can also execute checks that the server doesn&#8217;t know about and the server will still process their results, more on these &#8216;standalone checks&#8217; in a future article.)</p>
<p>Sensu-server relies on a Redis instance to keep persistent data. It also relies heavily (as do most sensu components) on access to rabbitmq for passing data between itself and sensu-client nodes.</p>
<h3>sensu-client</h3>
<p>Run this on all of your systems that you want to monitor. Sensu-client will execute checks scripts (think <code>check_http</code>, <code>check_load</code>, etc) and return the results from these checks to sensu-server via rabbitmq.</p>
<h3>sensu-api</h3>
<p>A REST API that provides access to various pieces of data maintained on the sensu-server in Redis. You will typically run this on the same server as your sensu-server or Redis instance. It is mostly used by internal sensu components at this time.</p>
<h3>sensu-dashboard</h3>
<p>Web dashboard providing an overview of the current state of your Sensu infrastructure and the ability to perform actions, such as temporarily silencing alerts.</p>
<h2>Installing</h2>
<p>As you start to explore Sensu you will find that it was built from the start to be used in conjunction with a CM tool such as Chef or Puppet. However, for the purposes of this article I will walk through a simple manual install. </p>
<p>This article covers installation of Sensu via RPM on CentOS-5 and CentOS-6. Debian/ubuntu and derivatives are not covered in this guide, but many of the same steps will apply. At this time there are no .deb packages for the Sensu components so you will have to install Sensu from gem (ie: <code>gem install sensu sensu-dashboard</code>). Hopefully soon we will have native .deb packages for the Sensu components.</p>
<p>One thing to note when installing from gem: you may get an error when starting sensu-server or sensu-client if you do not have a &#8220;client&#8221; section defined in your config and if you don&#8217;t have at least one &#8220;check&#8221;.</p>
<p>You will probably want to use Sensu with Chef or Puppet soon after you get bootstrapped (of course you&#8217;re already using a modern CM tool in your infrastructure anyway, right?) There are good <a href="https://github.com/sonian/sensu/tree/master/dist/chef">Chef</a> and <a href="https://github.com/sonian/sensu/tree/master/dist/puppet">Puppet</a> recipes in the github repos that can help you get going fairly quickly. There are also a few community members working on improving these pieces so should get even better over time.</p>
<p>Additionally, the original dev platform for Sensu was Ubuntu but work has been done to help make it a little more CentOS/RHEL-friendly. I&#8217;m going to use CentOS 5 and 6 in this article just because I&#8217;m more familiar with this platform than the debian/ubuntu family. In any case, it shouldn&#8217;t matter too much because the purpose of this article is to show you Sensu.</p>
<p>We will use 2 nodes, one will be our server and the other will be a simple client, with the following bits on each:</p>
<p>Server:</p>
<ul>
<li>rabbitmq</li>
<li>redis</li>
<li>sensu-server / sensu-client / sensu-api / sensu-dashboard</li>
</ul>
<p>Client:</p>
<ul>
<li>sensu-client</li>
</ul>
<h2>Install a Sensu server node</h2>
<h3>Install rabbitmq</h3>
<p>We will base our approach on the rabbit install guide from here: <a href="http://www.rabbitmq.com/install-rpm.html"></a><a href="http://www.rabbitmq.com/install-rpm.html">http://www.rabbitmq.com/install-rpm.html</a></p>
<p>(CentOS 5 only) We need to install both the EPEL-5 and epel-erlang yum repos. The EPEL-5 yum repo contains the older R12B version of Erlang which would work fine with rabbit except we wouldn&#8217;t have access to SSL nor the web management plugins. Thus, we&#8217;ll be installing a newer Erlang from the <code>epel-erlang</code> repo which provides R14B for cent5.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> rpm <span style="color: #660033;">-Uvh</span> http:<span style="color: #000000; font-weight: bold;">//</span>dl.fedoraproject.org<span style="color: #000000; font-weight: bold;">/</span>pub<span style="color: #000000; font-weight: bold;">/</span>epel<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">5</span><span style="color: #000000; font-weight: bold;">/</span>i386<span style="color: #000000; font-weight: bold;">/</span>epel-release-<span style="color: #000000;">5</span>-<span style="color: #000000;">4</span>.noarch.rpm
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">wget</span> <span style="color: #660033;">-O</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>yum.repos.d<span style="color: #000000; font-weight: bold;">/</span>epel-erlang.repo http:<span style="color: #000000; font-weight: bold;">//</span>repos.fedorapeople.org<span style="color: #000000; font-weight: bold;">/</span>repos<span style="color: #000000; font-weight: bold;">/</span>peter<span style="color: #000000; font-weight: bold;">/</span>erlang<span style="color: #000000; font-weight: bold;">/</span>epel-erlang.repo</pre></div></div>

<p>(CentOS 6 only) Install the EPEL-6 yum repo which contains Erlang R14B:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> rpm <span style="color: #660033;">-Uvh</span> http:<span style="color: #000000; font-weight: bold;">//</span>download.fedoraproject.org<span style="color: #000000; font-weight: bold;">/</span>pub<span style="color: #000000; font-weight: bold;">/</span>epel<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">6</span><span style="color: #000000; font-weight: bold;">/</span>i386<span style="color: #000000; font-weight: bold;">/</span>epel-release-<span style="color: #000000;">6</span>-<span style="color: #000000;">5</span>.noarch.rpm</pre></div></div>

<p>Install Erlang:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> yum <span style="color: #c20cb9; font-weight: bold;">install</span> erlang</pre></div></div>

<p>Install RabbitMQ:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> rpm <span style="color: #660033;">--import</span> http:<span style="color: #000000; font-weight: bold;">//</span>www.rabbitmq.com<span style="color: #000000; font-weight: bold;">/</span>rabbitmq-signing-key-public.asc
<span style="color: #c20cb9; font-weight: bold;">sudo</span> rpm <span style="color: #660033;">-Uvh</span> http:<span style="color: #000000; font-weight: bold;">//</span>www.rabbitmq.com<span style="color: #000000; font-weight: bold;">/</span>releases<span style="color: #000000; font-weight: bold;">/</span>rabbitmq-server<span style="color: #000000; font-weight: bold;">/</span>v2.7.1<span style="color: #000000; font-weight: bold;">/</span>rabbitmq-server-2.7.1-<span style="color: #000000;">1</span>.noarch.rpm</pre></div></div>

<p>We need to make some SSL certs for our rabbitmq server and the sensu clients. I put a simple script up on <a href="https://github.com/joemiller/joemiller.me-intro-to-sensu">github</a> to help with this. You&#8217;ll want to change a few things in the <code>openssl.cnf</code> to for your organization if you use this in production. The script will generate a few files that we&#8217;ll need throughout the guide, so keep them nearby.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git</span> clone <span style="color: #c20cb9; font-weight: bold;">git</span>:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>joemiller<span style="color: #000000; font-weight: bold;">/</span>joemiller.me-intro-to-sensu.git
<span style="color: #7a0874; font-weight: bold;">cd</span> joemiller.me-intro-to-sensu<span style="color: #000000; font-weight: bold;">/</span>
.<span style="color: #000000; font-weight: bold;">/</span>ssl_certs.sh clean
.<span style="color: #000000; font-weight: bold;">/</span>ssl_certs.sh generate</pre></div></div>

<p>Configure RabbitMQ to use these SSL certs</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rabbitmq<span style="color: #000000; font-weight: bold;">/</span>ssl
<span style="color: #c20cb9; font-weight: bold;">cp</span> server_key.pem <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rabbitmq<span style="color: #000000; font-weight: bold;">/</span>ssl<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #c20cb9; font-weight: bold;">cp</span> server_cert.pem <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rabbitmq<span style="color: #000000; font-weight: bold;">/</span>ssl<span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #c20cb9; font-weight: bold;">cp</span> testca<span style="color: #000000; font-weight: bold;">/</span>cacert.pem <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>rabbitmq<span style="color: #000000; font-weight: bold;">/</span>ssl<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>Create <code>/etc/rabbitmq/rabbitmq.config</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="erlang" style="font-family:monospace;"><span style="color: #109ab8;">&#91;</span>
  <span style="color: #109ab8;">&#123;</span>rabbit<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span>
    <span style="color: #109ab8;">&#123;</span>ssl_listeners<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #ff9600;">5671</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span>
    <span style="color: #109ab8;">&#123;</span>ssl_options<span style="color: #6bb810;">,</span> <span style="color: #109ab8;">&#91;</span><span style="color: #109ab8;">&#123;</span>cacertfile<span style="color: #6bb810;">,</span><span style="color: #ff7800;">&quot;/etc/rabbitmq/ssl/cacert.pem&quot;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span>
                   <span style="color: #109ab8;">&#123;</span>certfile<span style="color: #6bb810;">,</span><span style="color: #ff7800;">&quot;/etc/rabbitmq/ssl/server_cert.pem&quot;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span>
                   <span style="color: #109ab8;">&#123;</span>keyfile<span style="color: #6bb810;">,</span><span style="color: #ff7800;">&quot;/etc/rabbitmq/ssl/server_key.pem&quot;</span><span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span>
                   <span style="color: #109ab8;">&#123;</span>verify<span style="color: #6bb810;">,</span>verify_peer<span style="color: #109ab8;">&#125;</span><span style="color: #6bb810;">,</span>
                   <span style="color: #109ab8;">&#123;</span>fail_if_no_peer_cert<span style="color: #6bb810;">,</span>true<span style="color: #109ab8;">&#125;</span><span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#125;</span>
  <span style="color: #109ab8;">&#93;</span><span style="color: #109ab8;">&#125;</span>
<span style="color: #109ab8;">&#93;</span><span style="color: #6bb810;">.</span></pre></div></div>

<p>Install the RabbitMQ webUI management console:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">rabbitmq-plugins <span style="color: #7a0874; font-weight: bold;">enable</span> rabbitmq_management</pre></div></div>

<p>Set RabbitMQ to start on boot and start it up immediately:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>chkconfig rabbitmq-server on
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>rabbitmq-server start</pre></div></div>

<p>Verify operation with the RabbitMQ Web UI: Username is &#8220;guest&#8221;, password is &#8220;guest&#8221; &#8211; <code>http://&lt;SENSU-SERVER&gt;:55672</code>. Protocol amqp should be bound to port 5672 and amqp/ssl on port 5671.</p>
<p>Finally, let&#8217;s create a <code>/sensu</code> vhost and a <code>sensu</code> user/password on our rabbit:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">rabbitmqctl add_vhost <span style="color: #000000; font-weight: bold;">/</span>sensu
rabbitmqctl add_user sensu mypass
rabbitmqctl set_permissions <span style="color: #660033;">-p</span> <span style="color: #000000; font-weight: bold;">/</span>sensu sensu <span style="color: #ff0000;">&quot;.*&quot;</span> <span style="color: #ff0000;">&quot;.*&quot;</span> <span style="color: #ff0000;">&quot;.*&quot;</span></pre></div></div>

<h3>Install redis</h3>
<p>At this point we already have the EPEL repo installed on our server so we will install EPEL&#8217;s version of Redis. For Cent5 this will be a fairly old redis v2.0, and for Cent6 it will be v2.2. Both should work fine with Sensu.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> yum <span style="color: #c20cb9; font-weight: bold;">install</span> redis
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #000000; font-weight: bold;">/</span>sbin<span style="color: #000000; font-weight: bold;">/</span>chkconfig redis on
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>redis start</pre></div></div>

<h3>Install ruby 1.8.7</h3>
<p>(CentOS 5 only) Sensu needs ruby 1.8.7+ but CentOS-5 ships with older Ruby 1.8.5. We will use the ruby 1.8.7 rpm&#8217;s from Opscode&#8217;s Chef. See <a href="http://wiki.opscode.com/display/chef/Installing+Chef+Client+on+CentOS#InstallingChefClientonCentOS-InstallRuby">this page on the Chef wiki</a> for additional details.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #c20cb9; font-weight: bold;">wget</span> <span style="color: #660033;">-O</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>yum.repos.d<span style="color: #000000; font-weight: bold;">/</span>aegisco.repo http:<span style="color: #000000; font-weight: bold;">//</span>rpm.aegisco.com<span style="color: #000000; font-weight: bold;">/</span>aegisco<span style="color: #000000; font-weight: bold;">/</span>el5<span style="color: #000000; font-weight: bold;">/</span>aegisco.repo</pre></div></div>

<p>(CentOS 6) CentOS 6 ships with ruby 1.8.7 so we don&#8217;t need any external repos.</p>
<p>Install Ruby packages;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> yum <span style="color: #c20cb9; font-weight: bold;">install</span> ruby ruby-ri ruby-rdoc ruby-shadow rubygems curl openssl-devel</pre></div></div>

<h3>Install Sensu components.</h3>
<p>Now we are ready to install Sensu. We will install two rpms: <code>rubygem-sensu</code> and <code>rubygem-sensu-dashboard</code>. This will install four components: sensu-server, sensu-client, sensu-api, sensu-dashboard. Sensu servers use all of these and clients only use sensu-client.</p>
<p>We are going to use <a href="http://twitter.com/jeremy_carroll">@jeremy_carroll</a>&#8216;s recently created yum repo to install Sensu via rpm. This repo contains sensu rpm&#8217;s for both CentOS 5 and 6. It&#8217;s awesome that Jeremy has taken the time to set this up and I hope we can use this as a basis for automating the building of rpms and debs for all releases of Sensu. Since this repo was setup pretty much as this blog was being written, it&#8217;s possible that this repo will move to a different location in the future.</p>
<p>(CentOS 5 only)</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> rpm <span style="color: #660033;">-Uvh</span> http:<span style="color: #000000; font-weight: bold;">//</span>yum.carrollops.com<span style="color: #000000; font-weight: bold;">/</span>el<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">5</span><span style="color: #000000; font-weight: bold;">/</span>sensu-release-<span style="color: #000000;">1</span>.noarch.rpm</pre></div></div>

<p>(CentOS 6 only)</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> rpm <span style="color: #660033;">-Uvh</span> http:<span style="color: #000000; font-weight: bold;">//</span>yum.carrollops.com<span style="color: #000000; font-weight: bold;">/</span>el<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">6</span><span style="color: #000000; font-weight: bold;">/</span>sensu-release-<span style="color: #000000;">1</span>.noarch.rpm</pre></div></div>

<p>We need to ignore the rubygem rpm&#8217;s that come from EPEL because they will conflict with the sensu rpm&#8217;s. Edit your <code>/etc/yum.repos.d/epel.repo</code> file and add the following line to the [epel] section.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">exclude</span>=rubygem-rack,rubygem-sinatra</pre></div></div>

<p>Install and enable sensu service components:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> yum <span style="color: #c20cb9; font-weight: bold;">install</span> rubygem-sensu rubygem-sensu-dashboard
<span style="color: #c20cb9; font-weight: bold;">sudo</span> chkconfig sensu-server on
<span style="color: #c20cb9; font-weight: bold;">sudo</span> chkconfig sensu-api on
<span style="color: #c20cb9; font-weight: bold;">sudo</span> chkconfig sensu-client on
<span style="color: #c20cb9; font-weight: bold;">sudo</span> chkconfig sensu-dashboard on</pre></div></div>

<p>Copy the SSL client key + cert that we created earlier into <code>/etc/sensu/ssl</code></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">cp</span> client_key.pem client_cert.pem  <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>sensu<span style="color: #000000; font-weight: bold;">/</span>ssl<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>Next we need to configure sensu by editing <code>/etc/sensu/config.json</code>. For now we will create just enough config to start sensu. Later we will add checks and handlers. Note (for later use) that Sensu will also read json config snippets out of the  <code>/etc/sensu/conf.d</code> directory so you can piece together a config easily using your CM tool.</p>

<div class="wp_syntax"><div class="code"><pre class="json" style="font-family:monospace;">{
  &quot;rabbitmq&quot;: {
    &quot;ssl&quot;: {
      &quot;private_key_file&quot;: &quot;/etc/sensu/ssl/client_key.pem&quot;,
      &quot;cert_chain_file&quot;: &quot;/etc/sensu/ssl/client_cert.pem&quot;
    },
    &quot;port&quot;: 5671,
    &quot;host&quot;: &quot;localhost&quot;,
    &quot;user&quot;: &quot;sensu&quot;,
    &quot;password&quot;: &quot;mypass&quot;,
    &quot;vhost&quot;: &quot;/sensu&quot;
  },
  &quot;redis&quot;: {
    &quot;host&quot;: &quot;localhost&quot;,
    &quot;port&quot;: 6379
  },
  &quot;api&quot;: {
    &quot;host&quot;: &quot;localhost&quot;,
    &quot;port&quot;: 4567
  },
  &quot;dashboard&quot;: {
    &quot;host&quot;: &quot;localhost&quot;,
    &quot;port&quot;: 8080,
    &quot;user&quot;: &quot;admin&quot;,
    &quot;password&quot;: &quot;secret&quot;
  }
}</pre></div></div>

<p>Configure <code>/etc/sensu/conf.d/client.json</code> for the current node:</p>

<div class="wp_syntax"><div class="code"><pre class="json" style="font-family:monospace;">{
  &quot;client&quot;: {
    &quot;name&quot;: &quot;sensu-server.dom.tld&quot;,
    &quot;address&quot;: &quot;10.0.0.1&quot;,
    &quot;subscriptions&quot;: [ &quot;test&quot; ]
  }
}</pre></div></div>

<p>(CentOS 5 x86_64 only) With the current set of rpm&#8217;s we need to add a path to the GEM_PATH in order to find a couple of the rubygems we installed. Run the following:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;export GEM_PATH=<span style="color: #000099; font-weight: bold;">\$</span>GEM_PATH:/usr/lib64/ruby/gems/1.8&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>profile.d<span style="color: #000000; font-weight: bold;">/</span>gem_path.sh
. <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>profile.d<span style="color: #000000; font-weight: bold;">/</span>gem_path.sh</pre></div></div>

<p>Now let&#8217;s try to start the Sensu components:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>sensu-server start
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>sensu-api start
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>sensu-client start    
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>sensu-dashboard start</pre></div></div>

<p>If all goes well, the 4 processes mentioned above will be running and the dashboard will be accessible on <code>http://&lt;SENSU SERVER&gt;:8080</code>. Log files are available in <code>/var/log/sensu</code> in case anything is wrong.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">sensu    <span style="color: #000000;">14249</span>  <span style="color: #000000;">0.0</span>  <span style="color: #000000;">3.4</span>  <span style="color: #000000;">92924</span> <span style="color: #000000;">17648</span> ?        S    02:<span style="color: #000000;">56</span>   <span style="color: #000000;">0</span>:00 ruby <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>sensu-server ...
sensu    <span style="color: #000000;">14404</span>  <span style="color: #000000;">0.0</span>  <span style="color: #000000;">4.1</span> <span style="color: #000000;">102172</span> <span style="color: #000000;">20884</span> ?        S    03:05   <span style="color: #000000;">0</span>:00 ruby <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>sensu-api ...
sensu    <span style="color: #000000;">14425</span>  <span style="color: #000000;">0.0</span>  <span style="color: #000000;">3.7</span> <span style="color: #000000;">104860</span> <span style="color: #000000;">19292</span> ?        Sl   03:06   <span style="color: #000000;">0</span>:00 ruby <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>sensu-client ...
sensu    <span style="color: #000000;">14553</span>  <span style="color: #000000;">0.4</span>  <span style="color: #000000;">7.0</span> <span style="color: #000000;">140544</span> <span style="color: #000000;">35932</span> ?        Sl   03:07   <span style="color: #000000;">0</span>:00 ruby <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>sensu-dashboard ...</pre></div></div>

<p>If you see an openssl error like the one below on CentOS-5, it&#8217;s likely because you&#8217;re on a x86_64 box but some ruby-libs or ruby-devel 1.8.5 rpm&#8217;s from the base repo were accidentally installed, remove them.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">Starting sensu-client: <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>ruby<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">1.8</span><span style="color: #000000; font-weight: bold;">/</span>openssl<span style="color: #000000; font-weight: bold;">/</span>cipher.rb:<span style="color: #000000;">22</span>: Cipher is not a module <span style="color: #7a0874; font-weight: bold;">&#40;</span>TypeError<span style="color: #7a0874; font-weight: bold;">&#41;</span>
    from <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>ruby<span style="color: #000000; font-weight: bold;">/</span>site_ruby<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">1.8</span><span style="color: #000000; font-weight: bold;">/</span>rubygems<span style="color: #000000; font-weight: bold;">/</span>custom_require.rb:<span style="color: #000000;">36</span>:<span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">`</span>gem_original_require<span style="color: #ff0000;">'</span></pre></div></div>

<h2>Installing a sensu client node</h2>
<p>Installing Sensu on a client node is similar to installing the server. We will need to install ruby, the Sensu rpm, and then configure Sensu. There are only a few small differences which are detailed below.</p>
<h3>Install ruby 1.8.7</h3>
<p>Follow the same steps from the <code>Install ruby 1.8.7</code> section we used to build our server.</p>
<h3>Install sensu-client</h3>
<p>Follow the steps from <code>Install Sensu components</code> section we used to build our server, with the following differences:</p>
<ul>
<li>Only install <code>rubygem-sensu</code> and skip <code>rubygem-sensu-dashboard</code>
</li>
<li>You will only need the <code>rabbitmq</code> section in <code>/etc/sensu/config.json</code> file. Make sure you point it to your rabbit server.</li>
<li>Only enable and start the <code>sensu-client</code> service, ie: <code>chkconfig sensu-client on</code> and <code>/etc/init.d/sensu-client start</code>.</li>
</ul>
<p>The client will log to <code>/var/log/sensu/sensu-client.log</code>.</p>
<h2>Add a check</h2>
<p>Now that we&#8217;ve installed a Sensu server and a client, let&#8217;s create a simple check so we can begin to see how the pieces fit together. We&#8217;re going to write a check to determine if <code>crond</code> is running. We&#8217;ll be using the <code>check-procs.rb</code> script from the <a href="https://github.com/sonian/sensu-community-plugins">sensu-community-plugins</a> repo.</p>
<p>Most of the plugins in the <a href="https://github.com/sonian/sensu-community-plugins">sensu-community-plugins</a> repo rely on the helper classes from the sensu-plugins gem, so let&#8217;s install that first. You may need to install gcc in order to build the json gem dependency. Note that we are installing this from a gem because there is not an rpm available yet.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> gem <span style="color: #c20cb9; font-weight: bold;">install</span> sensu-plugin <span style="color: #660033;">--no-rdoc</span> <span style="color: #660033;">--no-ri</span></pre></div></div>

<p>Next, we&#8217;re going to grab the <code>check-procs.rb</code> script directly from github and install it into <code>/etc/sensu/plugins</code>. You don&#8217;t have to install checks into this directory, but it&#8217;s convenient.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">wget</span> <span style="color: #660033;">-O</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>sensu<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>check-procs.rb https:<span style="color: #000000; font-weight: bold;">//</span>raw.github.com<span style="color: #000000; font-weight: bold;">/</span>sonian<span style="color: #000000; font-weight: bold;">/</span>sensu-community-plugins<span style="color: #000000; font-weight: bold;">/</span>master<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>processes<span style="color: #000000; font-weight: bold;">/</span>check-procs.rb
<span style="color: #c20cb9; font-weight: bold;">chmod</span> <span style="color: #000000;">755</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>sensu<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>check-procs.rb</pre></div></div>

<p>Let&#8217;s create a new json file to hold our check definition in <code>/etc/sensu/conf.d/check_cron.json</code>. Put this file on both the Sensu server and client. </p>
<p>(NOTE: as of sensu 0.9.2 &#8216;standalone&#8217; checks were added which only need to be configured on the client-side. We will cover standalone checks in future articles.)</p>

<div class="wp_syntax"><div class="code"><pre class="json" style="font-family:monospace;">{
  &quot;checks&quot;: {
    &quot;cron_check&quot;: {
      &quot;handler&quot;: &quot;default&quot;,
      &quot;command&quot;: &quot;/etc/sensu/plugins/check-procs.rb -p crond -C 1 &quot;,
      &quot;interval&quot;: 60,
      &quot;subscribers&quot;: [ &quot;webservers&quot; ]
    }
  }
}</pre></div></div>

<p>Next, we need to tell our client node to listen to subscribe to the <code>webservers</code> queue. The Sensu server will publish a request every 60 seconds on the <code>webservers</code> queue and any client registered to this queue will execute checks that have been registered to this queue. Edit the <code>/etc/sensu/conf.d/client.json</code> file on the client:</p>

<div class="wp_syntax"><div class="code"><pre class="json" style="font-family:monospace;">{
  &quot;client&quot;: {
    &quot;name&quot;: &quot;sensu-client.domain.tld&quot;,
    &quot;address&quot;: &quot;127.0.0.1&quot;,
    &quot;subscriptions&quot;: [ &quot;test&quot;, &quot;webservers&quot; ]
  }
}</pre></div></div>

<p>Finally, restart sensu on the client and server nodes.</p>
<p>After a few minutes we should see the following in the <code>/var/log/sensu/sensu-client.log</code> on the client:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">I, <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2012</span>-01-18T21:<span style="color: #000000;">17</span>:<span style="color: #000000;">07.561000</span> <span style="color: #666666; font-style: italic;">#12984]  INFO -- : [subscribe] -- received check request -- cron_check {&quot;message&quot;:&quot;[subscribe] -- received check request -- cron_check&quot;,&quot;level&quot;:&quot;info&quot;,&quot;timestamp&quot;:&quot;2012-01-18T21:17:07.   %6N-0700&quot;}</span></pre></div></div>

<p>And on the server we should see the following in <code>/var/log/sensu/sensu-server.log</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">I, <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2012</span>-01-18T21:<span style="color: #000000;">18</span>:<span style="color: #000000;">07.559666</span> <span style="color: #666666; font-style: italic;">#30970]  INFO -- : [publisher] -- publishing check request -- cron_check -- webservers {&quot;message&quot;:&quot;[publisher] -- publishing check request -- cron_check -- webservers&quot;,&quot;level&quot;:&quot;info&quot;,&quot;timestamp&quot;:&quot;2012-01-18T21:18:07.   %6N-0700&quot;}</span>
I, <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2012</span>-01-18T21:<span style="color: #000000;">25</span>:<span style="color: #000000;">07.745012</span> <span style="color: #666666; font-style: italic;">#30970]  INFO -- : [result] -- received result -- sensu-client.domain.tld -- cron_check -- 0 -- CheckProcs OK: Found 1 matching processes; cmd /crond/</span></pre></div></div>

<p>Next, let&#8217;s see if we can raise an alert.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>crond stop</pre></div></div>

<p>After about a minute we should see an alert on the sensu-dashboard: <code>http://&lt;SERVER IP&gt;:8080</code></p>
<p><a href="http://joemiller.me/wp-content/uploads/2012/01/dashboard-screenshot.png"><img src="http://joemiller.me/wp-content/uploads/2012/01/dashboard-screenshot.png" alt="" title="sensu-dashboard" width="693" height="277" class="aligncenter size-full wp-image-443" /></a></p>
<h2>Add a handler</h2>
<p>Now that we have created our first check we are ready to hook it up to a handler. Out of the box Sensu ships with a &#8216;default&#8217; handler which does nothing more than parse the JSON its fed via STDIN and spits back to STDOUT. </p>
<p>There is a growing list of handlers available in the <a href="https://github.com/sonian/sensu-community-plugins/tree/master/handlers">sensu-community-plugins</a> repo, including Pagerduty, IRC, Campfire, etc.</p>
<p>Let&#8217;s create a simple handler that simply sends the raw check output to ourselves via email.</p>
<p>The most common handler type is &#8220;pipe&#8221; which tells Sensu to shell out and run the specified command. We&#8217;ll cover more handler types in the future. On the server nodes, we will define our &#8216;email&#8217; handler in <code>/etc/sensu/conf.d/handler_email.json</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="json" style="font-family:monospace;">{
  &quot;handlers&quot;: {
    &quot;email&quot;: {
      &quot;type&quot;: &quot;pipe&quot;,
      &quot;command&quot;: &quot;mail -s 'sensu alert' your@address&quot;
    }
  }
}</pre></div></div>

<p>On the sensu-server and sensu-client nodes we&#8217;ll also need to update our check definition and connect it to the new handler, edit the <code>/etc/sensu/conf.d/check_cron.json</code> files and modify the &#8220;handlers&#8221; attribute:</p>

<div class="wp_syntax"><div class="code"><pre class="json" style="font-family:monospace;">{
  &quot;checks&quot;: {
    &quot;cron_check&quot;: {
      &quot;handlers&quot;: [&quot;default&quot;, &quot;email&quot;],
 ...</pre></div></div>

<p>Restart sensu-client and sensu-server on the nodes and then stop the crond daemon again. In a few minutes we should get an email from sensu with the subject &#8220;sensu alert&#8221; and a bag full of JSON data.</p>
<p>This isn&#8217;t the most useful handler but it illustrates the concepts of checks and handlers and how they work together. At this point we now have a working sensu-client and sensu-server to start experimenting further. In the future we&#8217;ll cover more examples of checks, handlers, metrics, etc.</p>
<p>If you have further questions please visit #sensu on IRC Freenode.</p>
<p><strong>Update (3/2/2012):</strong> Olivier Le Cam (<a href="https://twitter.com/#!/olecam" title="@olecam">@olecam</a>) <a href="http://olecam.online.fr/sensu-debian.txt" title="sensu-debian">posted</a> some Debian-specific instructions that accompany this process which also include instructions on building .deb packages for Sensu.</p>
<p><strong>More Sensu articles:</strong> <a href="http://joemiller.me/category/sensu/" title="sensu">sensu</a></p>
]]></content:encoded>
			<wfw:commentRss>http://joemiller.me/2012/01/19/getting-started-with-the-sensu-monitoring-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Correlating Puppet changes to events in your infrastructure using&#160;graphite</title>
		<link>http://joemiller.me/2011/11/05/correlating-puppet-changes-to-events-in-your-infrastructure/</link>
		<comments>http://joemiller.me/2011/11/05/correlating-puppet-changes-to-events-in-your-infrastructure/#comments</comments>
		<pubDate>Sun, 06 Nov 2011 02:09:15 +0000</pubDate>
		<dc:creator>jmiller</dc:creator>
				<category><![CDATA[devOps]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[puppet]]></category>
		<category><![CDATA[metrics]]></category>

		<guid isPermaLink="false">http://joemiller.me/?p=402</guid>
		<description><![CDATA[Sometimes it is pretty obvious when Puppet changes something in your infrastructure and bad things happen in a big dramatic way. Other times it&#8217;s not so obvious. It can be invaluable to be able to correlate changes made by Puppet to other events happening in your infrastructure. For example, in this diagram we have plotted [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes it is pretty obvious when Puppet changes something in your infrastructure and bad things happen in a big dramatic way. Other times it&#8217;s not so obvious. It can be invaluable to be able to correlate changes made by Puppet to other events happening in your infrastructure.</p>
<p>For example, in this diagram we have plotted the load average from a group of servers. Blue vertical lines mark points in time when puppet modified a resource on a host in the group. We can see that immediately following a puppet change the load spiked on one of the servers.</p>
<p><a href="http://joemiller.me/wp-content/uploads/2011/11/graphite-puppet-event-example-720x300-crop.png"><img class="aligncenter size-full wp-image-410" title="graphite-puppet-event-example-720x300-crop" src="http://joemiller.me/wp-content/uploads/2011/11/graphite-puppet-event-example-720x300-crop.png" alt="" width="720" height="300" /></a></p>
<p>Code available on github:</p>
<ul>
<li><a title="https://github.com/joemiller/puppet-graphite_event" href="https://github.com/joemiller/puppet-graphite_event">https://github.com/joemiller/puppet-graphite_event</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://joemiller.me/2011/11/05/correlating-puppet-changes-to-events-in-your-infrastructure/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>List of statsd server&#160;implementations</title>
		<link>http://joemiller.me/2011/09/21/list-of-statsd-server-implementations/</link>
		<comments>http://joemiller.me/2011/09/21/list-of-statsd-server-implementations/#comments</comments>
		<pubDate>Wed, 21 Sep 2011 18:34:46 +0000</pubDate>
		<dc:creator>jmiller</dc:creator>
				<category><![CDATA[devOps]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://joemiller.me/?p=339</guid>
		<description><![CDATA[Statsd is a simple client/server mechanism from the folks at Etsy that allows operations and development teams to easily feed a variety of metrics into a Graphite system. For more info on statsd read the seminal blog article on Statsd &#8220;Measure Anything, Measure Everything&#8221;. As would be expected there are statsd clients in many languages. [...]]]></description>
			<content:encoded><![CDATA[<p>Statsd is a simple client/server mechanism from the folks at Etsy that allows operations and development teams to easily feed a variety of metrics into a Graphite system. For more info on statsd read the seminal blog article on Statsd <a title="Etsy: Measure Anything, Measure Everything" href="http://codeascraft.etsy.com/2011/02/15/measure-anything-measure-everything/">&#8220;Measure Anything, Measure Everything&#8221;</a>.</p>
<p>As would be expected there are statsd clients in many languages. But, there are also many implementations of the statsd server. This is nice because each organization can pick the one that best fits them. For example, a python shop might prefer to deploy a python based statsd instead of Etsy&#8217;s original node.js implementation. Also, there are some statsd implementations that diverge from the original design and provide additional features.</p>
<p>I could not find a single resource that listed all of the different implementations, so I figured I would try to start one here.</p>
<ul>
<li><a title="https://github.com/etsy/statsd" href="https://github.com/etsy/statsd">Etsy&#8217;s statsd</a>: node.js. The Original</li>
<li><a title="https://github.com/fetep/ruby-statsd" href="https://github.com/fetep/ruby-statsd">petef-statsd</a>: ruby. Supports AMQP.</li>
<li><a title="https://github.com/seatgeek/statsd_rb" href="https://github.com/seatgeek/statsd_rb">statsd_rb</a>: ruby.</li>
<li><a title="https://github.com/quasor/statsd" href="https://github.com/quasor/statsd">quasor/statsd</a>: ruby. can send data to graphite or mongoDB</li>
<li><a title="py-statsd" href="https://github.com/sivy/py-statsd">py-statsd</a>: python (including python client code).</li>
<li><a title="https://github.com/pistolero/zbx-statsd" href="https://github.com/pistolero/zbx-statsd">zbx-statsd</a>: python, based on py-statsd. Sends data to Zabbix instead of graphite.</li>
<li><a title="https://github.com/jamesgolick/statsd.scala" href="https://github.com/jamesgolick/statsd.scala">statsd.scala</a>: scala. Sends data to Ganglia instead of Graphite. Different messaging protocol, uses JSON.</li>
<li><a title="https://launchpad.net/txstatsd" href="https://launchpad.net/txstatsd">txStatsD</a>: python + twisted, from the folks @ Canonical</li>
<li><a title="https://github.com/engineyard/statsd-librato" href="https://github.com/engineyard/statsd-librato">statsd-librato</a>: node.js. Fork of etsy&#8217;s statsd for sending data to Librato instead of graphite from the folks @ Engine Yard.</li>
<li><a title="https://github.com/opscode/estatsd" href="https://github.com/opscode/estatsd">estatsd</a>: erlang. From the folks @ Opscode</li>
<li><a title="https://github.com/mojodna/metricsd" href="https://github.com/mojodna/metricsd">metricsd</a>: scala. Should be drop-in compatible with etsy&#8217;s statsd, but with support for additional metric types (eg: meter, gauge, histogram)</li>
<li><a title="statsd-c" href="https://github.com/jbuchbinder/statsd-c">statsd-c</a>: C. compatible with original etsy statsd</li>
<li><a title="statsd (librato)" href="https://github.com/librato/statsd">statsd (librato)</a>: node.js.  <a title="Librato" href="http://librato.com/">Librato&#8217;s</a> officially maintained fork of statsd based on the changes from Engine Yard. Supports multiple graphing services including <a title="Librato Metrics" href="http://metrics.librato.com">Librato Metrics</a></li>
<li><a title="bucky" href="https://github.com/cloudant/bucky">bucky</a>: python. A unique spin on statsd that supports collecting data from statsd clients, collectd, and metricsd, with output to graphite. The ability to translate collectd plugin names to be more graphite-friendly is very compelling.</li>
<li><a title="clj-statsd-svr" href="https://github.com/netmelody/clj-statsd-svr">clj-statsd-svr</a>: Clojure.</li>
<li><a title="statsite" href="https://github.com/armon/statsite">statsite</a>: C. Statsite is designed to be both highly performant, and very flexible, using libev to be extremely fast.</li>
</ul>
<p>Deprecated:</p>
<ul>
<li><a title="https://github.com/kiip/statsite/" href="https://github.com/kiip/statsite/">statsite</a>: python. Replaced by a new implementation in C, see above.</li>
</ul>
<p>Please leave a comment if you have an implementation that should be listed here. Feedback on any of the above implementations would be helpful too.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemiller.me/2011/09/21/list-of-statsd-server-implementations/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Network Link Conditioner in Xcode 4.1,&#160;Lion</title>
		<link>http://joemiller.me/2011/07/25/network-link-conditioner-in-xcode-4-1-lion/</link>
		<comments>http://joemiller.me/2011/07/25/network-link-conditioner-in-xcode-4-1-lion/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 22:07:42 +0000</pubDate>
		<dc:creator>jmiller</dc:creator>
				<category><![CDATA[macosx]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://joemiller.me/?p=320</guid>
		<description><![CDATA[Previously, I wrote a post about using the &#8216;dummynet&#8217; functionality in Mac OSX&#8217;s ipfw(8) firewall to simulate a variety of networking conditions, such as:  bandwidth, packet loss, latency (delay). This is a great feature for testing software under a variety of network conditions but it can be a little tough to use unless you&#8217;re comfortable [...]]]></description>
			<content:encoded><![CDATA[<p>Previously, I wrote a <a title="Simulate network latency, packet loss, and low bandwidth on Mac OSX" href="http://joemiller.me/2010/08/31/simulate-network-latency-packet-loss-and-bandwidth-on-mac-osx/">post</a> about using the &#8216;dummynet&#8217; functionality in Mac OSX&#8217;s ipfw(8) firewall to simulate a variety of networking conditions, such as:  bandwidth, packet loss, latency (delay). This is a great feature for testing software under a variety of network conditions but it can be a little tough to use unless you&#8217;re comfortable at the command line, or even better, have unix scripting skills since there are multiple commands required to create even simple scenarios.</p>
<p>Then, today I noticed that Apple now includes a new prefPane in Xcode 4.1 and Lion called &#8220;Network Link Conditioner&#8221; that simplifies all of this, and even includes a few profiles to get you started (eg: &#8220;Wifi, Average case&#8221;, &#8220;3G, Lossy Network&#8221;.) Pretty cool feature. Especially useful for iOS developers. Screenshot below.</p>
<ul>
<li>Install: find and run /Developer/Applications/Utilities/Network Link Conditioner/Network Link Conditioner.prefPane</li>
</ul>
<p><a href="http://joemiller.me/wp-content/uploads/2011/07/Screen-Shot-2011-07-25-at-2.57.41-PM.png"><img class="alignnone size-full wp-image-321" title="Network Link Conditioner" src="http://joemiller.me/wp-content/uploads/2011/07/Screen-Shot-2011-07-25-at-2.57.41-PM.png" alt="" width="655" height="351" /></a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://joemiller.me/2011/07/25/network-link-conditioner-in-xcode-4-1-lion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>groovy-statsdclient</title>
		<link>http://joemiller.me/2011/06/29/groovy-statsdclient/</link>
		<comments>http://joemiller.me/2011/06/29/groovy-statsdclient/#comments</comments>
		<pubDate>Wed, 29 Jun 2011 23:50:13 +0000</pubDate>
		<dc:creator>jmiller</dc:creator>
				<category><![CDATA[groovy]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://joemiller.me/?p=309</guid>
		<description><![CDATA[In an attempt to learn some Groovy and Gradle I wrote an implementation of a Statsd client in groovy.  It&#8217;s similar to other statsd clients in other languages and supports the typical increment(), decrement(), and timing() methods. It&#8217;s not available on Maven Central or via Grape at this time, which will be a future learning exercise. [...]]]></description>
			<content:encoded><![CDATA[<p>In an attempt to learn some Groovy and Gradle I wrote an implementation of a Statsd client in groovy.  It&#8217;s similar to other statsd clients in other languages and supports the typical increment(), decrement(), and timing() methods.</p>
<p>It&#8217;s not available on Maven Central or via Grape at this time, which will be a future learning exercise. In the meantime you can download a pre-built .jar or the source code from github:</p>
<ul>
<li><a title="https://github.com/joemiller/groovy-statsdclient" href="https://github.com/joemiller/groovy-statsdclient">https://github.com/joemiller/groovy-statsdclient</a></li>
</ul>
<p>For more background on Statsd, check out this blog article from Etsy:  <a title="Statsd: Measure anything, Measure Everything" href="http://codeascraft.etsy.com/2011/02/15/measure-anything-measure-everything/">Measure Anything, Measure Everything</a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://joemiller.me/2011/06/29/groovy-statsdclient/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
