Opinionated telemetry setup for Rust services.
use telemetry_setup::TelemetryBuilder;
fn main() -> Result<(), telemetry_setup::TelemetryError> {
let _telemetry = TelemetryBuilder::new("controller").init()?;
tracing::info!("started");
Ok(())
}Keep the returned TelemetryGuard alive for the lifetime of the process:
- call
TelemetryGuard::shutdown().awaitduring teardown for a clean flush - initialize telemetry once per process; calling
init()more than once is unsupported - dropping the guard without calling
shutdown()first is only a best-effort fallback - on multi-thread Tokio runtimes, drop attempts a final OTLP flush
- on
current_threadruntimes, OTLP flush-on-drop is unavailable because that path relies ontokio::task::block_in_place, so explicit shutdown is strongly preferred
This crate enables Tokio's rt-multi-thread feature to support the multi-thread drop path.
Tokio metrics require the tokio-metrics feature and an installed OpenTelemetry
meter provider. With OTLP enabled, this crate installs one automatically.
Without OTLP, consumers must install their own meter provider or Tokio metrics
will record into OpenTelemetry's default no-op global meter.
- formatted
tracinglogs to stdout - optional OTLP export for traces, logs, and metrics
- optional
journaldoutput - optional localhost-only log-level control API
- optional Tokio runtime metrics via OpenTelemetry
Cargo features:
otlp— enables OTLP trace, log, and metric export and the OTLP configuration typesjournald— enablestracing-journaldoutputlog-control— enables localhost-only HTTP endpoints for runtime filter changestokio-metrics— enables Tokio runtime gauges via OpenTelemetry
This example assumes the otlp, log-control, journald, and tokio-metrics
crate features are enabled.
# use std::collections::HashMap;
# use telemetry_setup::{LogControlConfig, OtlpConfig, OtlpHeadersConfig, TelemetryBuilder};
# fn example() -> Result<(), telemetry_setup::TelemetryError> {
let _telemetry = TelemetryBuilder::new("controller")
.with_stdout_filter("info")
.with_otlp_config(OtlpConfig {
url: "http://localhost:4318".to_string(),
headers: OtlpHeadersConfig {
common: HashMap::from([(
"X-Greptime-DB-Name".to_string(),
"edge".to_string(),
)]),
traces: HashMap::from([(
"x-greptime-pipeline-name".to_string(),
"greptime_trace_v1".to_string(),
)]),
logs: HashMap::from([(
"x-greptime-pipeline-name".to_string(),
"greptime_identity".to_string(),
)]),
..OtlpHeadersConfig::default()
},
..OtlpConfig::default()
})
.with_log_control(LogControlConfig { port: 6669 })
.enable_journald()
.enable_tokio_metrics()
.init()?;
# Ok(())
# }Defaults:
- stdout filter:
RUST_LOG, falling back toinfo - log-control port:
6669 - OTLP endpoint:
http://localhost:4318 - OTLP metric interval: 5 seconds, configurable from 1 second to 1 day
- Tokio metrics interval: 5 seconds
Use TelemetryBuilder::without_env_var() to ignore RUST_LOG.
When log-control is enabled, the crate binds an HTTP server only on 127.0.0.1.
There is no authentication, so any local process can inspect and change runtime filters.
Invalid filters return 400.
GET /filtersreturns{ "stdout": "...", "otlp": "..." | null }PUT /filters/stdoutaccepts{ "filter": "..." }and returns the updated filter statePUT /filters/otlpaccepts{ "filter": "..." }, returns the updated filter state, and returns404when OTLP is unavailable
See examples/:
stdout_only.rs— local stdout logging with no exporters or control APIstdout_custom_filter.rs— stdout logging with an explicit fallback filtergreptime_otlp.rs— GreptimeDB OTLP/HTTP traces, logs, and metrics configuration
Companion configuration:
greptime_otlp.toml— configuration for the GreptimeDB example
GreptimeDB export does not require a dedicated feature; configure headers with
OtlpConfig::headers.
Licensed under the MIT License. See LICENSE.