Skip to content
Open
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
2 changes: 2 additions & 0 deletions sdk/core/azure_core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

### Other Changes

- The `url.full` span attribute in distributed traces now has query parameter values sanitized. Only parameters in `LoggingOptions::additional_allowed_query_params` and the default allow list (e.g., `api-version`) retain their values; all others are replaced with `REDACTED`.

## 0.33.0 (2026-03-05)

### Features Added
Expand Down
7 changes: 7 additions & 0 deletions sdk/core/azure_core/src/http/options/instrumentation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@
use std::sync::Arc;

/// Policy options to enable distributed tracing.
///
/// # Notes
///
/// [`LoggingOptions::additional_allowed_query_params`](super::LoggingOptions::additional_allowed_query_params)
/// is used to sanitize query parameters in traced URLs as well.
/// Query parameters not in the default or additional allow list will have their values
/// replaced with `REDACTED` in the `url.full` span attribute.
#[derive(Clone, Debug, Default)]
pub struct InstrumentationOptions {
/// Set the tracer provider for distributed tracing.
Expand Down
12 changes: 10 additions & 2 deletions sdk/core/azure_core/src/http/options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ mod instrumentation;
mod user_agent;

pub use instrumentation::*;
use std::sync::Arc;
use typespec_client_core::http::policies::Policy;
use std::{borrow::Cow, collections::HashSet, sync::Arc};
use typespec_client_core::http::{policies::Policy, DEFAULT_ALLOWED_QUERY_PARAMETERS};
pub use typespec_client_core::http::{
ClientMethodOptions, ExponentialRetryOptions, FixedRetryOptions, LoggingOptions,
PipelineOptions, RetryOptions, Transport,
Expand Down Expand Up @@ -51,6 +51,7 @@ pub struct ClientOptions {
pub(crate) struct CoreClientOptions {
pub(crate) user_agent: UserAgentOptions,
pub(crate) instrumentation: InstrumentationOptions,
pub(crate) allowed_query_params: HashSet<Cow<'static, str>>,
}

impl ClientOptions {
Expand All @@ -60,6 +61,12 @@ impl ClientOptions {
pub(in crate::http) fn deconstruct(
self,
) -> (CoreClientOptions, typespec_client_core::http::ClientOptions) {
// Merge the default allowed query parameters with any additional ones from logging options.
// This merged set is shared by both the logging policy and the request instrumentation policy
// to sanitize query parameters in logs and traced URLs.
let mut allowed_query_params = (*DEFAULT_ALLOWED_QUERY_PARAMETERS).clone();
allowed_query_params.extend(self.logging.additional_allowed_query_params.iter().cloned());

let options = typespec_client_core::http::ClientOptions {
per_call_policies: self.per_call_policies,
per_try_policies: self.per_try_policies,
Expand All @@ -72,6 +79,7 @@ impl ClientOptions {
CoreClientOptions {
user_agent: self.user_agent,
instrumentation: self.instrumentation,
allowed_query_params,
},
options,
)
Expand Down
6 changes: 4 additions & 2 deletions sdk/core/azure_core/src/http/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,10 @@ impl Pipeline {

let mut per_try_policies = per_try_policies.clone();
if let Some(ref tracer) = tracer {
let request_instrumentation_policy =
RequestInstrumentationPolicy::new(Some(tracer.clone()));
let request_instrumentation_policy = RequestInstrumentationPolicy::new(
Some(tracer.clone()),
core_client_options.allowed_query_params.clone(),
);
push_unique(&mut per_try_policies, request_instrumentation_policy);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ mod tests {
};
use futures::future::BoxFuture;
use std::sync::Arc;
use typespec_client_core::http::DEFAULT_ALLOWED_QUERY_PARAMETERS;

// Test just the public API instrumentation policy without request instrumentation.
async fn run_public_api_instrumentation_test<C>(
Expand Down Expand Up @@ -320,8 +321,10 @@ mod tests {
let transport =
TransportPolicy::new(Transport::new(Arc::new(MockHttpClient::new(callback))));

let request_instrumentation_policy =
RequestInstrumentationPolicy::new(Some(mock_tracer.clone()));
let request_instrumentation_policy = RequestInstrumentationPolicy::new(
Some(mock_tracer.clone()),
(*DEFAULT_ALLOWED_QUERY_PARAMETERS).clone(),
);

let next: Vec<Arc<dyn Policy>> = vec![
Arc::new(request_instrumentation_policy),
Expand Down
Loading