provide-telemetry/rust
SPDX-License-Identifier: Apache-2.0 SPDX-FileCopyrightText: Copyright (C) 2026 provide.io llc
Structured logging + OpenTelemetry traces and metrics for Rust — feature
parity with the provide-telemetry
Python, TypeScript, and Go packages.
Install
Add to Cargo.toml:
[]
= { = "../rust" } # local workspace
# or once published:
# provide-telemetry = "0.3"
Requires Rust 1.81+.
Quick start
use ;
API reference
Setup
| Export | Description |
|---|---|
setup_telemetry() |
Idempotent init from environment variables. |
reconfigure_telemetry(overrides) |
Hot-reload sampling / backpressure / exporter policy. |
shutdown_telemetry() |
Flush and shut down all providers. |
get_runtime_config() |
Inspect the applied config snapshot. |
get_runtime_status() |
Inspect provider state, fallback mode, last error. |
Logging
let logger = get_logger;
logger.debug;
logger.info;
logger.warn;
logger.error;
// Attach structured fields inline
logger.info_with;
// Attach DARS metadata (domain.action.resource.status)
use event;
let ev = event.expect;
logger.info_event;
Event names follow the DA(R)S pattern: event() accepts 3–4 dot-separated
segments; event_name() accepts 3–5 segments.
Tracing
use ;
trace;
Metrics
use ;
let reqs = counter;
reqs.add;
let lat = histogram;
lat.record;
let cpu = gauge;
cpu.set;
Context binding
use ;
use BTreeMap;
let mut fields = new;
fields.insert;
fields.insert;
bind_context;
// All log calls on this task/thread include these fields automatically.
clear_context;
Session correlation
use ;
bind_session_context;
let sid = get_session_id; // Some("sess-abc-123")
clear_session_context;
W3C trace propagation
use ;
// In an HTTP handler — extract incoming traceparent/tracestate.
let traceparent = headers.get.map;
let baggage = headers.get.map;
let pc = extract_w3c_context;
bind_propagation_context;
// ... handle request ...
clear_propagation_context;
PII sanitization
use ;
use json;
register_pii_rule;
let payload = json!;
let clean = sanitize_payload;
// clean["user"]["ssn"] == "***"
Built-in: redacts password, token, secret, authorization, api_key,
and similar keys by default.
Health snapshot
use get_health_snapshot;
let snap = get_health_snapshot;
println!;
Testing helpers
Configuration
All options come from environment variables:
| Env var | Default | Description |
|---|---|---|
PROVIDE_TELEMETRY_SERVICE_NAME |
provide-service |
Service identity |
PROVIDE_TELEMETRY_ENV |
dev |
Deployment environment |
PROVIDE_TELEMETRY_VERSION |
0.0.0 |
Service version |
PROVIDE_LOG_LEVEL |
INFO |
Log level: TRACE / DEBUG / INFO / WARN / ERROR |
PROVIDE_LOG_FORMAT |
console |
Output format: console / json / pretty |
PROVIDE_LOG_PRETTY_KEY_COLOR |
dim |
ANSI color name for keys in pretty format |
PROVIDE_LOG_PRETTY_VALUE_COLOR |
"" |
ANSI color name for values in pretty format |
PROVIDE_LOG_PRETTY_FIELDS |
"" |
Comma-separated field names to display in pretty format |
PROVIDE_TELEMETRY_STRICT_SCHEMA |
false |
Enforce DA(R)S event name format |
PROVIDE_TRACE_ENABLED |
true |
Enable tracing |
PROVIDE_TRACE_SAMPLE_RATE |
1.0 |
Trace sample rate [0.0, 1.0] |
PROVIDE_METRICS_ENABLED |
true |
Enable metrics |
PROVIDE_SAMPLING_LOGS_RATE |
1.0 |
Log sampling rate [0.0, 1.0] |
PROVIDE_BACKPRESSURE_LOGS_MAXSIZE |
1000 |
Max queued log events before backpressure |
PROVIDE_SECURITY_MAX_ATTR_VALUE_LENGTH |
1024 |
Truncate long field values at this byte count |
PROVIDE_SECURITY_MAX_ATTR_COUNT |
64 |
Maximum context attributes per log record |
PROVIDE_SECURITY_MAX_NESTING_DEPTH |
8 |
Maximum PII sanitization recursion depth |
OTEL_EXPORTER_OTLP_ENDPOINT |
— | OTLP base endpoint (e.g. http://localhost:4318) |
OTEL_EXPORTER_OTLP_HEADERS |
— | Percent-encoded key=value auth headers |
OTEL_METRIC_EXPORT_INTERVAL |
60000 |
Metrics push interval in milliseconds (--features otel) |
Cargo features
| Feature | Default | Description |
|---|---|---|
governance |
yes | Data governance / consent gating. Without this, should_allow is always true. |
otel |
no | Real OTLP export for traces, metrics, and logs via opentelemetry-otlp (HTTP/protobuf). When off, the crate provides in-process fallback instrumentation (noop tracer, in-process metrics, stderr-only logs). |
otel-grpc |
no | Adds gRPC transport on top of otel. Requires tonic (heavier dep tree). |
OTLP export
When built with --features otel, setup_telemetry() installs real
TracerProvider, MeterProvider, and LoggerProvider backed by OTLP
HTTP/protobuf exporters. All three signals (traces, metrics, logs) are
emitted to the configured endpoint:
| Env Var | Example | Notes |
|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT |
http://localhost:4318 |
Shared base URL; per-signal paths (/v1/traces, /v1/metrics, /v1/logs) are appended automatically. |
OTEL_EXPORTER_OTLP_HEADERS |
Authorization=Basic%20dXNlcjpwYXNz |
Shared auth header (percent-encoded). |
OTEL_EXPORTER_OTLP_PROTOCOL |
http/protobuf |
Default. Also accepts http/json. grpc requires --features otel-grpc. |
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT |
http://traces:4318/v1/traces |
Signal-specific override (used verbatim, no path appending). |
OTEL_METRIC_EXPORT_INTERVAL |
60000 |
Metrics push interval in milliseconds. |
Tokio runtime requirement: this crate depends on tokio (for
run_with_resilience retry/timeout logic) regardless of feature flags.
With --features otel the SDK's batch span processor and periodic metrics
reader additionally require an active multi-threaded runtime. Call
setup_telemetry() from within a #[tokio::main] function or an
explicit tokio::runtime::Builder runtime:
async
Architecture: consent, sampling, backpressure, and resilience
modules act as pre-filters. The OTel SDK sits behind them and handles
batching + OTLP network export only. When OTel is unconfigured or the
feature is off, the crate falls back gracefully to in-process
instrumentation (stderr logs, noop tracer, in-process counters).
Spec conformance
This crate implements every required: true symbol in
spec/telemetry-api.yaml, with names
converted to Rust snake_case per the spec's naming_conventions.rust rule.
Run the conformance validator:
Examples
The example suite covers the same numbered telemetry topics as Python, TypeScript, and Go, includes OpenObserve integration examples, and keeps the OTLP E2E client/server pair used by the cross-language verification flow.
Requirements
- Rust 1.81+
Coverage gate
Rust CI enforces zero uncovered project lines with cargo-llvm-cov.
The gate ignores Rust standard-library source paths only; missed lines in
rust/ fail the workflow. Locally:
RUST_TEST_THREADS=1
Performance gate
Hot-path benchmarks (benches/hot_path.rs) run on every CI push as the
performance-smoke job, comparing per-op measurements against
baselines/perf-rust.json for the runner's OS bucket. Locally:
make perf-rust. See docs/PERFORMANCE.md for
the gate's design (5x default tolerance, OS-tagged baselines) and how to
seed or refresh entries.
Mutation testing
The Rust nightly mutation sweep is advisory only. It does not gate
CI the way the Python and Go mutation suites do, and the current
baseline in rust/mutants.out/ records a Failure
summary — the sweep's own build/test baseline is broken and no mutants
have been scored against it yet. Configuration lives in
rust/.cargo/mutants.toml.
Re-run the sweep from rust/:
This exactly mirrors the invocation used by the Rust mutation job in
.github/workflows/ci-mutation.yml.
Sweep outputs land in rust/mutants.out/ (tracked), including
outcomes.json, caught.txt, missed.txt, and per-mutant logs.
License
Apache-2.0. See LICENSE.