diff --git a/.docker/observability/prometheus.yml b/.docker/observability/prometheus.yml index 1039e2972..4ac483e6e 100644 --- a/.docker/observability/prometheus.yml +++ b/.docker/observability/prometheus.yml @@ -61,6 +61,7 @@ scrape_configs: otlp: promote_resource_attributes: - service.instance.id + - process.pid - service.name - service.namespace - cloud.availability_zone diff --git a/crates/obs/src/telemetry/resource.rs b/crates/obs/src/telemetry/resource.rs index 37bda8a5f..b5fa67907 100644 --- a/crates/obs/src/telemetry/resource.rs +++ b/crates/obs/src/telemetry/resource.rs @@ -16,9 +16,9 @@ //! //! A `Resource` describes the entity producing telemetry data. The resource //! built here includes the service name, service version, deployment -//! environment, the stable RustFS node identity, and the local machine IP -//! address so that data can be correlated across services in a distributed -//! system. +//! environment, the stable RustFS node identity, the process ID, and the local +//! machine IP address so telemetry series can be correlated across service +//! restarts and nodes. use crate::config::OtelConfig; use crate::node_identity::{RUSTFS_NODE_ATTRIBUTE, local_node_identity}; @@ -27,7 +27,7 @@ use opentelemetry_sdk::Resource; use opentelemetry_semantic_conventions::{ SCHEMA_URL, attribute::{ - DEPLOYMENT_ENVIRONMENT_NAME, NETWORK_LOCAL_ADDRESS, SERVICE_INSTANCE_ID as OTEL_SERVICE_INSTANCE_ID, + DEPLOYMENT_ENVIRONMENT_NAME, NETWORK_LOCAL_ADDRESS, PROCESS_PID, SERVICE_INSTANCE_ID as OTEL_SERVICE_INSTANCE_ID, SERVICE_VERSION as OTEL_SERVICE_VERSION, }, }; @@ -48,6 +48,8 @@ use std::borrow::Cow; /// - `network.local.address` — the primary local IP of the current host, /// useful as an operational fallback when the stable node name is not yet /// initialized. +/// - `process.pid` — distinguishes telemetry emitted by different processes +/// running on the same node. /// /// All attributes are attached to the resource using the semantic conventions /// schema URL to ensure compatibility with standard OTLP backends. @@ -70,6 +72,7 @@ pub(super) fn build_resource(config: &OtelConfig) -> Resource { KeyValue::new(RUSTFS_NODE_ATTRIBUTE, node_identity.clone()), KeyValue::new(OTEL_SERVICE_INSTANCE_ID, node_identity), KeyValue::new(NETWORK_LOCAL_ADDRESS, local_ip), + KeyValue::new(PROCESS_PID, i64::from(std::process::id())), ], SCHEMA_URL, ) @@ -101,6 +104,12 @@ mod tests { .map(|value| value.to_string()), Some("node1:9000".to_string()) ); + assert_eq!( + resource + .get(&Key::from_static_str(PROCESS_PID)) + .map(|value| value.to_string()), + Some(std::process::id().to_string()) + ); rustfs_common::set_global_local_node_name(&previous).await; }