opentracingrust/lib.rs
1//! An [OpenTracing](http://opentracing.io/) implementation for rust.
2//!
3//! This crate provides a generic Tracer interface following the OpenTracing
4//! specification that allows users (libraries, framework, applications) to
5//! implement distributed tracing across ecosystems and without committing to
6//! a specific distributed tracer.
7//!
8//! This means that:
9//!
10//! * Frameworks don't have to impose a tracer on applications.
11//! * Libraries can integrate their user's traces.
12//! * Applications lock end-users into a distributed tracer.
13//!
14//!
15//! # Official API heads up
16//!
17//! An Opentracing official API is in the works: https://github.com/opentracing/opentracing-rust
18//!
19//! Once the official API crate and utility crate are finished I hope to deprecate
20//! this crate in favour of the official crates.
21//!
22//! For that reason, development of this crate will be limited while I dedicate my
23//! time to help with the development of the offical opentracing-api crate.
24//!
25//! Lessons learend while developing this crate will be valuable knowledge for opentracing-api.
26//! If you find any issue and or usability limit, please let me know!
27//!
28//!
29//! # Architecture
30//!
31//! At the core of this library are three types:
32//!
33//! * `Tracer`: an interface to create and serialise `Span`s.
34//! * `Span`: each instance represents an operation and its metadata.
35//! * `SpanContext`: a tracer-specific identifier of a `Span`.
36//!
37//!
38//! ## Configuraing a `Tracer`
39//!
40//! <b>
41//! Application developers MUST read this, library and framework
42//! developers SHOULD still read it for completeness.
43//! </b>
44//!
45//! Every application and all the libraries and frameworks it uses
46//! share a single `Tracer` instance, unique to the entire process.
47//! The instance should be passed around using a dependency injection
48//! technique, of which there are many.
49//! This crate provides a `GlobalTracer` utility singleton for cases
50//! where dependency injections are not usable.
51//!
52//! Configuration of the `Tracer` instance used across the process is the
53//! responsibility of the application and should be performed as soon as
54//! possible in the initialisation phase.
55//!
56//! Tracers are implemented in separate crates and each tracers can be
57//! implemented as desired but there are two requirements of concrete tracers:
58//!
59//! * Initialisation returns instance of `Tracer`.
60//! * A `crossbeam_channel::unbounded` is used by the tracer to send
61//! `FinishedSpan`s to a reporting thread.
62//!
63//! The reporting thread is responsible for pushing the spans to the
64//! distributed tracer of choice.
65//!
66//! In code:
67//!
68//! ```
69//! extern crate opentracingrust;
70//!
71//! use std::time::Duration;
72//!
73//! use opentracingrust::tracers::NoopTracer;
74//! use opentracingrust::utils::GlobalTracer;
75//! use opentracingrust::utils::ReporterThread;
76//!
77//!
78//! fn main() {
79//! let (tracer, receiver) = NoopTracer::new();
80//! let reporter = ReporterThread::new_with_duration(
81//! receiver, Duration::from_millis(50), NoopTracer::report
82//! );
83//! GlobalTracer::init(tracer);
84//!
85//! // ... snip ...
86//! }
87//! ```
88//!
89//!
90//! ## Tracing an operation
91//!
92//! Now that a `Tracer` is configured and we are sending `FinishedSpan`s to a
93//! distributed tracing software, it is possible to trace operations.
94//!
95//! Tracing operations is done by:
96//!
97//! * Creating a named `Span` that represents the operation.
98//! * Attaching causality information with `SpanContext`s.
99//! * Adding any needed metadata.
100//! * Finishing the span once the operation is done.
101//!
102//! ```
103//! extern crate opentracingrust;
104//!
105//! use std::time::Duration;
106//!
107//! use opentracingrust::SpanContext;
108//! use opentracingrust::StartOptions;
109//!
110//! use opentracingrust::tracers::NoopTracer;
111//! use opentracingrust::utils::GlobalTracer;
112//! use opentracingrust::utils::ReporterThread;
113//!
114//!
115//! fn main() {
116//! let (tracer, receiver) = NoopTracer::new();
117//! let reporter = ReporterThread::new_with_duration(
118//! receiver, Duration::from_millis(50), NoopTracer::report
119//! );
120//! GlobalTracer::init(tracer);
121//! // Once the tracer is configured we can start working.
122//! start_working();
123//! }
124//!
125//! fn start_working() {
126//! let mut root_span = GlobalTracer::get().span("start_working");
127//! // The actual work is done in a sub-operation.
128//! do_work(root_span.context().clone());
129//! root_span.finish();
130//! }
131//!
132//! fn do_work(context: SpanContext) {
133//! let mut span = GlobalTracer::get().span_with_options(
134//! "do_work", StartOptions::default().child_of(context)
135//! );
136//! // ... do work ...
137//! span.finish();
138//! }
139//! ```
140//!
141//! The `examples/` directoy includes many more working
142//! end-to-end examples of different use cases.
143//!
144//!
145//! ## The `NoopTracer`
146//!
147//! As mentioned above, the crate does not provide concrete `Tracer`s
148//! but rather a standard interface for projects to bind against.
149//!
150//! The `NoopTracer` is the perfect tool to write tests with and a good default
151//! for examples and projects that do not yet implement full tracing support.
152#![doc(html_root_url = "https://docs.rs/opentracingrust/0.4.0")]
153extern crate crossbeam_channel;
154extern crate rand;
155
156mod carrier;
157mod errors;
158mod span;
159mod span_context;
160mod tracer;
161
162pub mod tracers;
163pub mod utils;
164
165
166pub use self::carrier::ExtractFormat;
167pub use self::carrier::InjectFormat;
168pub use self::carrier::MapCarrier;
169
170pub use self::errors::Error;
171pub use self::errors::Result;
172
173pub use self::span_context::ImplContext;
174pub use self::span_context::ImplContextBox;
175pub use self::span_context::SpanContext;
176pub use self::span_context::SpanReferenceAware;
177
178pub use self::span::AutoFinishingSpan;
179pub use self::span::FinishedSpan;
180pub use self::span::Span;
181pub use self::span::SpanReceiver;
182pub use self::span::SpanReference;
183pub use self::span::SpanSender;
184pub use self::span::StartOptions;
185
186pub use self::span::log::Log;
187pub use self::span::log::LogValue;
188pub use self::span::tag::TagValue;
189
190pub use self::tracer::Tracer;
191pub use self::tracer::TracerInterface;