#![deny(
explicit_outlives_requirements,
macro_use_extern_crate,
missing_debug_implementations,
trivial_casts,
trivial_numeric_casts,
unreachable_pub,
unsafe_code,
unused_qualifications,
unused_results,
variant_size_differences,
unused_variables,
clippy::complexity,
clippy::nursery,
clippy::pedantic,
clippy::perf,
clippy::style,
clippy::suspicious,
clippy::clone_on_ref_ptr,
clippy::create_dir,
clippy::dbg_macro,
clippy::default_numeric_fallback,
clippy::else_if_without_else,
clippy::empty_structs_with_brackets,
clippy::expect_used,
clippy::get_unwrap,
clippy::let_underscore_must_use,
clippy::map_err_ignore,
clippy::multiple_inherent_impl,
clippy::panic,
clippy::panic_in_result_fn,
clippy::pub_use,
clippy::rc_mutex,
clippy::rest_pat_in_fully_bound_structs,
clippy::same_name_method,
clippy::self_named_module_files,
clippy::shadow_reuse,
clippy::shadow_same,
clippy::shadow_unrelated,
clippy::unseparated_literal_suffix,
clippy::string_to_string,
clippy::todo,
clippy::unimplemented,
clippy::unreachable,
clippy::unwrap_in_result,
clippy::unwrap_used,
clippy::use_debug,
clippy::verbose_file_reads,
clippy::wildcard_enum_match_arm
)]
pub mod tracing {
use eyre::{eyre, Result};
use tracing_subscriber::EnvFilter;
pub fn init() -> Result<()> {
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.try_init()
.map_err(|error| eyre!("failed to initialize subscriber: {}", error))
}
}
pub mod otlp_tracing {
use eyre::Result;
use opentelemetry::KeyValue;
use opentelemetry_otlp::WithExportConfig;
use opentelemetry_sdk::{
runtime,
trace::{BatchConfig, RandomIdGenerator, Sampler},
Resource,
};
use opentelemetry_semantic_conventions::{
resource::{SERVICE_NAME, SERVICE_VERSION},
SCHEMA_URL,
};
use serde::Deserialize;
use tracing::instrument;
use tracing_opentelemetry::OpenTelemetryLayer;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter};
pub const DEFAULT_OTLP_GRPC_ENDPOINT: &str = "http://localhost:4317";
#[derive(Clone, Debug, Deserialize)]
#[serde(default)]
pub struct Configuration {
pub otlp_grpc_endpoint: String,
}
pub fn try_init(service_name: &'static str) -> Result<()> {
let configuration = Configuration::from_env()?;
tracing_subscriber::registry()
.with(EnvFilter::from_default_env())
.with(tracing_subscriber::fmt::layer())
.with(OpenTelemetryLayer::new(
opentelemetry_otlp::new_pipeline()
.tracing()
.with_trace_config(
opentelemetry_sdk::trace::Config::default()
.with_sampler(Sampler::ParentBased(Box::new(Sampler::TraceIdRatioBased(1.0))))
.with_id_generator(RandomIdGenerator::default())
.with_resource(Resource::from_schema_url(
[
KeyValue::new(SERVICE_NAME, service_name),
KeyValue::new(SERVICE_VERSION, env!("CARGO_PKG_VERSION")),
],
SCHEMA_URL,
)),
)
.with_batch_config(BatchConfig::default())
.with_exporter(
opentelemetry_otlp::new_exporter()
.tonic()
.with_endpoint(configuration.otlp_grpc_endpoint),
)
.install_batch(runtime::Tokio)?,
))
.try_init()?;
Ok(())
}
impl Configuration {
#[instrument(err(Debug), ret, level = "trace")]
pub fn from_env() -> Result<Self> {
Ok(envy::prefixed("OBSERVABILITY_").from_env::<Self>()?)
}
}
impl Default for Configuration {
fn default() -> Self {
Self {
otlp_grpc_endpoint: DEFAULT_OTLP_GRPC_ENDPOINT.to_string(),
}
}
}
}