use anyhow::Result; use clap::Parser; use dropshot::endpoint; use dropshot::ApiDescription; use dropshot::ConfigDropshot; use dropshot::HttpError; use dropshot::HttpResponseOk; use dropshot::RequestContext; use dropshot::ServerBuilder; use opentelemetry::{trace::TracerProvider as _, KeyValue}; use opentelemetry_otlp::WithExportConfig; use opentelemetry_sdk::{ trace::{RandomIdGenerator, Sampler}, Resource, }; use opentelemetry_semantic_conventions::{ attribute::{SERVICE_NAME, SERVICE_VERSION}, SCHEMA_URL, }; use schemars::JsonSchema; use serde::Serialize; use slog::Drain; use tracing_opentelemetry::OpenTelemetryLayer; use tracing_slog::TracingSlogDrain; use tracing_subscriber::prelude::*; use std::net::SocketAddr; use std::str::FromStr; use std::sync::Arc; #[derive(Parser, Debug)] #[command(version, about, long_about = None)] struct Cli {} /// Represents a project in our API. #[derive(Serialize, JsonSchema)] struct VersionInfo { /// Name of the project. name: String, } /// Fetch version info. #[endpoint { method = GET, path = "/version", }] #[tracing::instrument()] async fn api_version( rqctx: RequestContext<Arc<()>>, ) -> Result<HttpResponseOk<VersionInfo>, HttpError> { let ver = VersionInfo { name: String::from("patagia-controller"), }; Ok(HttpResponseOk(ver)) } #[tokio::main] async fn main() -> Result<(), String> { let _args = Cli::parse(); let fmt_layer = tracing_subscriber::fmt::layer(); let mut config_dropshot = ConfigDropshot::default(); config_dropshot.bind_address = SocketAddr::from_str("0.0.0.0:9474").unwrap(); config_dropshot.request_body_max_bytes = 1024 * 1024; // Adapt the Dropshot logger to tracing let dropshot_logger = { let level_drain = slog::LevelFilter(TracingSlogDrain, slog::Level::Debug).fuse(); let async_drain = slog_async::Async::new(level_drain).build().fuse(); slog::Logger::root(async_drain, slog::o!()) }; let otlp_exporter = opentelemetry_otlp::SpanExporter::builder() .with_tonic() .with_endpoint("https://localhost:4317") .build() .map_err(|e| e.to_string())?; let resource = Resource::from_schema_url( [ // KeyValue::new(SERVICE_NAME, env!("CARGO_PKG_NAME")), KeyValue::new(SERVICE_NAME, "patagia-controller"), KeyValue::new(SERVICE_VERSION, env!("CARGO_PKG_VERSION")), ], SCHEMA_URL, ); let tracer_provider = opentelemetry_sdk::trace::TracerProvider::builder() .with_config( opentelemetry_sdk::trace::Config::default() .with_sampler(Sampler::ParentBased(Box::new(Sampler::TraceIdRatioBased( 1.0, )))) .with_id_generator(RandomIdGenerator::default()) .with_resource(resource), ) .with_batch_exporter(otlp_exporter, opentelemetry_sdk::runtime::Tokio) .build(); let tracer = tracer_provider.tracer("patagia-controller"); // let telemetry = tracing_opentelemetry::layer().with_tracer(tracer); tracing_subscriber::registry() .with(tracing_subscriber::EnvFilter::from_default_env()) .with(fmt_layer) // .with(telemetry) .with(OpenTelemetryLayer::new(tracer)) .init(); tracing::info!("Patagia Controller"); foo().await; let mut api = ApiDescription::new(); api.register(api_version).map_err(|e| e.to_string())?; let server = ServerBuilder::new(api, Arc::new(()), dropshot_logger) .config(config_dropshot) .start() .map_err(|e| e.to_string())?; server.await } #[tracing::instrument] async fn foo() { tracing::info!( monotonic_counter.foo = 1_u64, key_1 = "bar", key_2 = 10, "This is the Foo!", ); tracing::info!(histogram.baz = 10, "histogram example",); }