> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/open-telemetry/opentelemetry-rust/llms.txt
> Use this file to discover all available pages before exploring further.

# Resource detection

> Automatically detect and configure resources that describe your telemetry-producing entity

## Overview

A [Resource](https://opentelemetry.io/docs/specs/otel/resource/sdk/) represents the entity producing telemetry data. Resources are immutable and contain attributes that describe your application, service, host, and environment.

## Resource attributes

Common resource attributes include:

* `service.name` - Your service name
* `service.version` - Application version
* `service.instance.id` - Unique instance identifier
* `host.name` - Hostname
* `process.pid` - Process ID
* `deployment.environment` - Environment (dev, staging, prod)

## Resource builders

OpenTelemetry Rust provides two ways to create resources:

### Default builder

Includes built-in detectors:

```rust theme={null}
use opentelemetry_sdk::Resource;

let resource = Resource::builder()
    .with_service_name("my-service")
    .build();
```

The default builder includes:

* `SdkProvidedResourceDetector` - SDK name and version
* `TelemetryResourceDetector` - Telemetry SDK information
* `EnvResourceDetector` - Environment variables

### Empty builder

Start with no attributes:

```rust theme={null}
use opentelemetry_sdk::Resource;
use opentelemetry::KeyValue;

let resource = Resource::builder_empty()
    .with_attributes(vec![
        KeyValue::new("service.name", "my-service"),
        KeyValue::new("service.version", "1.0.0"),
    ])
    .build();
```

## Built-in resource detectors

### SdkProvidedResourceDetector

Provides OpenTelemetry SDK information:

```rust theme={null}
use opentelemetry_sdk::resource::SdkProvidedResourceDetector;

let detector = SdkProvidedResourceDetector;
let resource = detector.detect();

// Attributes detected:
// - telemetry.sdk.name = "opentelemetry"
// - telemetry.sdk.language = "rust"
// - telemetry.sdk.version = "0.31.0"
```

### TelemetryResourceDetector

Provides telemetry SDK-specific information:

```rust theme={null}
use opentelemetry_sdk::resource::TelemetryResourceDetector;

let detector = TelemetryResourceDetector;
let resource = detector.detect();
```

### EnvResourceDetector

Detects resources from environment variables:

```rust theme={null}
use opentelemetry_sdk::resource::EnvResourceDetector;

let detector = EnvResourceDetector::new();
let resource = detector.detect();
```

**Environment variables:**

* `OTEL_RESOURCE_ATTRIBUTES` - Key-value pairs: `key1=value1,key2=value2`
* `OTEL_SERVICE_NAME` - Service name (overrides `service.name` in attributes)

**Example:**

```bash theme={null}
export OTEL_SERVICE_NAME=my-service
export OTEL_RESOURCE_ATTRIBUTES="service.version=1.0.0,deployment.environment=production"
```

## Service name priority

Service name is resolved in this order (highest to lowest priority):

1. `OTEL_SERVICE_NAME` environment variable
2. `service.name` in `OTEL_RESOURCE_ATTRIBUTES`
3. `with_service_name()` builder method
4. `service.name` in custom attributes
5. Default: `"unknown_service"`

```rust theme={null}
use opentelemetry_sdk::Resource;

// Priority 3: Builder method
let resource = Resource::builder()
    .with_service_name("my-service")
    .build();

// Priority 1: Environment variable (overrides builder)
// export OTEL_SERVICE_NAME=production-service
```

## Custom resource detectors

Implement the `ResourceDetector` trait:

```rust theme={null}
use opentelemetry_sdk::resource::ResourceDetector;
use opentelemetry::KeyValue;

struct CustomDetector;

impl ResourceDetector for CustomDetector {
    fn detect(&self) -> Vec<KeyValue> {
        vec![
            KeyValue::new("custom.attribute", "value"),
            KeyValue::new("build.id", env!("BUILD_ID")),
        ]
    }
}
```

Use custom detector:

```rust theme={null}
let resource = Resource::builder_empty()
    .with_detector(Box::new(CustomDetector))
    .build();
```

## Merging resources

Merge multiple resources together:

```rust theme={null}
use opentelemetry_sdk::Resource;
use opentelemetry::KeyValue;

let base_resource = Resource::builder()
    .with_service_name("my-service")
    .build();

let custom_resource = Resource::builder_empty()
    .with_attributes(vec![
        KeyValue::new("deployment.environment", "production"),
        KeyValue::new("service.version", "2.0.0"),
    ])
    .build();

// Merge resources (custom_resource takes precedence)
let merged = base_resource.merge(&custom_resource);
```

## Schema URLs

Resources can include a [schema URL](https://opentelemetry.io/docs/specs/otel/schemas/) that identifies the semantic convention version:

```rust theme={null}
use opentelemetry_sdk::Resource;
use opentelemetry::KeyValue;

let resource = Resource::builder_empty()
    .with_schema_url("https://opentelemetry.io/schemas/1.21.0")
    .with_attributes(vec![
        KeyValue::new("service.name", "my-service"),
    ])
    .build();
```

<Warning>
  When merging resources with different schema URLs, the operation may fail if the schemas are incompatible.
</Warning>

## Using resources with providers

### TracerProvider

```rust theme={null}
use opentelemetry_sdk::{
    trace::TracerProvider,
    Resource,
};

let resource = Resource::builder()
    .with_service_name("my-trace-service")
    .build();

let provider = TracerProvider::builder()
    .with_resource(resource)
    .build();
```

### MeterProvider

```rust theme={null}
use opentelemetry_sdk::{
    metrics::MeterProvider,
    Resource,
};

let resource = Resource::builder()
    .with_service_name("my-metrics-service")
    .build();

let provider = MeterProvider::builder()
    .with_resource(resource)
    .build();
```

### LoggerProvider

```rust theme={null}
use opentelemetry_sdk::{
    logs::LoggerProvider,
    Resource,
};

let resource = Resource::builder()
    .with_service_name("my-logging-service")
    .build();

let provider = LoggerProvider::builder()
    .with_resource(resource)
    .build();
```

## Complete example

```rust theme={null}
use opentelemetry::KeyValue;
use opentelemetry_sdk::{
    trace::{TracerProvider, BatchSpanProcessor},
    Resource,
};
use opentelemetry_otlp::SpanExporter;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create custom resource
    let resource = Resource::builder()
        .with_service_name(env!("CARGO_PKG_NAME"))
        .with_attributes(vec![
            KeyValue::new("service.version", env!("CARGO_PKG_VERSION")),
            KeyValue::new("deployment.environment", "production"),
            KeyValue::new("service.instance.id", uuid::Uuid::new_v4().to_string()),
        ])
        .build();
    
    // Use resource in provider
    let exporter = SpanExporter::builder().with_http().build()?;
    let processor = BatchSpanProcessor::builder(exporter, opentelemetry_sdk::runtime::Tokio).build();
    
    let provider = TracerProvider::builder()
        .with_resource(resource)
        .with_span_processor(processor)
        .build();
    
    Ok(())
}
```

## OS and Process detectors

For more advanced resource detection (OS, process, host info), use the separate `opentelemetry-resource-detectors` crate:

```toml theme={null}
[dependencies]
opentelemetry-resource-detectors = "0.1"
```

```rust theme={null}
use opentelemetry_resource_detectors::{OsResourceDetector, ProcessResourceDetector};
use opentelemetry_sdk::Resource;

let resource = Resource::builder()
    .with_detector(Box::new(OsResourceDetector))
    .with_detector(Box::new(ProcessResourceDetector))
    .build();
```

This provides:

* `host.name`
* `host.arch`
* `os.type`
* `os.description`
* `process.pid`
* `process.executable.name`
* `process.command_line`
* `process.runtime.name`
* `process.runtime.version`

## Best practices

<Tip>
  **Always set service.name** - This is the most important resource attribute for identifying your service in observability backends.
</Tip>

<Note>
  **Use semantic conventions** - Follow [OpenTelemetry semantic conventions](https://opentelemetry.io/docs/specs/semconv/) for standard attribute names.
</Note>

<Info>
  **Environment-based configuration** - Use `OTEL_SERVICE_NAME` and `OTEL_RESOURCE_ATTRIBUTES` environment variables for deployment-specific configuration.
</Info>

## Related

<CardGroup cols={2}>
  <Card title="Resources concept" icon="microchip" href="/concepts/resources">
    Learn about resource fundamentals
  </Card>

  <Card title="Semantic conventions" icon="book" href="/api/opentelemetry-semantic-conventions">
    Standard attribute names
  </Card>
</CardGroup>
