Skip to content

Instantly share code, notes, and snippets.

@nickchappell
Last active January 11, 2017 18:02
Show Gist options
  • Save nickchappell/fa025de695c996994098 to your computer and use it in GitHub Desktop.
Save nickchappell/fa025de695c996994098 to your computer and use it in GitHub Desktop.
Riemann config for Graphite input
; -*- mode: clojure; -*-
; vim: filetype=clojure
(logging/init {:file "/var/log/riemann/riemann.log"})
; Listen on the local interface over TCP (5555), UDP (5555), and websockets
; (5556)
(let [host "0.0.0.0"]
(tcp-server {:host host})
(udp-server {:host host})
(ws-server {:host host}))
;Start a Graphite server on the usual TCP port for Carbon, port 2003.
(graphite-server :host "0.0.0.0"
:protocol :tcp
:parser-fn
; This function parses Graphite events after they've been pre-processed by (graphite-server) calling (decode-graphite-line).
;They start out looking like this, with just the :service, :metric and :time keys having values:
; #riemann.codec.Event{
;:host nil,
;:service collectd.collectd1_local.df-run.df_complex-reserved,
;:state nil,
;:description nil,
;:metric 0.0,
;:tags nil,
;:time 1402720236,
;:ttl nil}
;The :time and :metric keys are set the way we want them to be, but we have to break up the value of the :service key into smaller
;useful pieces. Below is the function that does this.
;We start by getting the :service key and setting it to the local value 'service'. The :keys [service] is what does this. If we
;wanted to, we could also grab other keys by listing them after service: [service metric state ttl]. The ':as' lets us
;refer to the original event as 'event' within the function.
(fn [{:keys [service] :as event}]
;The let statement creates the local values 'source', 'hostname' and 'metricname'. The split' function call splits the 'service'
; string when it encounters a period, '.' which gets specified by the '#"\."', which is a Clojure regular expression. The last
;argument to the split function, '3', specifies how many splits to do at the most. Since the original :service value looks like this:
; 'collectd.collectd1_local.df-run.df_complex-reserved', we'll get 'collectd', 'collectd1_local' and 'df-run.df_complex-reserved'
;Splitting more than 3 times would turn 'df-run.df_complex-reserved' into 'df-run' and 'df_complex-reserved', when they're really
;smaller pieces of the same metric name. The [source hostname metricname] vector before the split function call tells Riemann to take
;the first result of the split and put it in the 'source' value, the 2nd result of the split into the 'hostname' value and the 3rd
;result into the 'metricname' value.
;''
(let [[source hostname metricname] (clojure.string/split service #"\." 3)]
{
;Once we've split the :service key's value and put it into the 3 local values, we can create a new Riemann event and fill in
;some of the missing values.
; Set the :host key to the value of the hostname
; The replace function finds _ in the hostnames and replaces them with a period. collectd adds _ in place of . for hostnames
; since it uses . to separate out the hostname from the metric name
:host (clojure.string/replace hostname #"_" ".")
;set the service key of the event to the metricname that we parsed out above
:service metricname
;set the :metric key of the new event to the value of the :metric key in the old event.
;In Clojure, map keys can be called as functions and given the map as an argument; the key's value is returned.
;We do that here to grab the :metric value out of the old event and set it equal to the :metric value in the new event:
:metric (:metric event)
;This works like the :service metricname above
:tags source
;This works in the same way as setting the :host above
:time (:time event)
;Keep the returned event in the index for 30 seconds
:ttl 30})))
;The end result of the above is this:
; #riemann.codec.Event{:host nil, :service collectd.collectd1_local.df-run.df_complex-reserved, :state nil, :description nil, :metric 0.0, :tags nil, :time 1402720236, :ttl nil}
; ...getting turned into this:
; #riemann.codec.Event{:host collectd1.local, :service df-root.df_complex-reserved, :metric 3.3860608E9, :tags collectd, :time 1402877026, :ttl 30}
; Expire old events from the index every 5 seconds.
(periodically-expire 5)
(let [index (index)]
; Inbound events will be passed to the functions that come after (streams...
(streams
;This is one function. Index all events immediately.
index
;Just for debugging, log all events to the log file specified above in "(logging/init...."
#(info %))
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment