1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
//! [OpenTracing][opentracing] API for Rust
//!
//! # Examples
//!
//! ```
//! use rustracing::sampler::AllSampler;
//! use rustracing::tag::Tag;
//! use rustracing::Tracer;
//! use std::thread;
//! use std::time::Duration;
//!
//! // Creates a tracer
//! let (span_tx, span_rx) = crossbeam_channel::bounded(10);
//! let tracer = Tracer::with_sender(AllSampler, span_tx);
//! {
//! // Starts "parent" span
//! let parent_span = tracer.span("parent").start_with_state(());
//! thread::sleep(Duration::from_millis(10));
//! {
//! // Starts "child" span
//! let mut child_span = tracer
//! .span("child_span")
//! .child_of(&parent_span)
//! .tag(Tag::new("key", "value"))
//! .start_with_state(());
//!
//! child_span.log(|log| {
//! log.error().message("a log message");
//! });
//! } // The "child" span dropped and will be sent to `span_rx`
//! } // The "parent" span dropped and will be sent to `span_rx`
//!
//! // Outputs finished spans to the standard output
//! while let Ok(span) = span_rx.try_recv() {
//! println!("# SPAN: {:?}", span);
//! }
//! ```
//!
//! As an actual usage example of the crate and an implmentation of the [OpenTracing] API,
//! it may be helpful to looking at [rustracing_jaeger] crate.
//!
//! # References
//!
//! - [The OpenTracing Semantic Specification (v1.1)][specification]
//!
//! [opentracing]: http://opentracing.io/
//! [specification]: https://github.com/opentracing/specification/blob/master/specification.md
//! [rustracing_jaeger]: https://github.com/sile/rustracing_jaeger
#![warn(missing_docs)]
#![allow(clippy::new_ret_no_self)]
#[macro_use]
extern crate trackable;
pub use crate::error::{Error, ErrorKind};
pub use crate::tracer::Tracer;
pub mod carrier;
pub mod convert;
pub mod log;
pub mod sampler;
pub mod span;
pub mod tag;
mod error;
mod tracer;
/// This crate specific `Result` type.
pub type Result<T> = std::result::Result<T, Error>;
#[cfg(test)]
mod tests {
use super::*;
use crate::sampler::AllSampler;
use crate::tag::{StdTag, Tag};
use std::thread;
use std::time::Duration;
#[test]
fn it_works() {
let (span_tx, span_rx) = crossbeam_channel::bounded(10);
let tracer = Tracer::with_sender(AllSampler, span_tx);
{
let span = tracer.span("it_works").start_with_state(());
let mut child = span.child("child", |options| options.start_with_state(()));
child.set_tags(|| StdTag::peer_addr("127.0.0.1:80".parse().unwrap()));
}
let span = span_rx.try_recv().unwrap();
assert_eq!(span.operation_name(), "child");
let span = span_rx.try_recv().unwrap();
assert_eq!(span.operation_name(), "it_works");
}
#[test]
fn example_code_works() {
// Creates a tracer
let (span_tx, span_rx) = crossbeam_channel::bounded(10);
let tracer = Tracer::with_sender(AllSampler, span_tx);
{
// Starts "parent" span
let parent_span = tracer.span("parent").start_with_state(());
thread::sleep(Duration::from_millis(10));
{
// Starts "child" span
let mut child_span = tracer
.span("child_span")
.child_of(&parent_span)
.tag(Tag::new("key", "value"))
.start_with_state(());
child_span.log(|log| {
log.error().message("a log message");
});
} // The "child" span dropped and will be sent to `span_rx`
} // The "parent" span dropped and will be sent to `span_rx`
// Outputs finished spans to the standard output
let mut count = 0;
while let Ok(span) = span_rx.try_recv() {
println!("# SPAN: {:?}", span);
count += 1;
}
assert_eq!(count, 2);
}
#[test]
fn nonblocking_on_full_queue() {
let (span_tx, span_rx) = crossbeam_channel::bounded(2);
let tracer = Tracer::with_sender(AllSampler, span_tx);
{
let span = tracer.span("first").start_with_state(());
let mut child = span.child("second", |options| options.start_with_state(()));
child.set_tags(|| StdTag::peer_addr("127.0.0.1:80".parse().unwrap()));
let _ = tracer.span("third").start_with_state(());
} // All spans dropped but only two ones will be sent to `span_rx` due to capacity limit, others are lost
// If the code continues, there was no blocking operation while sending span to the channel
assert!(span_rx.is_full());
assert_eq!(span_rx.len(), 2);
let span = span_rx.try_recv().unwrap();
assert_eq!(span.operation_name(), "third");
let span = span_rx.try_recv().unwrap();
assert_eq!(span.operation_name(), "second");
assert!(span_rx.is_empty());
}
}