Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
02fb657
create RC ConfigItem and wrap SamplingRules config
ZStriker19 Aug 4, 2025
c8d359f
sampling rules can be updated, made callback to do so
ZStriker19 Aug 4, 2025
142b521
handle extra services and rc enablement in configuration.rs
ZStriker19 Aug 7, 2025
7942f5e
remote_config work stopping point before full rfc
ZStriker19 Aug 8, 2025
0c7b9cd
right before switch to coupling config and rc
ZStriker19 Aug 10, 2025
5ebbf83
pass config into remoteconfig
ZStriker19 Aug 11, 2025
7503a0c
clarify passing of sampling rules json through updates
ZStriker19 Aug 11, 2025
48b74bb
streamline data for callback and converting json to rules
ZStriker19 Aug 11, 2025
bef6fa2
fallback only with empty incoming rc array
ZStriker19 Aug 11, 2025
138452c
add extra services in span processor
ZStriker19 Aug 11, 2025
13b8f2a
remove unused methods, add more tests for rc, remove example
ZStriker19 Aug 12, 2025
126febf
only log debug,lint
ZStriker19 Aug 12, 2025
fccd491
Merge branch 'main' into zachg/rc_sampling
ZStriker19 Aug 12, 2025
e99ed33
create general type for callbacks for extensibility
ZStriker19 Aug 12, 2025
09324f3
update random examples so tests pass
ZStriker19 Aug 12, 2025
bd3370c
fix licensing
ZStriker19 Aug 12, 2025
ea68246
Update LICENSE-3rdparty.csv and fix openssl-macros license tool confi…
ZStriker19 Aug 12, 2025
bb4f06a
make parsing of rc more extensible for future products
ZStriker19 Aug 12, 2025
f4b3388
remove uneeded api change
ZStriker19 Aug 12, 2025
3bbd416
touch ups
ZStriker19 Aug 12, 2025
ef49d83
only pass shared config when needed
ZStriker19 Aug 13, 2025
4abec47
lazy init rc http client creation to avoid panic
ZStriker19 Aug 13, 2025
9d9ba80
increase timeout by 1 second to avoid occasional connection failures
ZStriker19 Aug 14, 2025
c532722
testing equipment
ZStriker19 Aug 14, 2025
65f0510
Revert "increase timeout by 1 second to avoid occasional connection f…
ZStriker19 Aug 14, 2025
7dd1fcd
increase timeout by 1 second to avoid occasional connection failures
ZStriker19 Aug 14, 2025
745baa8
hold callbacks in struct instead of hashmap
ZStriker19 Aug 14, 2025
be6b057
switch rc client from reqwest to hyper
ZStriker19 Aug 14, 2025
5006fa0
Merge branch 'zachg/rc_sampling' into zachg/rc_testing
ZStriker19 Aug 14, 2025
d39950d
add cargo toml for testing app
ZStriker19 Aug 14, 2025
ab6a179
fix agent site
ZStriker19 Aug 14, 2025
96cee57
move updating service tracker to span exporter
ZStriker19 Aug 14, 2025
0c1000f
Merge branch 'main' into zachg/rc_sampling
ZStriker19 Aug 15, 2025
4d78e93
Merge branch 'main' into zachg/rc_sampling
ZStriker19 Aug 15, 2025
b2ff4c7
Update dd-trace/src/configuration/remote_config.rs
ZStriker19 Aug 19, 2025
e34f89e
Update dd-trace/Cargo.toml
ZStriker19 Aug 19, 2025
45af6de
fix method combining
ZStriker19 Aug 19, 2025
31bc417
Merge branch 'zachg/rc_sampling' into zachg/rc_testing
ZStriker19 Aug 27, 2025
f921392
merge main
ZStriker19 Aug 27, 2025
d794507
fix(test): add defaults to the test run script
bantonsson Aug 28, 2025
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
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ members = [
"datadog-opentelemetry",
"datadog-opentelemetry/examples/propagator",
"datadog-opentelemetry/examples/simple_tracing",
"datadog-opentelemetry/examples/remote_config_test",
"datadog-opentelemetry-mappings",
"dd-trace",
"dd-trace-propagation",
Expand Down
51 changes: 42 additions & 9 deletions datadog-opentelemetry/examples/README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,55 @@
# Examples

## simple_tracing
This directory contains example applications demonstrating various features of the `datadog-opentelemetry` crate.

Demonstrates basic usage of Datadog OpenTelemetry tracing. Creates nested spans and demonstrates tracer initialization and shutdown.
## Available Examples

### simple_tracing
A basic example showing how to initialize the Datadog tracer and create spans.

**Run:**
```bash
cargo run -p simple_tracing
```

## propagator

HTTP server that demonstrates trace context propagation between services. Shows how to extract trace context from incoming requests and inject it into outgoing requests.
### propagator
An example demonstrating trace propagation between services.

**Run:**
```bash
cargo run -p propagator
```

The server runs on `http://localhost:3000` with endpoints:
- `/health` - Health check endpoint
- `/echo` - Echo request body
- `/jump` - Makes outbound request to port 3001
### remote_config_test
A test application for manually testing the remote configuration feature for sampling rules. This application continuously emits spans under a specific service name (`dd-trace-rs-rc-test-service`) to test remote configuration updates from the Datadog backend.

**Features:**
- Initializes tracer with remote configuration enabled
- Emits ~2 traces per second with realistic span structures
- Creates different operation types: `user_login`, `data_fetch`, `file_upload`, `analytics_event`
- Each trace has a parent span with 2 child spans (`database_query` and `external_api_call`)

**Run:**
```bash
# From project root
cargo run -p remote_config_test

# Or use the convenience script
./run_remote_config_test.sh

# With debug logging to see remote config activity
DD_LOG_LEVEL=DEBUG cargo run -p remote_config_test
```

**Prerequisites:**
- Datadog Agent running on `localhost:8126`
- Agent must have remote configuration enabled
- Agent should be configured to receive remote config from Datadog backend

**Testing Remote Configuration:**
1. Start the application
2. Verify spans are being sent to your APM dashboard
3. Create a sampling rule in your Datadog backend for service `dd-trace-rs-rc-test-service`
4. Monitor the application and APM dashboard to see sampling rate changes

See the [remote_config_test README](remote_config_test/README.md) for detailed instructions.
14 changes: 14 additions & 0 deletions datadog-opentelemetry/examples/remote_config_test/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "remote_config_test"
version = "0.1.0"
edition = "2021"

[[bin]]
name = "remote_config_test"
path = "src/main.rs"

[dependencies]
datadog-opentelemetry = { path = "../.." }
dd-trace = { path = "../../../dd-trace" }
opentelemetry = { workspace = true }
tokio = { workspace = true, features = ["full", "signal"] }
97 changes: 97 additions & 0 deletions datadog-opentelemetry/examples/remote_config_test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Remote Configuration Test Application

This is a test application for manually testing the remote configuration feature for sampling rules in `dd-trace-rs`. It continuously emits spans under a specific service name so you can test remote configuration updates from the Datadog backend.

## What it does

- Initializes the Datadog tracer with remote configuration enabled
- Continuously emits spans under the service name `dd-trace-rs-rc-test-service`
- Creates realistic traces with multiple spans (parent + 2 child spans)
- Simulates different operation types: `user_login`, `data_fetch`, `file_upload`, `analytics_event`
- Emits approximately 2 traces per second
- Logs progress every 10 traces

## Prerequisites

1. **Datadog Agent**: You need a Datadog Agent running on `localhost:8126` that is configured to receive remote configuration updates from the Datadog backend.

2. **Agent Configuration**: Your agent should have remote configuration enabled. Check your agent's configuration for:
```yaml
remote_configuration:
enabled: true
```

## How to run

### Option 1: From the project root
```bash
# Build and run the test application
cargo run --bin remote_config_test -p remote_config_test
```

### Option 2: From the example directory
```bash
cd datadog-opentelemetry/examples/remote_config_test
cargo run
```

## Environment Variables

You can customize the behavior using these environment variables:

- `DD_TRACE_AGENT_URL`: Agent URL (default: `http://localhost:8126`)
- `DD_LOG_LEVEL`: Log level for Datadog tracing (default: `INFO`)
- `DD_REMOTE_CONFIGURATION_ENABLED`: Enable/disable remote config (default: `true`)

Example with custom agent URL:
```bash
DD_TRACE_AGENT_URL=http://localhost:8126 cargo run
```

## Testing Remote Configuration

1. **Start the application**: Run the test application using one of the methods above.

2. **Verify spans are being sent**: Check your Datadog APM dashboard to confirm spans from `dd-trace-rs-rc-test-service` are being received.

3. **Create a sampling rule**: In your Datadog backend, create a sampling rule for the service:
- Service: `dd-trace-rs-rc-test-service`
- Sample rate: Choose a rate (e.g., 0.1 for 10% sampling)

4. **Monitor for changes**: Watch the application logs and your APM dashboard to see if the sampling rate changes when the remote configuration is applied.

## Expected Behavior

- **Initial**: The application should emit spans at whatever the default sampling rate is
- **After remote config update**: The sampling rate should change according to your remote configuration rule
- **Remote config polling**: The client polls for configuration updates every 5 seconds (as per the spec)

## Debugging

### Increase logging verbosity
```bash
DD_LOG_LEVEL=DEBUG cargo run
```

### Check agent connectivity
Make sure your agent is accessible:
```bash
curl http://localhost:8126/v0.7/config
```

### Check spans are reaching the agent
```bash
curl http://localhost:8126/info
```

## What to look for

When remote configuration is working correctly, you should see:

1. **In application logs**: Periodic remote config client activity
2. **In agent logs**: Remote configuration requests and responses
3. **In APM dashboard**: Changes in sampling rate for the `dd-trace-rs-rc-test-service`

## Stopping the application

Press `Ctrl+C` to gracefully stop the application. It will flush any remaining spans before shutting down.
111 changes: 111 additions & 0 deletions datadog-opentelemetry/examples/remote_config_test/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/
// SPDX-License-Identifier: Apache-2.0

use opentelemetry::trace::{Tracer, TraceContextExt};
use opentelemetry::Context;
use std::time::Duration;
use tokio::time::sleep;

const SERVICE_NAME: &str = "dd-trace-rs-rc-test-service";

async fn process_request(request_id: u64, request_type: &str) {
// Create the main span for this request
let tracer = opentelemetry::global::tracer("request-processor");
let main_span = tracer.start(format!("process_{}", request_type));
let cx = Context::current_with_span(main_span);

// Database query - create span, do work, end span
{
let db_span = tracer.start_with_context("database_query", &cx);
let _db_cx = cx.with_span(db_span);
sleep(Duration::from_millis(20 + (request_id % 30))).await;
} // span ends here

// External API call - create span, do work, end span
{
let api_span = tracer.start_with_context("external_api_call", &cx);
let _api_cx = cx.with_span(api_span);
sleep(Duration::from_millis(30 + (request_id % 40))).await;
} // span ends here
} // main span ends here

async fn background_worker() {
let mut counter = 0u64;
loop {
counter += 1;

// Simulate different types of requests
let request_type = match counter % 4 {
0 => "user_login",
1 => "data_fetch",
2 => "file_upload",
_ => "analytics_event",
};

process_request(counter, request_type).await;

// Sleep between requests - emit roughly 2 spans per second
sleep(Duration::from_millis(500)).await;

// Log every 10 requests to show we're still running
if counter % 10 == 0 {
println!("Emitted {} traces so far", counter);
}
}
}

#[tokio::main]
async fn main() {
println!("Starting remote config test application");
println!("Service name: {}", SERVICE_NAME);
println!("Agent URL: {}", std::env::var("DD_TRACE_AGENT_URL").unwrap_or_else(|_| "http://localhost:8126".to_string()));

// Initialize the Datadog tracer with remote config enabled
let config = dd_trace::Config::builder()
.set_service(SERVICE_NAME.to_string())
.set_env("dd-trace-rs-test-env".to_string())
.set_version("1.0.0".to_string())
// Remote config is enabled by default, but let's be explicit
.build();

// Enable debug logging to see remote config activity
if std::env::var("DD_LOG_LEVEL").unwrap_or_default().to_lowercase() == "debug" {
// Note: set_max_level is not public, but the config will handle log level internally
eprintln!("Debug logging enabled");
}

// Verify configuration values
println!("Config - Service: {}", config.service());
println!("Config - Environment: {:?}", config.env());
println!("Config - Version: {:?}", config.version());

let tracer_provider = datadog_opentelemetry::tracing()
.with_config(config)
.init();

println!("Tracer initialized with remote config enabled");
println!("Starting to emit spans continuously...");
println!("You can now create sampling rules in the Datadog backend for service: {}", SERVICE_NAME);
println!("Press Ctrl+C to stop");

// Run the background worker that emits spans
let worker_handle = tokio::spawn(background_worker());

// Wait for Ctrl+C
tokio::select! {
_ = tokio::signal::ctrl_c() => {
println!("Received Ctrl+C, shutting down...");
}
_ = worker_handle => {
println!("Worker finished unexpectedly");
}
}

// Shutdown the tracer to flush remaining spans
println!("Shutting down tracer...");
if let Err(e) = tracer_provider.shutdown_with_timeout(Duration::from_secs(5)) {
eprintln!("Error shutting down tracer: {}", e);
}

println!("Application stopped");
}
Loading
Loading