Skip to content

Commit

Permalink
Add new layer to add env vars to span attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverbrowneprima committed Apr 24, 2024
1 parent f07d68f commit 3c443dd
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repository = "https://github.com/primait/prima_tracing.rs"
version = "0.9.1"

[features]
default = []
default = ["live", "dev"]
# Legacy feature names kept for compatibility reasons
prima-logger-datadog = ["datadog"]
prima-logger-json = ["json-logger"]
Expand Down
52 changes: 52 additions & 0 deletions src/layer/kube_env.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use opentelemetry::KeyValue;
use tracing::{span, Subscriber};
use tracing_opentelemetry::OtelData;
use tracing_subscriber::{layer::Context, Layer};

// Extracts KUBE_APP_PART_OF, KUBE_APP_MANAGED_BY, KUBE_APP_VERSION and KUBE_APP_INSTANCE from the environment
// and adds them to span attributes
pub struct KubeEnvLayer {
pub kube_app_part_of: Option<String>,
pub kube_app_managed_by: Option<String>,
pub kube_app_version: Option<String>,
pub kube_app_instance: Option<String>,
}

impl Default for KubeEnvLayer {
fn default() -> Self {
Self {
kube_app_part_of: std::env::var("KUBE_APP_PART_OF").ok(),
kube_app_managed_by: std::env::var("KUBE_APP_MANAGED_BY").ok(),
kube_app_version: std::env::var("KUBE_APP_VERSION").ok(),
kube_app_instance: std::env::var("KUBE_APP_INSTANCE").ok(),
}
}
}

impl<S> Layer<S> for KubeEnvLayer
where
S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>,
{
fn on_new_span(&self, _attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) {
let span = ctx.span(id).expect("Span not found, this is a bug");
let mut extensions = span.extensions_mut();

if let Some(otel_data) = extensions.get_mut::<OtelData>() {
let builder = &mut otel_data.builder;
if let Some(ref mut attributes) = builder.attributes {
if let Some(ref part_of) = self.kube_app_part_of {
attributes.push(KeyValue::new("kube_app_part_of", part_of.clone()));
}
if let Some(ref managed_by) = self.kube_app_managed_by {
attributes.push(KeyValue::new("kube_app_managed_by", managed_by.clone()));
}
if let Some(ref version) = self.kube_app_version {
attributes.push(KeyValue::new("kube_app_version", version.clone()));
}
if let Some(ref instance) = self.kube_app_instance {
attributes.push(KeyValue::new("kube_app_instance", instance.clone()));
}
}
}
}
}
2 changes: 2 additions & 0 deletions src/layer/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
pub use error::ErrorLayer;
pub use kube_env::KubeEnvLayer;
pub use version::VersionLayer;

mod error;
mod kube_env;
mod version;
4 changes: 3 additions & 1 deletion src/subscriber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub fn configure_subscriber<T: EventFormatter + Send + Sync + 'static>(
version: _config.version.clone(),
})
.with(crate::layer::ErrorLayer)
.with(crate::layer::KubeEnvLayer::default())
};

#[cfg(not(feature = "json-logger"))]
Expand All @@ -40,7 +41,8 @@ pub fn configure_subscriber<T: EventFormatter + Send + Sync + 'static>(
use crate::json::formatter::PrimaFormattingLayer;
use crate::json::storage::PrimaJsonStorage;
subscriber
.with(PrimaJsonStorage)
.with(PrimaJsonStorage::default())
.with(crate::layer::KubeEnvLayer::default())
.with(PrimaFormattingLayer::new(
_config.service.clone(),
_config.country.to_string(),
Expand Down

0 comments on commit 3c443dd

Please sign in to comment.