diff --git a/examples/metrics-basic/Cargo.toml b/examples/metrics-basic/Cargo.toml index 37b79da140..b68573e60a 100644 --- a/examples/metrics-basic/Cargo.toml +++ b/examples/metrics-basic/Cargo.toml @@ -6,12 +6,9 @@ license = "Apache-2.0" publish = false [dependencies] -opentelemetry = { path = "../../opentelemetry", features = ["metrics", "otel_unstable"] } +opentelemetry = { path = "../../opentelemetry", features = ["metrics"] } opentelemetry_sdk = { path = "../../opentelemetry-sdk", features = ["metrics", "rt-tokio"] } opentelemetry-stdout = { path = "../../opentelemetry-stdout", features = ["metrics"]} tokio = { workspace = true, features = ["full"] } serde_json = { workspace = true } -[features] -default = ["otel_unstable"] -otel_unstable = ["opentelemetry/otel_unstable"] diff --git a/opentelemetry/src/lib.rs b/opentelemetry/src/lib.rs index 0e4dd54fc9..a2470a6447 100644 --- a/opentelemetry/src/lib.rs +++ b/opentelemetry/src/lib.rs @@ -5,26 +5,7 @@ //! [`API`]: https://opentelemetry.io/docs/specs/otel/overview/#api //! [OpenTelemetry]: https://opentelemetry.io/docs/what-is-opentelemetry/ //! -//! # Getting Started -//! -//! ```no_run -//! # #[cfg(feature = "trace")] -//! # { -//! use opentelemetry::{global, trace::{TraceContextExt, Tracer}, Context }; -//! -//! fn do_something() { -//! let tracer = global::tracer("my_component"); -//! let _guard = Context::current_with_span(tracer.start("my_span")).attach(); -//! // do work tracked by the now current span -//! } -//! # } -//! ``` -//! -//! See the [examples] directory for different integration patterns. -//! -//! [examples]: https://github.com/open-telemetry/opentelemetry-rust/tree/main/examples -//! -//! # Traces +//! # Getting Started with Traces //! //! The [`trace`] module includes types for tracking the progression of a single //! request while it is handled by services that make up an application. A trace @@ -32,8 +13,6 @@ //! by individual services or components involved in a request as it flows //! through a system. //! -//! ### Creating and exporting spans -//! //! ``` //! # #[cfg(feature = "trace")] //! # { @@ -55,40 +34,111 @@ //! # } //! ``` //! +//! See the [examples](https://github.com/open-telemetry/opentelemetry-rust/tree/main/examples) directory for different integration patterns. +//! //! See the [`trace`] module docs for more information on creating and managing //! spans. //! //! [`Span`]: crate::trace::Span //! -//! # Metrics -//! -//! -//! The [`metrics`] module includes types for recording measurements about a -//! service at runtime. -//! -//! ### Creating instruments and recording measurements -//! +//! # Getting Started with Metrics +//! +//! The [`metrics`] module provides types for recording measurements about a +//! service at runtime. Below are the key steps to report measurements using +//! OpenTelemetry Metrics: +//! +//! 1. **Obtain a Meter:** Get a `Meter` from a `MeterProvider`. +//! 2. **Create Instruments:** Use the `Meter` to create one or more instruments +//! (e.g., counters, histograms). +//! 3. **Record Measurements:** Use the instruments to record measurement values +//! along with optional attributes. +//! +//! ## How Metrics work in OpenTelemetry +//! In OpenTelemetry, raw measurements recorded using instruments are +//! **aggregated in memory** to form metrics. These aggregated metrics are +//! periodically exported by the [`opentelemetry_sdk`] at fixed intervals (e.g., +//! every 60 seconds) via exporters such as [`opentelemetry-stdout`] or +//! [`opentelemetry-otlp`]. This reduces reporting overhead while ensuring +//! up-to-date data. The aggregation strategy and export interval can be +//! customized in the [`opentelemetry_sdk`] based on your use case. +//! +//! ## Choosing the Right Instrument +//! Selecting the correct instrument is critical for accurately representing +//! your metrics data: +//! +//! - Use **Counters** for values that only increase, such as the number of +//! requests served or errors encountered. +//! - Use **UpDownCounters** for values that can increase or decrease, such as +//! the number of active connections, number of items in a queue etc. +//! - **Gauges:** Use for values that can go up or down and represent the +//! current state, such as CPU usage, temperature etc. +//! - Use **Histograms** for measuring the distribution of a value, such as +//! response times or payload sizes. +//! +//! ### Observable Instruments +//! +//! Counters, UpDownCounters, and Gauges have Observable variants that allow +//! values to be reported through a callback function. Observable instruments +//! are ideal when the metric value is managed elsewhere and needs to be +//! observed by OpenTelemetry instrumentation. The callbacks are automatically +//! invoked by the OpenTelemetry SDK before every export (e.g., every 60 +//! seconds). +//! +//! For example: +//! - An **ObservableCounter** can monitor the number of page faults in a +//! process as reported by the operating system. +//! - An **ObservableUpDownCounter** can monitor the size of an in-memory queue +//! by reporting the size using queue's len() method within the callback +//! function. +//! - An **ObservableGauge** can monitor the CPU temperature by using +//! temperature sensor APIs within the callback function. +//! +//! For detailed guidance, refer to [OpenTelemetry Metrics API - Instrumentation +//! Guidance](https://opentelemetry.io/docs/specs/otel/metrics/supplementary-guidelines/#instrument-selection). +//! +//! ## Best Practices +//! - **Re-use Instruments:** Instruments are designed for +//! reuse. Avoid creating new instruments repeatedly. +//! - **Clone for Sharing:** If the same instrument needs to be used across +//! multiple parts of your code, you can safely clone it to share. +//! +//! ## Example Usage //! ``` -//! # #[cfg(feature = "metrics")] -//! # { //! use opentelemetry::{global, KeyValue}; //! -//! // get a meter from a provider +//! // Get a meter from a provider. //! let meter = global::meter("my_service"); //! -//! // create an instrument -//! let counter = meter.u64_counter("my_counter").build(); +//! // Create an instrument (in this case, a Counter). +//! let counter = meter.u64_counter("request.count").build(); //! -//! // record a measurement +//! // Record a measurement by passing the value and a set of attributes. //! counter.add(1, &[KeyValue::new("http.client_ip", "83.164.160.102")]); -//! # } +//! +//! // Create an ObservableCounter and register a callback that reports the measurement. +//! let _observable_counter = meter +//! .u64_observable_counter("bytes_received") +//! .with_callback(|observer| { +//! observer.observe( +//! 100, +//! &[ +//! KeyValue::new("protocol", "udp"), +//! ], +//! ) +//! }) +//! .build(); //! ``` //! +//! See the +//! [examples](https://github.com/open-telemetry/opentelemetry-rust/tree/main/examples/metrics-basic) +//! directory that show a runnable example with all type of instruments. +//! +//! //! See the [`metrics`] module docs for more information on creating and //! managing instruments. //! //! -//! # Logs +//! # Getting Started with Logs //! //! The [`logs`] module contains the Logs Bridge API. It is not intended to be //! called by application developers directly. It is provided for logging @@ -102,23 +152,24 @@ //! [`opentelemetry-appender-tracing`](https://crates.io/crates/opentelemetry-appender-tracing) //! crates. //! -//! ## Crate Feature Flags +//! # Crate Feature Flags //! //! The following core crate feature flags are available: //! //! * `trace`: Includes the trace API. //! * `metrics`: Includes the metrics API. //! * `logs`: Includes the logs bridge API. +//! * `internal-logs`: Includes internal logging for the OpenTelemetry library via `tracing`. //! -//! The default feature flags are ["trace", "metrics", "logs"] +//! The default feature flags are ["trace", "metrics", "logs", "internal-logs"]. //! //! The following feature flags provides additional configuration for `logs`: //! * `spec_unstable_logs_enabled`: Allow users to control the log level //! //! The following feature flags enable APIs defined in OpenTelemetry specification that is in experimental phase: -//! * `otel_unstable`: Includes unstable APIs. +//! * `otel_unstable`: Includes unstable APIs. There are no features behind this flag at the moment. //! -//! ## Related Crates +//! # Related Crates //! //! In addition to `opentelemetry`, the [`open-telemetry/opentelemetry-rust`] //! repository contains several additional crates designed to be used with the @@ -133,6 +184,8 @@ //! trace information from [`http`] headers. //! - [`opentelemetry-otlp`] exporter for sending telemetry in the //! OTLP format. +//! - [`opentelemetry-stdout`] provides ability to output telemetry to stdout, +//! primarily used for learning/debugging purposes. //! - [`opentelemetry-prometheus`] provides a pipeline and exporter for sending //! metrics information to [`Prometheus`]. //! - [`opentelemetry-zipkin`] provides a pipeline and exporter for sending @@ -148,6 +201,7 @@ //! [`http`]: https://crates.io/crates/http //! [`open-telemetry/opentelemetry-rust`]: https://github.com/open-telemetry/opentelemetry-rust //! [`opentelemetry_sdk`]: https://crates.io/crates/opentelemetry_sdk +//! [`opentelemetry-stdout`]: https://crates.io/crates/opentelemetry_stdout //! [`opentelemetry-http`]: https://crates.io/crates/opentelemetry-http //! [`opentelemetry-otlp`]: https://crates.io/crates/opentelemetry-otlp //! [`opentelemetry-prometheus`]: https://crates.io/crates/opentelemetry-prometheus @@ -155,7 +209,7 @@ //! [`Prometheus`]: https://prometheus.io //! [`Zipkin`]: https://zipkin.io //! -//! ## Supported Rust Versions +//! # Supported Rust Versions //! //! OpenTelemetry is built against the latest stable release. The minimum //! supported version is 1.70. The current OpenTelemetry version is not