Riemann (riemann.io) is an event stream processor, usually deployed as a router for events generated by software systems. As Kyle Kingsbury, the author states: “Riemann’s job is to process, analyze and react to the event stream”. In effect, event stream processing is functional transformation writ large; events from various sources (e.g., hardware stats, application metrics, network data etc) are received then grouped, filtered, mapped, averaged, coalesced, forwarded, etc.
Riemann is written in Clojure. Riemann is also configured via Clojure. It’s “parentheses all the way down”.
But does a tool for functional transformation of data require a functional language? To what extent does the implementation language impact the capabilities Riemann exposes to the end user?
This presentation will take a deep dive into both the capabilities of the configuration system and the core Clojure implementation to see why a functional language is such a good choice to implement this type of application.
22. Correlate events from disparate
sources
What is the latency of the web servers when the DB
servers are generating timeouts?
Filter events based on key criteria Ignore all network events with a normal status
Aggregate events to perform
statistical analysis (e.g., percentiles)
What is the average response rate for 95% of requests?
Monitor status of sources by
availability of events
Which services haven’t sent any events for the last 5
minutes?
Route event streams to multiple
consumers
Send all error events from DB servers to the DBA team
as well as the main operational dashboards
SAMPLE RIEMANN USE CASES
23. i = f(e)
e: thundering herd of events
i: information ready for downstream processing
24. Hypothesis
Event processing is function
application at large scale… using
Clojure to build/configure Riemann is a
logical choice.
29. HOMOICONICITY
“[It] is where a program's source code is written
as a basic data structure that the
programming language knows how to access.”
Wikipedia
(defn validate-config
[file]
(try
(read-strings (slurp file))
(catch clojure.lang.LispReader$ReaderException e
(throw (logging/nice-syntax-error e file)))))
riemannsource
30. HIGHER ORDER FUNCTIONS
“A stream is just a function that takes a variable
number of child streams and returns a function
that takes an event and responds to the event it is passed
when it is invoked.”
http://riemann.io/quickstart.html
“a higher-order function… does at least one of the
following:
[1] takes one or more functions as an input,
[2] outputs a function”
Wikipedia
31. HIGHER ORDER FUNCTIONS
“A stream is just a function that takes a variable
number of child streams and returns a function
that takes an event and responds to the event it is passed
when it is invoked.”
http://riemann.io/quickstart.html
(streams
(rate 5 prn)
)
riemannconfig
34. “clojure's remarkably fast for
what it is, sexprs make the
tree structure of the streams
visually apparent, it makes
writing the concurrent algos
much simpler, and macros
allow us to express things
like 'by and 'pipe in ways
that would be awkward in
other languages without
building our own AST &
interpreter or transpiler,
etc.”
“clojure's remarkably fast for
what it is, sexprs make the
tree structure of the streams
visually apparent, it makes
writing the concurrent algos
much simpler, and macros
allow us to express things
like 'by and 'pipe in ways
that would be awkward in
other languages without
building our own AST &
interpreter or transpiler,
etc.”
@APHYR SAID…
35. S-EXPRESSIONS
“a notation for nested list (tree-structured)
data… popularised by the programming
language Lisp”
Wikipedia
36. S-EXPRESSIONS
(streams
(where (and (service #"^riak")
(state “critical”))
(email “delacroix@vonbraun.com"))
)
1 Filter certain events…
2 Let people know…
1
2
riemannconfig
“make the tree structure of the
streams visually apparent”
37. 3
1
2
S-EXPRESSIONS
1 Split on event fields…
2 Detect state changes…
3 Collate and email
(streams
(by [:host :service]
(changed :state
(rollup 5 3600
(email “delacroix@vonbraun.com"))))
)
riemannconfig
“make the tree structure of the
streams visually apparent”
41. Hypothesis
Event processing is function
application at large scale: using Clojure
to build/configure Riemann is a logical
choice.
homoiconicity
higherorderfunctions
s-expressions
macros
immutability