Skip to content

Instantly share code, notes, and snippets.

@matteosister
Last active November 30, 2020 11:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matteosister/c0a442a7f929d7a259893f8bd4bf733b to your computer and use it in GitHub Desktop.
Save matteosister/c0a442a7f929d7a259893f8bd4bf733b to your computer and use it in GitHub Desktop.
opentelemetry tracing update
// with these deps it compiles, but the global tracer do not log anything
// tracing = { version = "^0.1.21" }
// tracing-subscriber = "^0.2.15"
// tracing-opentelemetry = "^0.9.0"
// tracing-futures = "^0.2.4"
// opentelemetry = { version = "^0.10.0" }
// opentelemetry-jaeger = { version = "^0.9.0", features = ["collector_client"] }
//
// I call this from main with
// let uninstall = Tracing::initialize().expect("unable to initialize tracing");
use actix_web::http::HeaderName;
use actix_web::HttpRequest;
use log::info;
use opentelemetry::{
propagation::text_map_propagator::TextMapPropagator,
propagation::Extractor,
Key,
{sdk, sdk::propagation::TraceContextPropagator},
};
use opentelemetry_jaeger::Uninstall;
use tracing::Span;
use tracing_opentelemetry::OpenTelemetrySpanExt;
use tracing_subscriber::layer::SubscriberExt;
use crate::errors::StarskyResult;
const VAR_OPENTELEMETRY_URL: &str = "OPENTELEMETRY_URL";
pub struct Carrier<'a>(&'a HttpRequest);
impl<'a> Carrier<'a> {
pub fn from_actix_request(req: &'a HttpRequest) -> Self {
Self(req)
}
}
impl Extractor for Carrier<'_> {
fn get(&self, key: &str) -> Option<&str> {
use std::str::FromStr;
self.0
.headers()
.get(HeaderName::from_str(key).expect("Must be header name"))
.map(|header_value| header_value.to_str().expect("invalid header value"))
}
fn keys(&self) -> Vec<&str> {
self.0
.headers()
.iter()
.map(|(header_name, _)| header_name.as_str())
.collect()
}
}
pub struct Tracing;
impl Tracing {
pub fn initialize() -> StarskyResult<Uninstall> {
let collector_url = std::env::var(VAR_OPENTELEMETRY_URL)?;
let env = std::env::var("APP_ENV")
.ok()
.unwrap_or_else(|| "dev".to_owned());
info!(
"initializing tracing with collector located at {}",
collector_url
);
let (tracer, uninstall) = opentelemetry_jaeger::new_pipeline()
.with_collector_endpoint(collector_url)
.with_service_name("Starsky")
.with_tags(vec![Key::new("environment").string(env)])
.with_trace_config(sdk::trace::Config {
default_sampler: Box::new(sdk::trace::Sampler::AlwaysOn),
..Default::default()
})
.install()
.expect("failed to install opentelemetry_jaeger exporter pipeline");
let telemetry = tracing_opentelemetry::layer().with_tracer(tracer);
let subscriber = tracing_subscriber::Registry::default().with(telemetry);
tracing::subscriber::set_global_default(subscriber)
.expect("setting default subscriber failed");
Ok(uninstall)
}
pub fn set_parent_context(carrier: &Carrier) {
let propagator = TraceContextPropagator::new();
let parent_context = propagator.extract(carrier);
Span::current().set_parent(&parent_context);
}
}
// this works with these dependencies
// tracing = { version = "0.1.21", features = ["max_level_debug", "release_max_level_info"] }
// tracing-subscriber = "0.2"
// tracing-opentelemetry = "0.8.0"
// tracing-futures = "0.2.4"
// opentelemetry = "0.8.0"
// opentelemetry-jaeger = { version = "0.7.0", features = ["collector_client"] }
use actix_web::http::HeaderName;
use actix_web::HttpRequest;
use log::info;
use opentelemetry::{
api::{
context::propagation::text_propagator::HttpTextFormat, trace::provider::Provider,
Extractor, Key, TraceContextPropagator,
},
sdk,
};
use tracing::Span;
use tracing_opentelemetry::OpenTelemetrySpanExt;
use tracing_subscriber::layer::SubscriberExt;
use crate::errors::StarskyResult;
const VAR_OPENTELEMETRY_URL: &str = "OPENTELEMETRY_URL";
pub struct Carrier<'a>(&'a HttpRequest);
impl<'a> Carrier<'a> {
pub fn from_actix_request(req: &'a HttpRequest) -> Self {
Self(req)
}
}
impl Extractor for Carrier<'_> {
fn get(&self, key: &str) -> Option<&str> {
use std::str::FromStr;
self.0
.headers()
.get(HeaderName::from_str(key).expect("Must be header name"))
.map(|header_value| header_value.to_str().expect("invalid header value"))
}
}
pub struct Tracing;
impl Tracing {
pub fn initialize() -> StarskyResult<()> {
let collector_url = std::env::var(VAR_OPENTELEMETRY_URL)?;
Self::do_initialize(collector_url)?;
Ok(())
}
pub fn set_parent_context(carrier: &Carrier) {
let propagator = TraceContextPropagator::new();
let parent_context = propagator.extract(carrier);
Span::current().set_parent(&parent_context);
}
fn do_initialize(collector_url: String) -> StarskyResult<()> {
let env = std::env::var("APP_ENV")
.ok()
.unwrap_or_else(|| "dev".to_owned());
info!(
"initializing tracing with collector located at {}",
collector_url
);
let exporter = opentelemetry_jaeger::Exporter::builder()
.with_collector_endpoint(collector_url)
.with_process(opentelemetry_jaeger::Process {
service_name: "Starsky".to_owned(),
tags: vec![Key::new("environment").string(env)],
})
.init()
.unwrap();
let provider = sdk::Provider::builder()
.with_simple_exporter(exporter)
.with_config(sdk::Config {
default_sampler: Box::new(sdk::Sampler::AlwaysOn),
..Default::default()
})
.build();
let tracer = provider.get_tracer("starsky");
let telemetry = tracing_opentelemetry::layer().with_tracer(tracer);
let subscriber = tracing_subscriber::Registry::default().with(telemetry);
tracing::subscriber::set_global_default(subscriber)
.expect("setting default subscriber failed");
Ok(())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment