Awesome
clj-zipkin
Zipkin tracing instrumentation for Clojure applications.
Usage
Add the following dependency to your project.clj
file:
[clj-zipkin "0.1.4"]
Tracing
Tracing a code chunk
(:require [clj-zipkin.tracer :as t)
(t/trace {:host "10.2.1.2" :span "GET" :scribe {:host "zipkin.host" :port 9410}}
(..code..))
Nested tracing, scribe config can be avoided for inner tracing. This will make inner traces appear in zipkin as childs of the immediate parent trace.
(:require [clj-zipkin.tracer :as t)
(t/trace {:host "10.2.1.2" :span "GET" :scribe {:host "zipkin.host" :port 9410}}
(..code..)
(t/trace {:host "10.2.1.2" :span "OTHER"}
(..code..)))
Tracing with a specific trace-id
, since all related spans in zipkin should share the
same trace-id
, if your code is executing in different hosts you can tie your traces
together specifying the trace-id
to use.
(:require [clj-zipkin.tracer :as t)
(t/trace {:host "10.2.1.2" :span "GET" :trace-id 12345 :scribe {:host "zipkin.host" :port 9410}}
(..code..)
(t/trace {:host "10.2.1.2" :span "OTHER"}
(..code..)))
Parameters
Tracing parameters
:host => current host, defaults to InetAddress/getLocalHost if unspecified
:span => span name
:annotations {:k :v} => key/value map to annotate this trace
:trace-id => optional, new one will be created if unspecified
:span-id => optional, current span-id, useful to append annotations or to keep track of created id
:parent-span-id => optional, parent span-id, this span will be nested
:scribe => scribe/zipkin endpoint configuration {:host h :port p}
The host
parameter can also be a structured hash-map
{:host "10.2.1.1" :port 3030 :service "Service Name"}
If not specified will default to port 0
and service Unknown Service
.
Connection
The make-logger
function creates a logger object to be reused among different tracing calls.
Use it in order to avoid creation of a new connection for each logged span.
(def conn (t/make-logger {:host "zipkin.host" :port 9410}))
(t/trace {:host "10.2.1.2" :span "GET" :scribe conn}
(..code..))
Thread based tracing
In the particular case you can't or really don't want to wrap your code in the trace
macro call, there's a set of apis using Thread Local Storage with the start
and close
span api calls decoupled.
Require the namespace tls
, for thread local storage (or thread local
spans if you like it more).
(:require [clj-zipkin.tracer :as t]
[clj-zipkin.tls :as tls])
Start span
At your logging entry point create the new span, this operation doesn't log a thing to zipkin just yet.
;;this should happen at entry point
(tls/start-span {:operation "GET"
:host "10.2.1.1"
:trace-id trace-id
:parent-id parent-id})
There's no need to keep track of state or variables since it's stored as thread state.
Propagation
If somewhere inside your traced code you need to retrieve the current trace or span ids - to propagate to other services for instance -, use the get-span
api call.
(:trace-id (tls/get-span))
=> 12345
The variables trace-id
and span-id
are available for proper trace propagation.
Annotations
If some information is collected during the operation, it's possible to append annotations to the thread local span using the add-annotation
api call. add-annotation
receives a map with name/values to annotate.
(tls/add-annotation {:n1 1 :n2 "da"})
This map will be merged with the previously annotated values for this thread span.
Closing span
When span is finished and ready to be logged to zipkin, issue a close-span
call passing a logger connection parameter.
(tls/close-span (t/make-logger {:host "localhost" :port 9410}))
Ring Handler
A ring handler is available for automated tracing of incoming requests
(require '[clj-zipkin.middleware :as m])
(defroutes routes
(GET "/" [] "<h1>Hello World</h1>")
(route/not-found "<h1>Page not found</h1>"))
(def app
(-> routes
(m/request-tracer {:scribe {:host "localhost" :port 9410}
:service "WebServer"})))
Configuration received by the tracer handler is almost the same as the trace
function defined above, so it also supports a host
parameter.
(m/request-tracer {:scribe {:host "localhost" :port 9410}
:host {:port 2020 :service "MyService"}}))
If no ip
is specified will default to java.net.InetAddress/getLocalHost
##Example
There's a small running example here showing how to chain different spans in a web server.
This is how it looks that example in zipkin:
##TODO
- Change span annotations default text?
License
Copyright © 2013 Guillermo Winkler
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.