8 releases
0.1.8 | Mar 10, 2022 |
---|---|
0.1.7 | Dec 15, 2021 |
0.1.6 | Nov 9, 2021 |
0.1.4 | Jan 6, 2021 |
0.1.1 | Nov 8, 2020 |
#1716 in Network programming
23,564 downloads per month
Used in 62 crates
(2 directly)
110KB
2.5K
SLoC
mick-jaeger
Rust client for sending traces to a Jaeger server.
Everything is documented at the crate root. See docs.rs.
lib.rs
:
Jaeger client.
Overview
In order to use this crate, you must be familiar with the concept of a span.
A span covers a certain period of time, typically from the start of an operation to the end. In other words, you generally start a span at the beginning of a function or block, and end it at the end of the function/block.
The purpose of this crate is to let you easily record spans and send them to a Jaeger server, which will aggerate them and let you visualize them.
Each span belongs to a trace. A trace is identified by a 128 bits identifier. Jaeger lets you easily visualize all the spans belonging to the same trace, even if they come from different clients.
As an example, imagine an HTTP frontend server receiving an HTTP request. It can generate a new trace id for this request, then pass this identifier around to other external processes that process parts of this request. These external processes, being all connected to the same Jaeger server, can report spans corresponding to this request.
The easiest way to start a Jaeger server for quick experimentation is through Docker:
docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
-p 5775:5775/udp \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 14268:14268 \
-p 14250:14250 \
-p 9411:9411 \
jaegertracing/all-in-one:1.20
See also the official documentation.
Usage: initialization
First and foremost, call init
in order to allocate all the necessary objects.
This returns a combination of a TracesIn
and TracesOut
. Think of them as a sender and
receiver. The TracesIn
is used in order to send completed spans to the TracesOut
.
Sending the traces to the server isn't covered by this library. The TracesOut
must be
polled using TracesOut::next
, and the data sent through UDP to the Jaeger server.
let (traces_in, mut traces_out) = mick_jaeger::init(mick_jaeger::Config {
service_name: "demo".to_string(),
});
let udp_socket = async_std::net::UdpSocket::bind("0.0.0.0:0").await.unwrap();
udp_socket.connect("127.0.0.1:6831").await.unwrap();
async_std::task::spawn(async move {
loop {
let buf = traces_out.next().await;
udp_socket.send(&buf).await.unwrap();
}
});
If TracesOut::next
isn't called often enough, in other words if the background task is too
slow, the spans sent on the TracesIn
will be automatically and silently discarded. This
isn't expected to happen under normal circumstances.
Usage: spans
Use the TracesIn::span
method to create spans.
The basic way to use this library is to use TracesIn::span
. This creates a Span
object
that, when destroyed, will send a report destined to the TracesOut
.
Note: As long as a
Span
is alive, it will not be visible on the Jaeger server. You are encouraged to create short-lived spans and long-lived trace IDs.
let _span = traces_in.span(NonZeroU128::new(43).unwrap(), "something");
// do something
// The span is reported when it is destroyed at the end of the scope.
Note: Do not name your spans
_
, otherwise they will be destroyed immediately!
It is possible, and encouraged, to add tags to spans.
let mut _span = traces_in.span(NonZeroU128::new(43).unwrap(), "something");
_span.add_string_tag("key", "value");
Spans can have children:
fn my_function(traces_in: &std::sync::Arc<mick_jaeger::TracesIn>) {
let mut _span = traces_in.span(NonZeroU128::new(43).unwrap(), "foo");
// do something
{
let mut _span = _span.child("bar");
// something expensive
}
}
If an event happens at a precise point in time rather than over time, logs can also be added.
let mut _span = traces_in.span(NonZeroU128::new(43).unwrap(), "something");
_span.log().with_string("key", "value");
Differences with other crates
While there exists other crates that let you interface with Jaeger, they are all
overcomplicated according to the author of mick_jaeger
. Some are lossy abstractions: by
trying to be easy to use, they hide important details (such as the trace ID), which causes
more confusion than it helps.
mick_jaeger
tries to be simple. The fact that it doesn't handle sending to the server
removes a lot of opinionated decisions concerning networking libraries and threading.
mick_jaeger
could theoretically be no_std
-compatible (after a few tweaks), but can't
because at the time of writing there is no no-std-compatible library for the thrift
protocol.
Dependencies
~2MB
~38K SLoC