opentelemetry_jaeger/
lib.rs

1//! Collects OpenTelemetry spans and reports them to a given Jaeger
2//! `agent` or `collector` endpoint, propagate the tracing context between the applications using [Jaeger propagation format].
3//!
4//! *Warning*: Note that the exporter component from this crate will be [deprecated][jaeger-deprecation]
5//! in the future. Users are advised to move to [opentelemetry_otlp][otlp-exporter] instead as [Jaeger][jaeger-otlp]
6//! supports accepting data in the OTLP protocol.
7//! See the [Jaeger Docs] for details about Jaeger and deployment information.
8//!
9//! *Compiler support: [requires `rustc` 1.64+][msrv]*
10//!
11//! [Jaeger Docs]: https://www.jaegertracing.io/docs/
12//! [jaeger-deprecation]: https://github.com/open-telemetry/opentelemetry-specification/pull/2858/files
13//! [jaeger-otlp]: https://www.jaegertracing.io/docs/1.38/apis/#opentelemetry-protocol-stable
14//! [otlp-exporter]: https://docs.rs/opentelemetry-otlp/latest/opentelemetry_otlp/
15//! [msrv]: #supported-rust-versions
16//! [jaeger propagation format]: https://www.jaegertracing.io/docs/1.18/client-libraries/#propagation-format
17//!
18//! ## Quickstart
19//!
20//! First make sure you have a running version of the Jaeger instance
21//! you want to send data to:
22//!
23//! ```shell
24//! $ docker run -d -p6831:6831/udp -p6832:6832/udp -p16686:16686 -p14268:14268 jaegertracing/all-in-one:latest
25//! ```
26//!
27//! Then install a new jaeger pipeline with the recommended defaults to start
28//! exporting telemetry:
29//!
30//! ```no_run
31//! use opentelemetry::{global, trace::{Tracer, TraceError}};
32//! use opentelemetry_jaeger_propagator;
33//!
34//! #[tokio::main]
35//! async fn main() -> Result<(), TraceError> {
36//!     global::set_text_map_propagator(opentelemetry_jaeger_propagator::Propagator::new());
37//!     let tracer = opentelemetry_jaeger::new_agent_pipeline().install_simple()?;
38//!
39//!     tracer.in_span("doing_work", |cx| {
40//!         // Traced app logic here...
41//!     });
42//!
43//!     global::shutdown_tracer_provider(); // export remaining spans
44//!
45//!     Ok(())
46//! }
47//! ```
48//!
49//! Or if you are running on an async runtime like Tokio and want to report spans in batches
50//! ```no_run
51//! use opentelemetry::{global, trace::{Tracer, TraceError}};
52//! use opentelemetry_sdk::runtime::Tokio;
53//! use opentelemetry_jaeger_propagator;
54//!
55//! fn main() -> Result<(), TraceError> {
56//!     global::set_text_map_propagator(opentelemetry_jaeger_propagator::Propagator::new());
57//!     let tracer = opentelemetry_jaeger::new_agent_pipeline().install_batch(Tokio)?;
58//!
59//!     tracer.in_span("doing_work", |cx| {
60//!         // Traced app logic here...
61//!     });
62//!
63//!     global::shutdown_tracer_provider(); // export remaining spans
64//!
65//!     Ok(())
66//! }
67//! ```
68//! ## Performance
69//!
70//! For optimal performance, a batch exporter is recommended as the simple exporter
71//! will export each span synchronously on drop. You can enable the `rt-tokio`,
72//! `rt-tokio-current-thread` or `rt-async-std` features and specify a runtime
73//! on the pipeline builder to have a batch exporter configured for you
74//! automatically.
75//!
76//! ```toml
77//! [dependencies]
78//! opentelemetry_sdk = { version = "*", features = ["rt-tokio"] }
79//! opentelemetry-jaeger = { version = "*", features = ["rt-tokio"] }
80//! ```
81//!
82//! ```no_run
83//! # fn main() -> Result<(), opentelemetry::trace::TraceError> {
84//! let tracer = opentelemetry_jaeger::new_agent_pipeline()
85//!     .install_batch(opentelemetry_sdk::runtime::Tokio)?;
86//! # Ok(())
87//! # }
88//! ```
89//!
90//! [`tokio`]: https://tokio.rs
91//! [`async-std`]: https://async.rs
92//!
93//! ## Jaeger Exporter From Environment Variables
94//!
95//! The jaeger pipeline builder can be configured dynamically via environment
96//! variables. All variables are optional, a full list of accepted options can
97//! be found in the [jaeger variables spec].
98//!
99//! [jaeger variables spec]: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md
100//!
101//! ## Jaeger Collector Example
102//!
103//! If you want to skip the agent and submit spans directly to a Jaeger collector,
104//! you can enable the optional `collector_client` feature for this crate. This
105//! example expects a Jaeger collector running on `http://localhost:14268`.
106//!
107//! ```toml
108//! [dependencies]
109//! opentelemetry-jaeger = { version = "..", features = ["collector_client", "isahc_collector_client"] }
110//! ```
111//!
112//! Then you can use the [`with_endpoint`] method to specify the endpoint:
113//!
114//! [`with_endpoint`]: exporter::config::collector::CollectorPipeline::with_endpoint
115//!
116//! ```ignore
117//! // Note that this requires the `collector_client` feature.
118//! // We enabled the `isahc_collector_client` feature for a default isahc http client.
119//! // You can also provide your own implementation via .with_http_client() method.
120//! use opentelemetry::trace::{Tracer, TraceError};
121//!
122//! fn main() -> Result<(), TraceError> {
123//!     let tracer = opentelemetry_jaeger::new_collector_pipeline()
124//!         .with_endpoint("http://localhost:14268/api/traces")
125//!         // optionally set username and password for authentication of the exporter.
126//!         .with_username("username")
127//!         .with_password("s3cr3t")
128//!         .with_isahc()
129//!         //.with_http_client(<your client>) provide custom http client implementation
130//!         .install_batch(opentelemetry_sdk::runtime::Tokio)?;
131//!
132//!     tracer.in_span("doing_work", |cx| {
133//!         // Traced app logic here...
134//!     });
135//!
136//!     Ok(())
137//! }
138//! ```
139//! ## Resource, tags and service name
140//! In order to export the spans in different format. opentelemetry uses its own
141//! model internally. Most of the jaeger spans' concept can be found in this model.
142//! The full list of this mapping can be found in [OpenTelemetry to Jaeger Transformation].
143//!
144//! The **process tags** in jaeger spans will be mapped as resource in opentelemetry. You can
145//! set it through `OTEL_RESOURCE_ATTRIBUTES` environment variable or using [`with_trace_config`].
146//!
147//! Note that to avoid copying data multiple times. Jaeger exporter will uses resource stored in [`Exporter`].
148//!
149//! The **tags** in jaeger spans will be mapped as attributes in opentelemetry spans. You can
150//! set it through [`set_attribute`] method.
151//!
152//! Each jaeger span requires a **service name**. This will be mapped as a resource with `service.name` key.
153//! You can set it using one of the following methods from highest priority to lowest priority.
154//! 1. [`with_service_name`].
155//! 2. include a `service.name` key value pairs when configure resource using [`with_trace_config`].
156//! 3. set the service name as `OTEL_SERVICE_NAME` environment variable.
157//! 4. set the `service.name` attributes in `OTEL_RESOURCE_ATTRIBUTES`.
158//! 5. if the service name is not provided by the above method. `unknown_service` will be used.
159//!
160//! Based on the service name, we update/append the `service.name` process tags in jaeger spans.
161//!
162//! [`with_service_name`]: crate::exporter::config::agent::AgentPipeline::with_service_name
163//! [`with_trace_config`]: crate::exporter::config::agent::AgentPipeline::with_trace_config
164//! [`set_attribute`]: opentelemetry::trace::Span::set_attribute
165//! [OpenTelemetry to Jaeger Transformation]:https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk_exporters/jaeger.md
166//!
167//! ## Kitchen Sink Full Configuration
168//!
169//! Example showing how to override all configuration options. See the
170//! [`CollectorPipeline`] and [`AgentPipeline`] docs for details of each option.
171//!
172//! [`CollectorPipeline`]: config::collector::CollectorPipeline
173//! [`AgentPipeline`]: config::agent::AgentPipeline
174//!
175//! ### Export to agents
176//! ```no_run
177//! use opentelemetry::{global, KeyValue, trace::{Tracer, TraceError}};
178//! use opentelemetry_sdk::{trace::{config, RandomIdGenerator, Sampler}, Resource};
179//! use opentelemetry_jaeger_propagator;
180//!
181//! fn main() -> Result<(), TraceError> {
182//!     global::set_text_map_propagator(opentelemetry_jaeger_propagator::Propagator::new());
183//!     let tracer = opentelemetry_jaeger::new_agent_pipeline()
184//!         .with_endpoint("localhost:6831")
185//!         .with_service_name("my_app")
186//!         .with_max_packet_size(9_216)
187//!         .with_auto_split_batch(true)
188//!         .with_instrumentation_library_tags(false)
189//!         .with_trace_config(
190//!             config()
191//!                 .with_sampler(Sampler::AlwaysOn)
192//!                 .with_id_generator(RandomIdGenerator::default())
193//!                 .with_max_events_per_span(64)
194//!                 .with_max_attributes_per_span(16)
195//!                  // resources will translated to tags in jaeger spans
196//!                 .with_resource(Resource::new(vec![KeyValue::new("key", "value"),
197//!                           KeyValue::new("process_key", "process_value")])),
198//!         )
199//!         .install_batch(opentelemetry_sdk::runtime::Tokio)?;
200//!
201//!     tracer.in_span("doing_work", |cx| {
202//!         // Traced app logic here...
203//!     });
204//!
205//!     // export remaining spans. It's optional if you can accept spans loss for the last batch.
206//!     global::shutdown_tracer_provider();
207//!
208//!     Ok(())
209//! }
210//! ```
211//!
212//! ### Export to collectors
213//! Note that this example requires `collector_client` and `isahc_collector_client` feature.
214//! ```ignore
215//! use opentelemetry::{global, KeyValue, trace::{Tracer, TraceError}};
216//! use opentelemetry_sdk::{trace::{config, RandomIdGenerator, Sampler}, Resource};
217//! use opentelemetry_jaeger_propagator;
218//!
219//! fn main() -> Result<(), TraceError> {
220//!     global::set_text_map_propagator(opentelemetry_jaeger_propagator::Propagator::new());
221//!     let tracer = opentelemetry_jaeger::new_collector_pipeline()
222//!         .with_endpoint("http://localhost:14250/api/trace") // set collector endpoint
223//!         .with_service_name("my_app") // the name of the application
224//!         .with_trace_config(
225//!             config()
226//!                 .with_sampler(Sampler::AlwaysOn)
227//!                 .with_id_generator(RandomIdGenerator::default())
228//!                 .with_max_events_per_span(64)
229//!                 .with_max_attributes_per_span(16)
230//!                 .with_max_events_per_span(16)
231//!                 // resources will translated to tags in jaeger spans
232//!                 .with_resource(Resource::new(vec![KeyValue::new("key", "value"),
233//!                           KeyValue::new("process_key", "process_value")])),
234//!         )
235//!         .with_username("username")
236//!         .with_password("s3cr3t")
237//!         .with_timeout(std::time::Duration::from_secs(2))
238//!         .install_batch(opentelemetry_sdk::runtime::Tokio)?;
239//!
240//!     tracer.in_span("doing_work", |cx| {
241//!         // Traced app logic here...
242//!     });
243//!
244//!     // export remaining spans. It's optional if you can accept spans loss for the last batch.
245//!     global::shutdown_tracer_provider();
246//!
247//!     Ok(())
248//! }
249//! ```
250//!
251//! # Crate Feature Flags
252//!
253//! The following crate feature flags are available:
254//!
255//! * `collector_client`: Export span data directly to a Jaeger collector. User MUST provide the http client.
256//!
257//! * `hyper_collector_client`: Export span data with Jaeger collector backed by a hyper default http client.
258//!
259//! * `reqwest_collector_client`: Export span data with Jaeger collector backed by a reqwest http client.
260//!
261//! * `reqwest_blocking_collector_client`: Export span data with Jaeger collector backed by a reqwest blocking http client.
262//!
263//! * `isahc_collector_client`: Export span data with Jaeger collector backed by a isahc http client.
264//!
265//! * `wasm_collector_client`: Enable collector in wasm.
266//!
267//! Support for recording and exporting telemetry asynchronously can be added
268//! via the following flags, it extends the [`opentelemetry`] feature:
269//!
270//! * `rt-tokio`: Enable sending UDP packets to Jaeger agent asynchronously when the tokio
271//!   [`Multi-Threaded Scheduler`] is used.
272//!
273//! * `rt-tokio-current-thread`: Enable sending UDP packets to Jaeger agent asynchronously when the
274//!   tokio [`Current-Thread Scheduler`] is used.
275//!
276//! * `rt-async-std`: Enable sending UDP packets to Jaeger agent asynchronously when the
277//!   [`async-std`] runtime is used.
278//!
279//! [`Multi-Threaded Scheduler`]: https://docs.rs/tokio/latest/tokio/runtime/index.html#multi-thread-scheduler
280//! [`Current-Thread Scheduler`]: https://docs.rs/tokio/latest/tokio/runtime/index.html#current-thread-scheduler
281//! [`async-std`]: https://async.rs
282//! [`opentelemetry`]: https://crates.io/crates/opentelemetry
283//!
284//! # Supported Rust Versions
285//!
286//! OpenTelemetry is built against the latest stable release. The minimum
287//! supported version is 1.64. The current OpenTelemetry version is not
288//! guaranteed to build on Rust versions earlier than the minimum supported
289//! version.
290//!
291//! The current stable Rust compiler and the three most recent minor versions
292//! before it will always be supported. For example, if the current stable
293//! compiler version is 1.64, the minimum supported version will not be
294//! increased past 1.46, three minor versions prior. Increasing the minimum
295//! supported compiler version is not considered a semver breaking change as
296//! long as doing so complies with this policy.
297#![warn(
298    future_incompatible,
299    missing_debug_implementations,
300    missing_docs,
301    nonstandard_style,
302    rust_2018_idioms,
303    unreachable_pub,
304    unused
305)]
306#![allow(deprecated)]
307#![cfg_attr(
308    docsrs,
309    feature(doc_cfg, doc_auto_cfg),
310    deny(rustdoc::broken_intra_doc_links)
311)]
312#![doc(
313    html_logo_url = "https://raw.githubusercontent.com/open-telemetry/opentelemetry-rust/main/assets/logo.svg"
314)]
315#![cfg_attr(test, deny(warnings))]
316
317pub use exporter::config;
318#[cfg(feature = "collector_client")]
319pub use exporter::config::collector::new_collector_pipeline;
320#[cfg(feature = "wasm_collector_client")]
321pub use exporter::config::collector::new_wasm_collector_pipeline;
322pub use exporter::{
323    config::agent::new_agent_pipeline, runtime::JaegerTraceRuntime, Error, Exporter, Process,
324};
325
326mod exporter;
327
328#[cfg(feature = "integration_test")]
329#[doc(hidden)]
330pub mod testing;