Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions opentelemetry-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## vNext

- Fix `service.name` Resource attribute fallback to follow OpenTelemetry
specification by using `unknown_service:<process.executable.name>` format when
service name is not explicitly configured. Previously, it only used
`unknown_service`.
- Fix `SpanExporter::shutdown()` default timeout from 5 nanoseconds to 5 seconds.
- **Breaking** `SpanExporter` trait methods `shutdown`, `shutdown_with_timeout`, and `force_flush` now take `&self` instead of `&mut self` for consistency with `LogExporter` and `PushMetricExporter`. Implementers using interior mutability (e.g., `Mutex`, `AtomicBool`) require no changes.
- Added `Resource::get_ref(&self, key: &Key) -> Option<&Value>` to allow retrieving a reference to a resource value without cloning.
Expand Down
42 changes: 27 additions & 15 deletions opentelemetry-sdk/src/logs/logger_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,11 +477,15 @@ mod tests {
let _ = super::SdkLoggerProvider::builder()
.with_log_processor(processor_with_resource.clone())
.build();
assert_resource(
&processor_with_resource,
&exporter_with_resource,
SERVICE_NAME,
Some("unknown_service"),
let service_name = processor_with_resource
.resource()
.get(&Key::from_static_str(SERVICE_NAME))
.map(|v| v.to_string())
.unwrap();
assert!(
service_name.starts_with("unknown_service:opentelemetry_sdk-"),
"Expected service name to start with 'unknown_service:opentelemetry_sdk-', got: {}",
service_name
);
assert_telemetry_resource(&processor_with_resource, &exporter_with_resource);
});
Expand Down Expand Up @@ -516,11 +520,15 @@ mod tests {
let _ = super::SdkLoggerProvider::builder()
.with_log_processor(processor_with_resource.clone())
.build();
assert_resource(
&processor_with_resource,
&exporter_with_resource,
SERVICE_NAME,
Some("unknown_service"),
let service_name = processor_with_resource
.resource()
.get(&Key::from_static_str(SERVICE_NAME))
.map(|v| v.to_string())
.unwrap();
assert!(
service_name.starts_with("unknown_service:opentelemetry_sdk-"),
"Expected service name to start with 'unknown_service:opentelemetry_sdk-', got: {}",
service_name
);
assert_resource(
&processor_with_resource,
Expand Down Expand Up @@ -558,11 +566,15 @@ mod tests {
)
.with_log_processor(processor_with_resource.clone())
.build();
assert_resource(
&processor_with_resource,
&exporter_with_resource,
SERVICE_NAME,
Some("unknown_service"),
let service_name = processor_with_resource
.resource()
.get(&Key::from_static_str(SERVICE_NAME))
.map(|v| v.to_string())
.unwrap();
assert!(
service_name.starts_with("unknown_service:opentelemetry_sdk-"),
"Expected service name to start with 'unknown_service:opentelemetry_sdk-', got: {}",
service_name
);
assert_resource(
&processor_with_resource,
Expand Down
39 changes: 27 additions & 12 deletions opentelemetry-sdk/src/metrics/meter_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -461,10 +461,15 @@ mod tests {
let default_meter_provider = super::SdkMeterProvider::builder()
.with_reader(reader)
.build();
assert_resource(
&default_meter_provider,
SERVICE_NAME,
Some("unknown_service"),
let service_name = default_meter_provider.inner.pipes.0[0]
.resource
.get(&Key::from_static_str(SERVICE_NAME))
.map(|v| v.to_string())
.unwrap();
assert!(
service_name.starts_with("unknown_service:opentelemetry_sdk-"),
"Expected service name to start with 'unknown_service:opentelemetry_sdk-', got: {}",
service_name
);
assert_telemetry_resource(&default_meter_provider);
});
Expand All @@ -491,10 +496,15 @@ mod tests {
let env_resource_provider = super::SdkMeterProvider::builder()
.with_reader(reader3)
.build();
assert_resource(
&env_resource_provider,
SERVICE_NAME,
Some("unknown_service"),
let service_name = env_resource_provider.inner.pipes.0[0]
.resource
.get(&Key::from_static_str(SERVICE_NAME))
.map(|v| v.to_string())
.unwrap();
assert!(
service_name.starts_with("unknown_service:opentelemetry_sdk-"),
"Expected service name to start with 'unknown_service:opentelemetry_sdk-', got: {}",
service_name
);
assert_resource(&env_resource_provider, "key1", Some("value1"));
assert_resource(&env_resource_provider, "k3", Some("value2"));
Expand All @@ -520,10 +530,15 @@ mod tests {
.build(),
)
.build();
assert_resource(
&user_provided_resource_config_provider,
SERVICE_NAME,
Some("unknown_service"),
let service_name = user_provided_resource_config_provider.inner.pipes.0[0]
.resource
.get(&Key::from_static_str(SERVICE_NAME))
.map(|v| v.to_string())
.unwrap();
assert!(
service_name.starts_with("unknown_service:opentelemetry_sdk-"),
"Expected service name to start with 'unknown_service:opentelemetry_sdk-', got: {}",
service_name
);
assert_resource(
&user_provided_resource_config_provider,
Expand Down
29 changes: 24 additions & 5 deletions opentelemetry-sdk/src/resource/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,19 @@ impl ResourceDetector for SdkProvidedResourceDetector {
.detect()
.get(&Key::new(super::SERVICE_NAME))
})
.unwrap_or_else(|| "unknown_service".into()),
.unwrap_or_else(|| {
// Fallback to unknown_service:<process.executable.name> per spec
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/resource/sdk.md#sdk-provided-resource-attributes
env::current_exe()
.ok()
.and_then(|path| {
path.file_name()
.and_then(|name| name.to_str())
.map(|name| format!("unknown_service:{}", name))
})
.unwrap_or_else(|| "unknown_service".to_string())
.into()
}),
)])
.build()
}
Expand Down Expand Up @@ -135,11 +147,18 @@ mod tests {

#[test]
fn test_sdk_provided_resource_detector() {
// Ensure no env var set
// Ensure no env var set - should fallback to unknown_service:<executable_name>
// For cargo tests, the executable name is typically <crate_name>-<hash>
let no_env = SdkProvidedResourceDetector.detect();
assert_eq!(
no_env.get(&Key::from_static_str(crate::resource::SERVICE_NAME)),
Some(Value::from("unknown_service")),
let service_name = no_env
.get(&Key::from_static_str(crate::resource::SERVICE_NAME))
.map(|v| v.to_string())
.unwrap();

assert!(
service_name.starts_with("unknown_service:opentelemetry_sdk-"),
"Expected service name to start with 'unknown_service:opentelemetry_sdk-', got: {}",
service_name
);

temp_env::with_var(OTEL_SERVICE_NAME, Some("test service"), || {
Expand Down
42 changes: 30 additions & 12 deletions opentelemetry-sdk/src/trace/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,10 +606,16 @@ mod tests {
// If users didn't provide a resource and there isn't a env var set. Use default one.
temp_env::with_var_unset("OTEL_RESOURCE_ATTRIBUTES", || {
let default_config_provider = super::SdkTracerProvider::builder().build();
assert_resource(
&default_config_provider,
SERVICE_NAME,
Some("unknown_service"),
let service_name = default_config_provider
.config()
.resource
.get(&Key::from_static_str(SERVICE_NAME))
.map(|v| v.to_string())
.unwrap();
assert!(
service_name.starts_with("unknown_service:opentelemetry_sdk-"),
"Expected service name to start with 'unknown_service:opentelemetry_sdk-', got: {}",
service_name
);
assert_telemetry_resource(&default_config_provider);
});
Expand All @@ -631,10 +637,16 @@ mod tests {
Some("key1=value1, k2, k3=value2"),
|| {
let env_resource_provider = super::SdkTracerProvider::builder().build();
assert_resource(
&env_resource_provider,
SERVICE_NAME,
Some("unknown_service"),
let service_name = env_resource_provider
.config()
.resource
.get(&Key::from_static_str(SERVICE_NAME))
.map(|v| v.to_string())
.unwrap();
assert!(
service_name.starts_with("unknown_service:opentelemetry_sdk-"),
"Expected service name to start with 'unknown_service:opentelemetry_sdk-', got: {}",
service_name
);
assert_resource(&env_resource_provider, "key1", Some("value1"));
assert_resource(&env_resource_provider, "k3", Some("value2"));
Expand All @@ -658,10 +670,16 @@ mod tests {
.build(),
)
.build();
assert_resource(
&user_provided_resource_config_provider,
SERVICE_NAME,
Some("unknown_service"),
let service_name = user_provided_resource_config_provider
.config()
.resource
.get(&Key::from_static_str(SERVICE_NAME))
.map(|v| v.to_string())
.unwrap();
assert!(
service_name.starts_with("unknown_service:opentelemetry_sdk-"),
"Expected service name to start with 'unknown_service:opentelemetry_sdk-', got: {}",
service_name
);
assert_resource(
&user_provided_resource_config_provider,
Expand Down