<?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>The Untergeek</title>
	<atom:link href="http://untergeek.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://untergeek.com</link>
	<description></description>
	<lastBuildDate>Sat, 06 Apr 2013 02:40:32 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>A rant about education, success and the 3 Ds</title>
		<link>http://untergeek.com/2013/04/05/a-rant-about-education-success-and-the-3-ds/</link>
		<comments>http://untergeek.com/2013/04/05/a-rant-about-education-success-and-the-3-ds/#comments</comments>
		<pubDate>Fri, 05 Apr 2013 16:34:38 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Education]]></category>

		<guid isPermaLink="false">http://untergeek.com/?p=108</guid>
		<description><![CDATA[<p>Update: <a href="http://www.boston.com/businessupdates/2013/04/04/mcdonalds/E2AM05uwD2OKEP5V4QyVfN/story.html" title="Contrary to online job posting, you don’t need a college degree to work at Mass. McDonald’s" target="_blank">Contrary to online job posting, you don’t need a college degree to work at Mass. McDonald’s</a></p> <p>Looks like the story was bogus. Short version: Some other job posting service put the erroneous requirement in its listing.</p> <p>However, [...]]]></description>
				<content:encoded><![CDATA[<p>Update: <a href="http://www.boston.com/businessupdates/2013/04/04/mcdonalds/E2AM05uwD2OKEP5V4QyVfN/story.html" title="Contrary to online job posting, you don’t need a college degree to work at Mass. McDonald’s" target="_blank">Contrary to online job posting, you don’t need a college degree to work at Mass. McDonald’s</a></p>
<p>Looks like the story was bogus.  Short version: Some other job posting service put the erroneous requirement in its listing.</p>
<p>However, my comments below remain as applicable as before.  (Note the Iranian expat who flipped burgers until she could use her chemical engineering degree).</p>
<p>Headline: <a title="McDonald’s help-wanted ad: Cashier position available; college degree required" href="http://www.washingtontimes.com/news/2013/apr/4/mcdonalds-help-wanted-ad-cashier-position-availabl/" target="_blank">McDonald’s help-wanted ad: Cashier position available; college degree required</a></p>
<p>From the article: &#8220;experts argue the unusually high qualifications McDonald&#8217;s is demanding are a sign of the times.&#8221;</p>
<p>The job description says compensation is $10/hour. Did you go to college for 4 years with dreams of making $10 per hour? Is that a sign of the times, or is it a sign of something else?</p>
<p>Please don&#8217;t take offense. I am not trying to demean or belittle anyone&#8217;s efforts or education. Full disclosure: I do not have a college degree, though I truly wish I had completed my degree when I had the chance. I applaud the hard work and determination of those who succeeded where I did not. I am nearly 40, and I see a disconnect in the world around me and I&#8217;m trying to understand it. I feel as though many young people today are told that a college degree is their ticket to a better future. But for many, once they have that degree, jobs that feel equivalent to their education are hard to find. While it can be argued that having a degree is more valuable than not having one we seem to be in an economy where skills, projects and/or portfolio are more highly valued than education-level. What skills do you have? What projects have you worked on? What have you created? What have you done recently that you are proud of? When you are applying for a job and asked questions such as these, will you have an answer, or will you point to your degree and say, I have this?</p>
<p>A degree is not a ticket to a better job, it&#8217;s more like an upgrade from economy to economy plus, or first class. You still need to get that ticket or boarding pass yourself, and the price is hard work. Sometimes it means taking an entry-level position and working your way up from the bottom. You need to use whatever job you do take to show that you have skills, initiative, creativity, determination and can solve problems on your own. Once you start doing this effectively and establish a history of being able to do so you will have those skills, that portfolio of you, that will be your ticket to a better future.</p>
<p>It used to be that a high school diploma alone was an indicator to an employer that you had the necessary skills to be worth taking a chance on. In my lifetime I have seen that requirement climb from high school diploma to college degree. Now it seems that many employers don&#8217;t want to take chances employing people with even college degrees. People may be afraid of taking the wrong job for fear of being pigeon-holed or type-cast, which could tarnish your résumé or hurt your chances at obtaining a job later in the field of their choice. I don&#8217;t blame anyone for those fears. I have had to reinvent myself for being type-cast as a systems administrator when I wanted to grow to bigger and better things.</p>
<p>I will share my own experience here, take from it what you will: My success has been determined by three <b>D</b>s: Desire, Drive &amp; Determination. Desire is the beginning. If you don&#8217;t desire to succeed at something, you won&#8217;t. Once you have desire, drive kicks in. Your drive will motivate you to do what is necessary to achieve your desire. Determination is what keeps you working when your drive is flagging, and it seems like you may not be able to achieve your desire. These are <i>gross</i> simplifications, but they will suffice for now. Everyone wants to climb the ladder of success, but you have to take the rungs at the bottom first. A high school diploma used to &#8220;spot&#8221; you the first rung or two, and a college degree another rung or two. That may still be true in many cases. I thought, like many it seems, that the rungs leading to success are on the ladder already&#8211;all I had to do was climb them. My life has taught me, and continues to remind me, that there are no higher rungs on the ladder to success that aren&#8217;t achieved at least in part by myself by way of those three <b>D</b>s. Education only counts for a few rungs. The rest is up to you.</p>
<p>So, that&#8217;s my rant. It&#8217;s also the message I want to send to my children. I read <a title="(Mom was right)" href="http://online.wsj.com/article/SB10001424127887324100904578402550244371508.html" target="_blank">another article</a> this morning from the WSJ that had a segment about a woman who&#8217;d escaped Iran before the Shah hit the fan in 1979. She&#8217;d had a college degree, too. She fled Iran, and eventually made it to Canada. One of her first jobs? Flipping burgers. She went on to become a successful chemical engineer. If I had to offer an explanation for her success, I&#8217;d probably say the three <b>D</b>&#8216;s had something to do with it.</p>
]]></content:encoded>
			<wfw:commentRss>http://untergeek.com/2013/04/05/a-rant-about-education-success-and-the-3-ds/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The Logstash Book</title>
		<link>http://untergeek.com/2013/02/04/the-logstash-book/</link>
		<comments>http://untergeek.com/2013/02/04/the-logstash-book/#comments</comments>
		<pubDate>Tue, 05 Feb 2013 04:32:49 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[Elasticsearch]]></category>
		<category><![CDATA[Logstash]]></category>

		<guid isPermaLink="false">http://untergeek.com/?p=102</guid>
		<description><![CDATA[<p>Get &#8220;<a href="http://logstashbook.com" title="The Logstash Book" target="_blank">The Logstash Book</a>&#8221; </p> <p>No, I am not the author. I am, however, in the credits on page 1, with links and examples drawn from some of the content on this site. The author, James Turnbull, approached me and asked if it would be okay to do so and [...]]]></description>
				<content:encoded><![CDATA[<p>Get &#8220;<a href="http://logstashbook.com" title="The Logstash Book" target="_blank">The Logstash Book</a>&#8221; </p>
<p>No, I am not the author.  I am, however, in the credits on page 1, with links and examples drawn from some of the content on this site.  The author, James Turnbull, approached me and asked if it would be okay to do so and I agreed (of course!).</p>
<p>If you are just learning about Logstash, Elasticsearch and Kibana, this is the book for you.  I&#8217;ve read through its pages.  This is the book I wish I&#8217;d had a year and a half ago when I first started with Logstash in its infancy.  A lot of what you will find in this book is the result of Jordan and the Logstash community&#8217;s hard work since then to make Logstash more user-friendly and accessible.  You&#8217;ll be a Logstash maven in no time if you follow the basics in this book.  The book even shows the basics of extending Logstash by adding your own plugins.  Who knows?  Maybe you&#8217;ll become a Logstash contributor too!</p>
<p>This is the first book published on Logstash, and it&#8217;s worth every penny of the inexpensive $9.99 asking price.  <a href="http://logstashbook.com" title="The Logstash Book" target="_blank">Get it now</a>, and get started with Logstash!</p>
<p>Disclaimer: I am not receiving any royalties to review or recommend this book.  It succeeds on its own merits and I am pleased to be associated with it in any way.</p>
]]></content:encoded>
			<wfw:commentRss>http://untergeek.com/2013/02/04/the-logstash-book/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing zoop</title>
		<link>http://untergeek.com/2013/01/30/introducing-zoop/</link>
		<comments>http://untergeek.com/2013/01/30/introducing-zoop/#comments</comments>
		<pubDate>Wed, 30 Jan 2013 17:58:23 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Zabbix]]></category>

		<guid isPermaLink="false">http://untergeek.com/?p=95</guid>
		<description><![CDATA[<p>Drumroll please…</p> <p>Introducing… zoooooooop!</p> <p>I got sick of hard-coding calls to the python Zabbix API module (<a href="https://github.com/gescheit/scripts" title="Python Zabbix API" target="_blank">https://github.com/gescheit/scripts</a>), so I wrote zoop: Zabbix Object-Oriented Python.</p> <p>With zoop, I have made (and will continue to add) classes, or objects if you will, of Zabbix API calls. Need to create a new item?</p> [...]]]></description>
				<content:encoded><![CDATA[<p>Drumroll please…</p>
<p>Introducing… zoooooooop!</p>
<p>I got sick of hard-coding calls to the python Zabbix API module (<a href="https://github.com/gescheit/scripts" title="Python Zabbix API" target="_blank">https://github.com/gescheit/scripts</a>), so I wrote zoop: Zabbix Object-Oriented Python.</p>
<p>With zoop, I have made (and will continue to add) classes, or objects if you will, of Zabbix API calls.  Need to create a new item?</p>
<p><code>
<pre>
from zoop import *

api = zoop(url='http://www.example.com/zabbix', username='zabbixusername', password='zabbixpassword')
host = api.host()
host.get(name='zabbix.example.com')
</pre>
<p></code><br />
The .get() method will fill the object with the API information, if the host exists (will search by either host, name or hostid)<br />
Once filled, the host object behaves like a python dict type, so you can call the values or set them like this: host["hostid"]</p>
<p><code>
<pre>
item = api.item()
item["hostid"] = host["hostid"]
item["key_"] = 'myitemkey'
item["other item values"] = etc.
</pre>
<p></code></p>
<p>There is a .get() method for items as well, e.g. item.get(key_=&#8217;my_item_key&#8217;, hostid=host["hostid"]), which will fill the item object with values from the API.</p>
<p>Please feel free to browse the source.  There is a LOT that could be done here to extend this and make it better, and encompass more API calls.  This is just for starters!</p>
<p>zoop is available at <a href="https://github.com/untergeek/zoop" title="zoop: Zabbix Object Oriented Python" target="_blank">https://github.com/untergeek/zoop</a></p>
]]></content:encoded>
			<wfw:commentRss>http://untergeek.com/2013/01/30/introducing-zoop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Zabbix Grab-Bag</title>
		<link>http://untergeek.com/2012/12/21/the-zabbix-grab-bag/</link>
		<comments>http://untergeek.com/2012/12/21/the-zabbix-grab-bag/#comments</comments>
		<pubDate>Fri, 21 Dec 2012 19:58:37 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Geek]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Zabbix]]></category>

		<guid isPermaLink="false">http://untergeek.com/?p=80</guid>
		<description><![CDATA[<p><a href="http://untergeek.github.com/zabbix-grab-bag/" title="Zabbix Grab-Bag GitHub Page" target="_blank">I finally created a repository on GitHub for all of my Zabbix scripts</a> (or, if you want to go directly to the repository: <a href="https://github.com/untergeek/zabbix-grab-bag" title="Zabbix Grab-Bag GitHub Repository" target="_blank">https://github.com/untergeek/zabbix-grab-bag</a>)</p> <p>This is the culmination of a dream that started a few years ago. I wanted a way to share [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://untergeek.github.com/zabbix-grab-bag/" title="Zabbix Grab-Bag GitHub Page" target="_blank">I finally created a repository on GitHub for all of my Zabbix scripts</a> (or, if you want to go directly to the repository: <a href="https://github.com/untergeek/zabbix-grab-bag" title="Zabbix Grab-Bag GitHub Repository" target="_blank">https://github.com/untergeek/zabbix-grab-bag</a>)</p>
<p>This is the culmination of a dream that started a few years ago.  I wanted a way to share my scripts in a way that others would be able to both use and improve them.  GitHub is the chosen vessel.</p>
<p>Rather than making this a true project, I envision it as more of a &#8220;grab-bag&#8221; of projects/scripts/templates from myself and others.  And you should be able to license your own scripts however you want, too.</p>
<p>So check it out!  Contribute!  Let&#8217;s make Zabbix even more awesome!</p>
]]></content:encoded>
			<wfw:commentRss>http://untergeek.com/2012/12/21/the-zabbix-grab-bag/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ls-zbxstatsd &#8211; Part 1: Wrangling a zabbix key from a statsd key string.</title>
		<link>http://untergeek.com/2012/12/08/ls-zbxstatsd-part-1-wrangling-a-zabbix-key-from-a-statsd-key-string/</link>
		<comments>http://untergeek.com/2012/12/08/ls-zbxstatsd-part-1-wrangling-a-zabbix-key-from-a-statsd-key-string/#comments</comments>
		<pubDate>Sat, 08 Dec 2012 20:51:40 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Logstash]]></category>
		<category><![CDATA[Zabbix]]></category>

		<guid isPermaLink="false">http://untergeek.com/?p=77</guid>
		<description><![CDATA[<p>I have just forked zbx-statsd from github into <a href="https://github.com/untergeek/ls-zbxstatsd" title="ls-zbxstatsd" target="_blank">ls-zbxstatsd</a>.</p> <p>The reason for this is that zbx-statsd was not compatible with the format coming from <a href="http://logstash.net/docs/1.1.5/outputs/statsd" title="Logstash's statsd output plugin" target="_blank">logstash&#8217;s statsd output plugin</a>. </p> <p>Statsd format is simply &#8220;key:value&#124;[type]&#8220;.<br /> In logstash, &#8220;key&#8221; is different, and the format becomes &#8220;namespace.sender.&#8217;whatever you [...]]]></description>
				<content:encoded><![CDATA[<p>I have just forked zbx-statsd from github into <a href="https://github.com/untergeek/ls-zbxstatsd" title="ls-zbxstatsd" target="_blank">ls-zbxstatsd</a>.</p>
<p>The reason for this is that zbx-statsd was not compatible with the format coming from <a href="http://logstash.net/docs/1.1.5/outputs/statsd" title="Logstash's statsd output plugin" target="_blank">logstash&#8217;s statsd output plugin</a>.  </p>
<p>Statsd format is simply &#8220;key:value|[type]&#8220;.<br />
In logstash, &#8220;key&#8221; is different, and the format becomes &#8220;namespace.sender.&#8217;whatever you named it in the statsd output plugin&#8217;:value|[type]&#8220;.  Things get more complicated when you need to split an already period-delimited &#8220;key&#8221; and figure out which part is which.  What if the &#8220;sender,&#8221; which is the zabbix host you want the metrics to be stored under, is a period-delimited FQDN?  </p>
<p>This was too much to handle so I added a delimiter.  Double semicolons.  With this, the format sent from logstash now looks like &#8220;namespace.sender;;.&#8217;whatever you named it in the statsd output plugin&#8217;:value|[type]&#8220;.  This is much more easy to split.</p>
<p>For now, I strip the namespace altogether.  I don&#8217;t need it, and while it might be useful later, I couldn&#8217;t think of a reason to keep it, so my script expects the default &#8220;logstash&#8221; and strips that out.  If you&#8217;re using this script at this time, don&#8217;t change the default namespace, or expect to edit the code.  Now I&#8217;m left with &#8220;sender;;.&#8217;whatever you named it in the statsd output plugin&#8217;:value|[type]&#8220;, where:</p>
<ul>
<li>sender = zabbix host</li>
<li>&#8216;whatever you named it in the statsd output plugin&#8217; = item key</li>
</ul>
<p>With the double semicolons I can easily separate the zabbix host name from the zabbix key, even if there are many periods in each.</p>
<p>With the resolution of this, it was time for stage two: Automatic item creation.</p>
]]></content:encoded>
			<wfw:commentRss>http://untergeek.com/2012/12/08/ls-zbxstatsd-part-1-wrangling-a-zabbix-key-from-a-statsd-key-string/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My current template/mapping</title>
		<link>http://untergeek.com/2012/11/05/my-current-templatemapping/</link>
		<comments>http://untergeek.com/2012/11/05/my-current-templatemapping/#comments</comments>
		<pubDate>Mon, 05 Nov 2012 21:07:14 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[Elasticsearch]]></category>
		<category><![CDATA[Logstash]]></category>

		<guid isPermaLink="false">http://untergeek.com/?p=70</guid>
		<description><![CDATA[<p>Expect this post to get updated from time to time. You can come back here to check out what I&#8217;m using and why.</p> <p>2012-11-05: I now map IP addresses (clientip field) as type IP to allow for range searches. I also map the fields in the geoip filter output to allow for non-analyzed terms facet [...]]]></description>
				<content:encoded><![CDATA[<p>Expect this post to get updated from time to time.  You can come back here to check out what I&#8217;m using and why.</p>
<p>2012-11-05: I now map IP addresses (clientip field) as type IP to allow for range searches.  I also map the fields in the geoip filter output to allow for non-analyzed terms facet output (allows full city names with spaces; proper capitalization, etc.)</p>
<pre>

curl -XPUT http://localhost:9200/_template/logstash_per_index -d '
{
    "template" : "logstash*",
    "settings" : {
        "number_of_shards" : 4,
        "index.cache.field.type" : "soft",
        "index.refresh_interval" : "5s",
        "index.store.compress.stored" : true,
        "index.query.default_field" : "@message",
        "index.routing.allocation.total_shards_per_node" : 4
    },
    "mappings" : {
        "_default_" : {
            "_all" : {"enabled" : false},
            "properties" : {
               "@fields" : {
                    "type" : "object",
                    "dynamic": true,
                    "path": "full",
                    "properties" : {
                        "clientip" : { "type": "ip" },
                        "geoip" : {
                            "type" : "object",
                            "dynamic": true,
                            "path": "full",
                            "properties" : {
                                    "area_code" : { "type": "string", "index": "not_analyzed" },
                                    "city_name" : { "type": "string", "index": "not_analyzed" },
                                    "continent_code" : { "type": "string", "index": "not_analyzed" },
                                    "country_code2" : { "type": "string", "index": "not_analyzed" },
                                    "country_code3" : { "type": "string", "index": "not_analyzed" },
                                    "country_name" : { "type": "string", "index": "not_analyzed" },
                                    "dma_code" : { "type": "string", "index": "not_analyzed" },
                                    "ip" : { "type": "string", "index": "not_analyzed" },
                                    "latitude" : { "type": "float", "index": "not_analyzed" },
                                    "longitude" : { "type": "float", "index": "not_analyzed" },
                                    "metro_code" : { "type": "float", "index": "not_analyzed" },
                                    "postal_code" : { "type": "string", "index": "not_analyzed" },
                                    "region" : { "type": "string", "index": "not_analyzed" },
                                    "region_name" : { "type": "string", "index": "not_analyzed" },
                                    "timezone" : { "type": "string", "index": "not_analyzed" }
                            }
                        }
                    }
               },
               "@message": { "type": "string", "index": "analyzed" },
               "@source": { "type": "string", "index": "not_analyzed" },
               "@source_host": { "type": "string", "index": "not_analyzed" },
               "@source_path": { "type": "string", "index": "not_analyzed" },
               "@tags": { "type": "string", "index": "not_analyzed" },
               "@timestamp": { "type": "date", "index": "not_analyzed" },
               "@type": { "type": "string", "index": "not_analyzed" }
            }
        }
    }

}
'


</pre>
]]></content:encoded>
			<wfw:commentRss>http://untergeek.com/2012/11/05/my-current-templatemapping/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Using elasticsearch mappings appropriately to map as type IP, int, float, etc.</title>
		<link>http://untergeek.com/2012/10/12/using-elasticsearch-mappings-appropriately-to-map-as-type-ip-int-float-etc/</link>
		<comments>http://untergeek.com/2012/10/12/using-elasticsearch-mappings-appropriately-to-map-as-type-ip-int-float-etc/#comments</comments>
		<pubDate>Fri, 12 Oct 2012 17:13:27 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[Elasticsearch]]></category>
		<category><![CDATA[linkedin]]></category>
		<category><![CDATA[Logstash]]></category>

		<guid isPermaLink="false">http://untergeek.com/?p=59</guid>
		<description><![CDATA[<p>Update 2012-11-05: My most recent template/mapping can be found <a href="http://untergeek.com/2012/11/05/my-current-templatemapping/" title="My most recent template/mapping" target="_blank">here</a>.</p> <p>I am updating previous templates in blogs accordingly, just FYI. </p> <p>Logstash allows you to tag certain fields as types within elasticsearch. This is useful for performing statistical analysis on numbers, such as the byte fields or the duration [...]]]></description>
				<content:encoded><![CDATA[<p><strong>Update 2012-11-05</strong>: My most recent template/mapping can be found <a href="http://untergeek.com/2012/11/05/my-current-templatemapping/" title="My most recent template/mapping" target="_blank">here</a>.</p>
<p>I am updating previous templates in blogs accordingly, just FYI.  </p>
<p>Logstash allows you to tag certain fields as types within elasticsearch.  This is useful for performing statistical analysis on numbers, such as the byte fields or the duration of a transaction in mili or microseconds.  In grok, this would be as simple as adding :int, or :float to the end of an expression, e.g. %{POSINT:bytes:int}.  This makes the correct mapping output when the event is sent to elasticsearch.  However, since we&#8217;re trying to avoid using grok and are sending values as pre-formatted JSON, this sometimes results in values not being properly tagged.</p>
<p>Jordan instructed me to not encapsulate values within double-quotes if the value is a number.  In doing so, the value is auto-sent as type long (for long integer).  However, <a href="http://www.elasticsearch.org/guide/reference/mapping/ip-type.html" title="Elasticsearch guide: IP Type" target="_blank">elasticsearch allows us to store IP addresses as type IP</a>.  This is crucial to using the range-based queries across IP blocks/subnets, e.g. clientip:[172.16.0.0 TO 172.23.255.255].  </p>
<p>In the past, I tried putting in :ip, just like with :int or :float.  I thought it was working, because I was able to do <i>a</i> range query.  But then it became clear that it was limited to a single dotted-quad difference, such as 192.168.0.1 TO 192.168.0.255.  It would not work with a larger subnet.  The way to discover if this is correctly configured or not is to pull the _mapping from your index: </p>
<pre>
curl -XGET 'http://localhost:9200/logstash-2012.10.12/_mapping?pretty=true'
(truncated)
           "clientip" : {
              "type" : "string"
            },

</pre>
<p>In this case, type &#8220;string&#8221; is not desired.  We want to see type: &#8220;ip&#8221;.  It turns out my mapping was misconfigured.  The correct way to do this is as follows (see the mappings section in particular):</p>
<pre>
curl -XPUT http://localhost:9200/_template/logstash_per_index -d '{
    "template" : "logstash*",
    "settings" : {
        "number_of_shards" : 4,
        "index.cache.field.type" : "soft",
        "index.refresh_interval" : "5s",
        "index.store.compress.stored" : true,
        "index.query.default_field" : "@message",
        "index.routing.allocation.total_shards_per_node" : 2
    },
    "mappings" : {
        "_default_" : {
           "_all" : {"enabled" : false},
           "properties" : {
              "@fields" : {
                   "type" : "object",
                   "dynamic": true,
                   "path": "full",
                   "properties" : {
                       "clientip" : { "type": "ip"}
                   }
              },
              "@message": { "type": "string", "index": "analyzed" },
              "@source": { "type": "string", "index": "not_analyzed" },
              "@source_host": { "type": "string", "index": "not_analyzed" },
              "@source_path": { "type": "string", "index": "not_analyzed" },
              "@tags": { "type": "string", "index": "not_analyzed" },
              "@timestamp": { "type": "date", "index": "not_analyzed" },
               "@type": { "type": "string", "index": "not_analyzed" }    
           }   
        }
   }
}
'

</pre>
<p>After applying this template, now I have type &#8220;ip&#8221; showing up:</p>
<pre>
curl -XGET 'http://localhost:9200/logstash-2012.10.12/_mapping?pretty=true'
(truncated)
           "clientip" : {
              "type" : "ip"
            },

</pre>
<p>The same logic is applicable to all other fields in the object @fields (logstash&#8217;s default object for everything not prepended with an @ sign).  Try it out!  Enjoy!  Keep in mind that this will not change existing data, but will work on new indexes created after replacing your template.</p>
]]></content:encoded>
			<wfw:commentRss>http://untergeek.com/2012/10/12/using-elasticsearch-mappings-appropriately-to-map-as-type-ip-int-float-etc/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using rsyslog to send pre-formatted JSON to logstash</title>
		<link>http://untergeek.com/2012/10/11/using-rsyslog-to-send-pre-formatted-json-to-logstash/</link>
		<comments>http://untergeek.com/2012/10/11/using-rsyslog-to-send-pre-formatted-json-to-logstash/#comments</comments>
		<pubDate>Thu, 11 Oct 2012 21:03:14 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[linkedin]]></category>
		<category><![CDATA[Logstash]]></category>

		<guid isPermaLink="false">http://untergeek.com/?p=54</guid>
		<description><![CDATA[<p>My last post was about sending pre-formatted JSON to logstash to avoid unnecessary grok parsing. In this post I will show how to do the same thing from rsyslog.</p> <p>And again, this comes with a disclaimer. My exact model here depends on a version of logstash recent enough to have the udp input. You could [...]]]></description>
				<content:encoded><![CDATA[<p>My last post was about sending pre-formatted JSON to logstash to avoid unnecessary grok parsing.  In this post I will show how to do the same thing from rsyslog.</p>
<p>And again, this comes with a disclaimer.  My exact model here depends on a version of logstash recent enough to have the udp input.  You could do tcp here, but that&#8217;s not my example.</p>
<p>Prerequsites: rsyslog version 6+ (I used version 6.4.2, with more recent json patching). <b>UPDATE:</b> I just tested with 7.2.5 with success.  The problem with earlier versions in the v7 branch were addressed in 7.2.2</p>
<blockquote><p>bugfix: garbled message if field name was used with jsonf property option<br />
The length for the field name was invalidly computed, resulting in either<br />
truncated field names or including extra random data. If the random data<br />
contained NULs, the rest of the message became unreadable.</p></blockquote>
<p>For the record: 6.4.2 works, 6.6 does not, 7.2.5 does.  These are the limits of my testing, so far.</p>
<p>rsyslog does what apache does (if you tell it to): escapes quotes and other characters so you can send legitimate JSON.  What I did was create a template (including an @message field, to mimic what is normally logged), and then send everything to a local logstash agent over a UDP port.</p>
<p><code></p>
<p>## rsyslogd.conf<br />
$ModLoad immark.so<br />
$ModLoad imuxsock.so<br />
$ModLoad imklog.so<br />
$ModLoad imudp<br />
# You only need $UDPServerRun if you want your syslog to be a centralized server.<br />
$UDPServerRun 514<br />
$AllowedSender UDP, 127.0.0.1, 172.19.42.0/24, [::1]/128</p>
<p>$template ls_json,"{%timestamp:::date-rfc3339,jsonf:@timestamp%,%source:::jsonf:@source_host%,\"@source\":\"syslog://%fromhost-ip:::json%\",\"@message\":\"%timestamp% %app-name%:%msg:::json%\",\"@fields\":{%syslogfacility-text:::jsonf:facility%,%syslogseverity-text:::jsonf:severity%,%app-name:::jsonf:program%,%procid:::jsonf:processid%}}"<br />
</code></p>
<pre>
*.*                                             @localhost:55514;ls_json

</pre>
<p>This sends out everything (every level/severity) to localhost:55514 (UDP) and formats with the ls_json format as defined above.</p>
<p>Here&#8217;s the logstash agent config, which is listening on 55514:</p>
<pre>## logstash.conf

input {
   udp {
      port => 55514
      type => "syslog"
      buffer_size => 8192
      format => "json_event"
   }
}

</pre>
<p>I don&#8217;t need any date magic here as the @timestamp works (still don&#8217;t know why it&#8217;s flaky for apache).  These events are ready for consumption, no filters necessary!</p>
<p>You could send the JSON out to file.  This is what an example line looks like:</p>
<p><code><br />
## JSON output</p>
<p>{"@source":"syslog://127.0.0.1","@type":"syslog","@tags":[],"@fields":{"facility":"cron","severity":"info","program":"","processid":"10522"},"@timestamp":"2012-09-29T17:30:00.975141-05:00","@source_host":"blackbox","@message":"Sep 29 17:30:00 : (root) CMD (/usr/libexec/atrun)"}</p>
<p></code></p>
<p>If you have an existing, native syslog config, you can keep it as-is, and just add the lines above to it (and re-name it to rsyslogd.conf or something).  rsyslogd will continue to write out to your same files in /var/log/*whatever* and also send in json format to port 55514.  Again, the idea here is minimal invasiveness:  Allow the logging to continue in the way it has been, but also forward it along to a centralized server.</p>
]]></content:encoded>
			<wfw:commentRss>http://untergeek.com/2012/10/11/using-rsyslog-to-send-pre-formatted-json-to-logstash/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Getting Apache to output JSON (for logstash)</title>
		<link>http://untergeek.com/2012/10/11/getting-apache-to-output-json-for-logstash/</link>
		<comments>http://untergeek.com/2012/10/11/getting-apache-to-output-json-for-logstash/#comments</comments>
		<pubDate>Thu, 11 Oct 2012 20:23:27 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[Elasticsearch]]></category>
		<category><![CDATA[linkedin]]></category>
		<category><![CDATA[Logstash]]></category>

		<guid isPermaLink="false">http://untergeek.com/?p=42</guid>
		<description><![CDATA[<p>Last time we looked at ways to improve logstash/elasticsearch with elasticsearch templates. Today we&#8217;ll save ourselves a lot of grok parsing pain with apache&#8217;s custom log feature.</p> <p>Disclaimer: This only works with versions of logstash supporting the UDP input. You can adapt this to send or log in another way, if you like, e.g. send [...]]]></description>
				<content:encoded><![CDATA[<p>Last time we looked at ways to improve logstash/elasticsearch with elasticsearch templates.  Today we&#8217;ll save ourselves a lot of grok parsing pain with apache&#8217;s custom log feature.</p>
<p><b>Disclaimer:</b> This only works with versions of logstash supporting the UDP input.  You can adapt this to send or log in another way, if you like, e.g. send the json to a file and have logstash tail it.</p>
<p>Let&#8217;s look first, then explain later.  If you are using an include line in your apache config (e.g. Include conf.d/*.conf) then all you need to do is to put this in a standalone or vhost.  If it&#8217;s a single-host apache, I will create logstash.conf and put this in it:</p>
<pre>LogFormat "{ \
            \"@vips\":[\"vip.example.com\",\"customer.example.net\"], \
            \"@source\":\"file://host.example.com//usr/local/apache2/logs/access_log\", \
            \"@source_host\": \"host.example.com\", \
            \"@source_path\": \"/usr/local/apache2/logs/access_log\", \
            \"@tags\":[\"Application\",\"Customer\"], \
            \"@message\": \"%h %l %u %t \\\"%r\\\" %>s %b\", \
            \"@fields\": { \
                \"timestamp\": \"%{%Y-%m-%dT%H:%M:%S%z}t\", \
                \"clientip\": \"%a\", \
                \"duration\": %D, \
                \"status\": %>s, \
                \"request\": \"%U%q\", \
                \"urlpath\": \"%U\", \
                \"urlquery\": \"%q\", \
                \"method\": \"%m\", \
                \"bytes\": %B \
                }  \
           }" ls_apache_json

CustomLog "|/usr/local/bin/udpclient.pl 127.0.0.1 57080" ls_apache_json

</pre>
<p>Some of this should look straightforward, but let me point to some pitfalls I had to dig myself out of.  </p>
<ul>
<li><b>bytes:</b> in the @message, I use %b, but in @fields, I use %B.  The reason is summed up nicely on <a href="http://httpd.apache.org/docs/2.2/mod/mod_log_config.html" title="mod_log_config" target="_blank">http://httpd.apache.org/docs/2.2/mod/mod_log_config.html</a> :<br />
<blockquote>%B	Size of response in bytes, excluding HTTP headers.<br />
%b	Size of response in bytes, excluding HTTP headers. In CLF format, i.e. a &#8216;-&#8217; rather than a 0 when no bytes are sent.</p></blockquote>
<p> In other words, since I&#8217;m trying to send an integer value, if I don&#8217;t choose %B, I may send a &#8211; (dash/hyphen) when there is no value to send, making the field be categorized as a string.  Jordan says that sending the JSON as an integer (i.e. no quotes) should make it into ES as an integer.  This may yet require a mapping/template.</li>
<li><b>@message:</b> This is the apache common format.  You could easily substitute in the same fields as go in the apache combined format.  Or, you could leave the common format as @message and simply add the fields for user-agent and referrer if you want to collect those:
<pre>
                \"referer\": \\\"%{Referer}i\\\", \
                \"useragent\": \\\"%{User-agent}i\\\" \

</pre>
</li>
<li><b>timestamp:</b> Jordan has had no problems with passing @timestamp directly, but I have had nothing but problems.  Perhaps I can get a solution linked here some time, but in the meanwhile, I simply spit out the timestamp here in ISO8601, and then use date and mutate in logstash.conf:<br />
</p>
<pre>
input {
   udp {
      port => 57080
      type => "apache"
      buffer_size => 8192
      format => "json_event"
   }
}

filter {
   date {
       type => "apache"
       timestamp => "ISO8601"
   }
   mutate {
        type   => "apache"
        remove => [ "timestamp" ]
   }
}
</pre>
</li>
</ul>
<p>What comes out is ready (except for the date munging) for feeding into elasticsearch, and even has an @message field for searching.  This method also makes it trivial to add extra fields (get them from <a href="http://httpd.apache.org/docs/2.2/mod/mod_log_config.html" title="mod_log_config" target="_blank">http://httpd.apache.org/docs/2.2/mod/mod_log_config.html</a>) without doing anything extra or having to re-work your patterns for grok.  As I mentioned previously, I keep the common log format for @message, then add the other fields (like duration, user-agent and referer) as needed. An apachectl restart is all it takes to get the new values into elasticsearch.</p>
<p>And for the sake of a complete solution, the <b>udpclient.pl</b> script:</p>
<pre><code>#!/usr/bin/perl
#udpclient.pl

use IO::Socket::INET;
my $host = $ARGV[0];
my $port = $ARGV[1];


# flush after every write
$| = 1;


my ($socket,$logdata);


#  We call IO::Socket::INET->new() to create the UDP Socket
# and bind with the PeerAddr.
$socket = new IO::Socket::INET (
   PeerAddr   => "$host:$port",
   Proto        => 'udp'
) or die "ERROR in Socket Creation : $!\n";


while ($logdata = &lt;STDIN>) {
    $socket->send($logdata);
}

$socket->close();</code></pre>
<p>I also tend to think that one of the best things about this solution is that it does not interfere with your current logging solution in any degree.  It simply catches more and sends it, pre-formatted, over local udp to logstash, and then to whatever output(s) you have defined.</p>
]]></content:encoded>
			<wfw:commentRss>http://untergeek.com/2012/10/11/getting-apache-to-output-json-for-logstash/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Using templates to improve elasticsearch caching (with logstash)</title>
		<link>http://untergeek.com/2012/09/20/using-templates-to-improve-elasticsearch-caching-with-logstash/</link>
		<comments>http://untergeek.com/2012/09/20/using-templates-to-improve-elasticsearch-caching-with-logstash/#comments</comments>
		<pubDate>Thu, 20 Sep 2012 17:34:35 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Geek]]></category>
		<category><![CDATA[Elasticsearch]]></category>
		<category><![CDATA[linkedin]]></category>
		<category><![CDATA[Logstash]]></category>

		<guid isPermaLink="false">http://untergeek.com/?p=30</guid>
		<description><![CDATA[<p>Update 2012-11-05: My most recent template/mapping can be found <a href="http://untergeek.com/2012/11/05/my-current-templatemapping/" title="My most recent template/mapping" target="_blank">here</a>.</p> <p>I find that logstash does a great job with the default index mapping behavior in elasticsearch if you are not sending a ton of log events.  Once that amount begins to grow, however, there is a need to manage [...]]]></description>
				<content:encoded><![CDATA[<p><strong>Update 2012-11-05</strong>: My most recent template/mapping can be found <a href="http://untergeek.com/2012/11/05/my-current-templatemapping/" title="My most recent template/mapping" target="_blank">here</a>.</p>
<p>I find that logstash does a great job with the default index mapping behavior in elasticsearch if you are not sending a ton of log events.  Once that amount begins to grow, however, there is a need to manage how it is indexed.  One great way to maximize your elasticsearch performance is to use an index template.</p>
<p>&nbsp;</p>
<pre>curl -XPUT http://localhost:9200/_template/logstash_per_index -d '
{
    "template" : "logstash*",
    "settings" : {
        "number_of_shards" : 4,
        "index.cache.filter.expire" : "5m",
        "index.cache.field.expire" : "5m",
        "index.refresh_interval" : "5s",
        "index.store.compress.stored" : true,
        "index.query.default_field" : "@message",
        "index.routing.allocation.total_shards_per_node" : 2
    },
    "mappings" : {
        "_default_" : {
             "_all" : {"enabled" : false}
        }
    }
}
'</pre>
<p>This template was awesome!  I let my field cache expire after 5 minutes to prevent it from overfilling.  I have compression turned on to save space.  I have 4 nodes and 4 shards (plus the default of 1 replica per shard).  With a fixed map of 2 total shards per node, I typically would have one primary shard and one replica per index per day.  I was using @message as my default search field and dropping the _all field for space considerations.  And then I learned about the soft cache type.</p>
<p>The field cache is awesome in elasticsearch, and you want that data to be persistent for as long as possible.  It makes searches lightning fast!  A 5 minute expiration time doesn&#8217;t help with that at all, and the tendency to re-cache the same data was painful.  I was hoping for another solution, but could never find one.  Then on the elasticsearch LinkedIn group, I found this article.  http://blog.sematext.com/2012/05/17/elasticsearch-cache-usage/  After learning about this change and how it had benefited others, I had to make the change myself.  Now my template looks like this:</p>
<pre>curl -XPUT http://localhost:9200/_template/logstash_per_index -d '{
    "template" : "logstash*",
    "settings" : {
        "number_of_shards" : 4,
        "index.cache.field.type" : "soft",
        "index.refresh_interval" : "5s",
        "index.store.compress.stored" : true,
        "index.query.default_field" : "@message",
        "index.routing.allocation.total_shards_per_node" : 2
    },
    "mappings" : {
        "_default_" : {
           "_all" : {"enabled" : false},
           "properties" : {
              "@fields" : {
                   "type" : "object",
                   "dynamic": true,
                   "path": "full",
                   "properties" : {
                       "clientip" : { "type": "ip"}
                   }
              },
              "@message": { "type": "string", "index": "analyzed" },
              "@source": { "type": "string", "index": "not_analyzed" },
              "@source_host": { "type": "string", "index": "not_analyzed" },
              "@source_path": { "type": "string", "index": "not_analyzed" },
              "@tags": { "type": "string", "index": "not_analyzed" },
              "@timestamp": { "type": "date", "index": "not_analyzed" },
               "@type": { "type": "string", "index": "not_analyzed" }    
           }   
        }
   }
}
'

</pre>
<p>The change means that I don&#8217;t need cache expiry any more.  The built-in GC engine will cover that for me!  The downside is that it will take a full 30 days for this solution to get fully caught up as the index.cache.field.type setting can&#8217;t be applied to existing indexes.</p>
]]></content:encoded>
			<wfw:commentRss>http://untergeek.com/2012/09/20/using-templates-to-improve-elasticsearch-caching-with-logstash/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
