lamina.trace documentation
aggregating-trace-router
fn
A trace-router which splits the query into distributable and non-distributable portions, and forwards
the distributable portion to endpoint-router
.
analyze-timings
fn
Aggregates timings, and periodically emits statistical information about them.
canonical-probe-name
fn
Returns the canonical representation of a probe name.
:foo:bar
=> "foo:bar"
`[:foo "bar:baz"] => "foo:bar:baz"
defn-instrumented
macro
A def form of (instrumented-fn...). Options can be defined in the function metadata:
(defn-instrumented foo {:implicit? false :timeout (constantly 1000)} "Here's a doc-string" [x] ...)
The :name can be explicitly defined, but will default to
the:function:namespace:the-function-name
distill-timing
fn
Returns a distillation of the timing object, containing only :task, :durations, :context, and :sub-tasks. This is an idempotent operation.
This data structure can be merged using merge-distilled-timings.
error-probe-channel
var
Like probe-channel, but if the probe is not active every message enqueued into the channe will be logged as an error.
instrument
fn
A general purpose transform for functions, allowing for tracing their execution, defining timeouts, and deferring their execution onto a thread pool.
Instrumenting a function does not change its behavior in any way (unless an :executor is defined, see below). This can be a powerful tool for both understanding complex tasks during development, and monitoring their behavior in production.
OVERHEAD
Instrumenting adds some overhead to a function, equivalent to the performance difference between calling
(+ 1 2 3)
and
(apply + [1 2 3])
If you'd happily call apply
on the function being instrumented, chances are you
won't notice the difference.
PROBES
Instrumenting a function creates enter
, return
, and error
probes. A :name
must be specified, and probe names will be of the structure name:enter,
name:return, etc. Data emitted by these probes may be captured by other functions
if :implicit? is set to true, which is the default.
When the function is invoked, the enter
probe emits a hash of the form
:name - the :name specified in the options :timestamp - time of invocation in milliseconds since the epoch :args - a list of arguments passed to the function
When the function completes and the value is realized, the return
probe
will emit the data above, and also:
:duration - the time elapsed since the invocation, in nanoseconds
:result - the value returned by the function
:sub-tasks - return
probe data, less :result, for all implicit instrumented
sub-functions
If an error is thrown, or the value is realized as an error, :result is replaced by
:error - the exception thrown or realized error
A :probes option may be defined, giving a hash of probe names onto channels that will consume their data:
{:error (sink->> #(println "ERROR:" %)) :return (sink->> #(println "Given" (:args %) ", returned" (:result %)))}
TIMEOUTS
A :timeout option may be specified, which should be a function that takes the arguments passed to the function, and returns the timeout in milliseconds or nil for no timeout. If the timeout elapses without any value, the returned result will be realized as an error of type 'lamina/timeout!'.
EXECUTORS
If an :executor is specified, the function will be executed on that thread pool, and return an unrealized result representing its eventual value.
In this case, :timeout will also interrupt the thread if it is still actively
computing the value, and the return
probe will include an :enqueued-duration
parameter that describes the time, in nanoseconds, spent waiting to be executed.
instrumented-fn
macro
A compile-time version of (instrument ...).
(instrumented-fn foo {:implicit? false} [x y] (+ x y))
The
merge-distilled-timings
fn
Returns a list of one or distilled timings, where :durations have been concatenated together for identical tasks.
probe-channel
var
Returns a probe channel for the given name. Keywords will be converted to simple strings, and sequences will be joined with ':' characters.
[:a "b" [1 2 3]] => "a:b:1:2:3"
register-context-builder
fn
Defines a function which is given a default context map, and returns a modified context map.
select-probes
fn
Activates all probes that match the given strings or regexes, and returns a channel that will emit all messages from these probes.
subscribe
fn
Returns a channel corresponding to topic
. options
are router-specific, and may be nil
.
time*
macro
A somewhat more useful variant of (time ...), which captures the sub-timings of all instrumented functions called within the scope. If the body returns an unrealized value, time* will wait for it to become realized.
trace
macro
Enqueues a value into the probe-channel described by probe
. The body is executed only
if there is a consumer for the probe channel; this is essentially a log statement that is
only active if someone is paying attention.
For performance reasons, the probe name must be something that can be resolved at compile-time.
trace*
macro
A variant of trace that allows the probe name to be resolved at runtime.
trace-router
fn
Creates a router which can be queried via the default syntax and allows multiple queries to share sub-streams.
Like lamina.cache/router
, with the addition of:
:timestamp
- a function which returns the logical time of each message, defaults to wall time.
:payload
- a function which describes the content of each message, defaults to identity
.
with-instrumentation
macro
Returns the full timing data for all code called within the scope.