TIPS & TRICKS

Splunk Hack #3 – Splunk on Rails

Ruby on Rails is a popular programming framework for quickly creating web applications. It provides its own web server for development testing, and ships with OSX, which means the tools are now widely available to a broad group of programmers/coders/hackers. Coupled with the fact that most Rails developers use either Linux or OSX, and Splunk runs great on both of those platforms, it seemed obvious that we should come up with some sort of solution for mashing the two together.

I mentioned this in passing to one Sean Dick who is a developer friend of mine in Oklahoma City. What follows is a nearly identical post to the one he made over at his self-named blogpost on Blogger on how to get Rails to integrate with Splunk. “There’s plenty left to do.”, he said, but I’m convinced it’s worthy of mentioning here. Thanks for hammering this out Sean!

Serious Material from Sean Begins Here

As per the norm, this post assumes you’ve downloaded Splunk for your particular platform. It also requires a newer install of Ruby on Rails. Come back when you’ve completed both these tasks.

Get Splunk started now:

> sudo export SPLUNK_HOME=/opt/splunk/
> sudo ./opt/splunk/bin/splunk start

You need to drop the Splunk on Rails plugin into your Rails app’s lib folder and then call it with require ‘splunkbase’ Note: If you’re running Splunk remote or on a non-standard port, don’t forget to change the SERVER variable in the plugin file!

Now let’s say you want to make sure your rails application is running bug-free, and when one does pop up, you need to know it pronto. You’ll create a new controller into which we’re going to put some splunk goodies. I named mine SplunkController, but you can be more creative.


class SplunkController < ApplicationController
require 'splunkbase'
@@foo = SplunkBase.new
def index
end
def reports
@document =" @@foo.splunkSearch('q' => params[:query])
end
end

This is really nothing more than making available the response from splunk to your view in the form of a variable. Defining a page for it to be displayed in is no more difficult than:

<pre><%= @document %> </pre>

Now we build the index page we defined so we can pass it the query:

<html>
<head>
<%= javascript_include_tag "prototype" %>
</head>
<body >
<%= form_remote_tag(:update => "graphDiv",
:url => {:action => :reports }) %>
<%= text_field_tag :query, nil, {:size => "100"} %>

<%= submit_tag "Get a report on your query" %>
<%= end_form_tag %>
<div id="graphDiv">
</div>
</body>
</html>

And believe it or not we’re ready to start asking Splunk some questions. Try giving it something like:

[search sourcetype::what_you_named_your_source error starthoursago=24] | outputxml

As you’ve probably gathered, that’ll give you a formatted list of all of the errors that have occurred in the last day.

Now let’s say you’ve got a rails application running internally that you don’t have the option to/don’t feel comfortable with outsource analysis to something like Google Analytics. Back to our cute little controller, we add in a new definition for the graphing page.

class SplunkController < ApplicationController
require 'splunkbase' #those two magical words
@@foo = SplunkBase.new
def index
end
def reports
@document = @@foo.splunkSearch('q' => params[:query])
end
def graph #for graphing, this fixes things up so we can display the data
@datahash = {} @queryDoc= @@foo.splunkSearch('q' => params[:query]) #here is the meat
@queryDoc.each_element("//r/") do |ele| #here we're sorting out what is useful
@datahash[ele.elements["m[@col='1']"].text] = ele.elements["m[@col='2']"].text.to_i
end
@sorted = @datahash.values.sort.reverse #sorting it for the hell of it
@chartheight = @datahash.values.max + 50 #to make it look pretty and consistent
end
end

This example is fairly simple and assumes you’re just looking for basic metrics on your site’s usage. You could build it larger to accept whatever you want splunk to throw back at you. This one expects to see something like "Content Name" => "value".

Now let’s take a stab at setting up the graph:


<samp><%= @queryDoc.to_s %></samp> #gives us a raw return of the data we pulled from Splunk
</div>
<% @sorted.each do |name, height| %> #Iterate through each of the data pairs and grab the height.
<div class="columnSpacer">
<div style="margin-top: <%= 100 - ((height * 100)/@chartheight.to_f) %>%"class="graphTitle">
<%= name %>
<br>
<%= height %> hits
</div>
<div class="graphColumn" style="height: <%= (height * 100)/@chartheight.to_f)%>%">

</div>
<% end %>

In the interest of keeping things from getting too esoteric I’ve committed a no-no and left some programming in the view. All in all, it’s pretty light math to get things displaying properly. As you should be able to glean from the code presented we’re just iterating through each of the name/value pairs we extracted from the XML Splunk returned and turning them into pretty little bars on a chart. Now all we need to do is put together the index page for accessing the graph function.


<html>
<head>
<%= javascript_include_tag "prototype" %>
</head>
<body >
<%= form_remote_tag(:update => "graphDiv",
:url => {:action => :graph }) %>
<%= text_field_tag :query, nil, {:size => "100"} %>

<%= submit_tag "Get a report on your query" %>
<%= end_form_tag %>
<div id="graphDiv">
</div>
</body>
</html>

There’s pretty minimal monkey business here, so let’s go on to the fun part:

Let’s take a look at what controllers are getting the most face-time for our users and what content sections are being perceived as being the most useful. This example comes from a site I did recently for a client and happens to be the most handy rails logfile I have within reach.

Pop in the query:

[search sourcetype="the_name_you_gave_your_source" | top 5 controller ] | outputxml

And you get something like this:

There are a myriad of options available to you through Splunk’s search interface, and learning to romance the queries to give you what you want would be a section all its own. This one, however consists of limiting the scope of the search ( sourcetype= ) and giving it a context to put it in ( top 5 controller ) — in this case, the top five controllers.

Next post I will cover the possibilities afforded with the use of bundles in Splunk in conjunction with your Rails application. In the meantime I highly suggest you peruse the REST API documentation supplied in your Splunk install and the admin/developer documentation on Splunk.com to get a more in-depth understanding of what you can do.

By Kord Campbell

Splunk
Posted by

Splunk

Join the Discussion