Skip to content

Commit

Permalink
Merge branch 'main' into otel-json
Browse files Browse the repository at this point in the history
  • Loading branch information
ramgdev committed Mar 29, 2024
2 parents 5222f8d + 5b5cb61 commit 25b0857
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 51 deletions.
27 changes: 18 additions & 9 deletions RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,33 @@ A draft PR can be created, but before releasing consider the following:
## Steps to Release

1. Create a release PR
- For each crate
- Bump appropriate version
- Update change logs to reflect release version.
- Update API/SDK version as necessary
- Attach `integration test` label to the PR to run integration tests
- If there's a large enough set of changes, consider writing a migration guide.

* For each crate
* Bump appropriate version
* Update change logs to reflect release version.
* Update API/SDK version as necessary
* Attach `integration test` label to the PR to run integration tests
* If there's a large enough set of changes, consider writing a migration guide.

2. Merge the PR
- Get reviews from other Maintainers
- Ensure that there haven't been any interfering PRs

* Get reviews from other Maintainers
* Ensure that there haven't been any interfering PRs

3. Tag the release commit based on the [tagging convention](#tagging-convention). It should usually be a bump on minor version before 1.0
4. Create Github Release
5. [Publish](#publishing-crates) to crates.io using the version as of the release commit
6. Post to [#otel-rust](https://cloud-native.slack.com/archives/C03GDP0H023) on CNCF Slack.


## Tagging Convention

For each crate: it should be `<crate-name>-<version>` `<version>` being the simple `X.Y.Z`.
For example:

```sh
git tag -a opentelemetry-http-0.11.1 -m "opentelemetry-http 0.11.1 release"
git push origin opentelemetry-http-0.11.1
```

## Publishing Crates

Expand Down
7 changes: 6 additions & 1 deletion opentelemetry-http/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
# Changelog

## vNext
- Add feature flag enabling users to configure `reqwest` usage to use rustls via `reqwest/rustls-tls` feature flag

## v0.11.1

- Add feature flag enabling users to configure `reqwest` usage to use rustls via
`reqwest/rustls-tls` feature flag
[1638](https://github.com/open-telemetry/opentelemetry-rust/pull/1638).

## v0.11.0

Expand Down
2 changes: 1 addition & 1 deletion opentelemetry-http/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "opentelemetry-http"
version = "0.11.0"
version = "0.11.1"
description = "Helper implementations for sending HTTP requests. Uses include propagating and extracting context over http, exporting telemetry, requesting sampling strategies."
homepage = "https://github.com/open-telemetry/opentelemetry-rust"
repository = "https://github.com/open-telemetry/opentelemetry-rust"
Expand Down
4 changes: 4 additions & 0 deletions opentelemetry-jaeger-propagator/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## vNext

### Changed

- Propagation error will be reported to global error handler [#1640](https://github.com/open-telemetry/opentelemetry-rust/pull/1640)

## v0.1.0

### Added
Expand Down
51 changes: 33 additions & 18 deletions opentelemetry-jaeger-propagator/src/propagator.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use opentelemetry::propagation::PropagationError;
use opentelemetry::{
global::{self, Error},
propagation::{text_map_propagator::FieldIter, Extractor, Injector, TextMapPropagator},
Expand Down Expand Up @@ -69,7 +70,7 @@ impl Propagator {
}

/// Extract span context from header value
fn extract_span_context(&self, extractor: &dyn Extractor) -> Result<SpanContext, ()> {
fn extract_span_context(&self, extractor: &dyn Extractor) -> Option<SpanContext> {
let mut header_value = Cow::from(extractor.get(self.header_name).unwrap_or(""));
// if there is no :, it means header_value could be encoded as url, try decode first
if !header_value.contains(':') {
Expand All @@ -78,17 +79,31 @@ impl Propagator {

let parts = header_value.split_terminator(':').collect::<Vec<&str>>();
if parts.len() != 4 {
return Err(());
global::handle_error(Error::Propagation(PropagationError::extract(
"invalid jaeger header format",
"JaegerPropagator",
)));
return None;
}

// extract trace id
let trace_id = self.extract_trace_id(parts[0])?;
let span_id = self.extract_span_id(parts[1])?;
// Ignore parent span id since it's deprecated.
let flags = self.extract_trace_flags(parts[3])?;
let state = self.extract_trace_state(extractor)?;

Ok(SpanContext::new(trace_id, span_id, flags, true, state))
match (
self.extract_trace_id(parts[0]),
self.extract_span_id(parts[1]),
// Ignore parent span id since it's deprecated.
self.extract_trace_flags(parts[3]),
self.extract_trace_state(extractor),
) {
(Ok(trace_id), Ok(span_id), Ok(flags), Ok(state)) => {
Some(SpanContext::new(trace_id, span_id, flags, true, state))
}
_ => {
global::handle_error(Error::Propagation(PropagationError::extract(
"invalid jaeger header format",
"JaegerPropagator",
)));
None
}
}
}

/// Extract trace id from the header.
Expand Down Expand Up @@ -188,7 +203,7 @@ impl TextMapPropagator for Propagator {
fn extract_with_context(&self, cx: &Context, extractor: &dyn Extractor) -> Context {
self.extract_span_context(extractor)
.map(|sc| cx.with_remote_span_context(sc))
.unwrap_or_else(|_| cx.clone())
.unwrap_or_else(|| cx.clone())
}

fn fields(&self) -> FieldIter<'_> {
Expand Down Expand Up @@ -430,7 +445,7 @@ mod tests {
);
assert_eq!(
propagator_with_custom_header.extract_span_context(&map),
Ok(SpanContext::new(
Some(SpanContext::new(
TraceId::from_hex("12345").unwrap(),
SpanId::from_hex("54321").unwrap(),
TRACE_FLAG_DEBUG | TraceFlags::SAMPLED,
Expand All @@ -447,7 +462,7 @@ mod tests {
);
assert_eq!(
propagator_with_custom_header.extract_span_context(&map),
Ok(SpanContext::new(
Some(SpanContext::new(
TraceId::from_hex("12345").unwrap(),
SpanId::from_hex("54321").unwrap(),
TRACE_FLAG_DEBUG | TraceFlags::SAMPLED,
Expand All @@ -463,7 +478,7 @@ mod tests {
);
assert_eq!(
propagator_with_custom_header.extract_span_context(&map),
Err(())
None,
);

map.clear();
Expand All @@ -473,7 +488,7 @@ mod tests {
);
assert_eq!(
propagator_with_custom_header.extract_span_context(&map),
Err(())
None,
);

map.clear();
Expand All @@ -483,7 +498,7 @@ mod tests {
);
assert_eq!(
propagator_with_custom_header.extract_span_context(&map),
Err(())
None,
);

map.clear();
Expand All @@ -493,7 +508,7 @@ mod tests {
);
assert_eq!(
propagator_with_custom_header.extract_span_context(&map),
Err(())
None,
);

map.clear();
Expand All @@ -506,7 +521,7 @@ mod tests {
map.set(&too_long_baggage_key, "baggage_value".to_owned());
assert_eq!(
propagator_with_custom_header.extract_span_context(&map),
Err(())
None,
);
}

Expand Down
1 change: 1 addition & 0 deletions opentelemetry-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- **Breaking** [#1624](https://github.com/open-telemetry/opentelemetry-rust/pull/1624) Remove `OsResourceDetector` and
`ProcessResourceDetector` resource detectors, use the
[`opentelemetry-resource-detector`](https://crates.io/crates/opentelemetry-resource-detectors) instead.
- Baggage propagation error will be reported to global error handler [#1640](https://github.com/open-telemetry/opentelemetry-rust/pull/1640)

## v0.22.1

Expand Down
60 changes: 38 additions & 22 deletions opentelemetry-sdk/src/propagation/baggage.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use once_cell::sync::Lazy;
use opentelemetry::propagation::PropagationError;
use opentelemetry::{
baggage::{BaggageExt, KeyValueMetadata},
global,
propagation::{text_map_propagator::FieldIter, Extractor, Injector, TextMapPropagator},
Context,
};
Expand Down Expand Up @@ -99,30 +101,44 @@ impl TextMapPropagator for BaggagePropagator {
{
let mut iter = name_and_value.split('=');
if let (Some(name), Some(value)) = (iter.next(), iter.next()) {
let name = percent_decode_str(name).decode_utf8().map_err(|_| ())?;
let value = percent_decode_str(value).decode_utf8().map_err(|_| ())?;
let decode_name = percent_decode_str(name).decode_utf8();
let decode_value = percent_decode_str(value).decode_utf8();

// Here we don't store the first ; into baggage since it should be treated
// as separator rather part of metadata
let decoded_props = props
.iter()
.flat_map(|prop| percent_decode_str(prop).decode_utf8())
.map(|prop| prop.trim().to_string())
.collect::<Vec<String>>()
.join(";"); // join with ; because we deleted all ; when calling split above
if let (Ok(name), Ok(value)) = (decode_name, decode_value) {
// Here we don't store the first ; into baggage since it should be treated
// as separator rather part of metadata
let decoded_props = props
.iter()
.flat_map(|prop| percent_decode_str(prop).decode_utf8())
.map(|prop| prop.trim().to_string())
.collect::<Vec<String>>()
.join(";"); // join with ; because we deleted all ; when calling split above

Ok(KeyValueMetadata::new(
name.trim().to_owned(),
value.trim().to_string(),
decoded_props.as_str(),
))
Some(KeyValueMetadata::new(
name.trim().to_owned(),
value.trim().to_string(),
decoded_props.as_str(),
))
} else {
global::handle_error(PropagationError::extract(
"invalid UTF8 string in key values",
"BaggagePropagator",
));
None
}
} else {
// Invalid name-value format
Err(())
global::handle_error(PropagationError::extract(
"invalid baggage key-value format",
"BaggagePropagator",
));
None
}
} else {
// Invalid baggage value format
Err(())
global::handle_error(PropagationError::extract(
"invalid baggage format",
"BaggagePropagator",
));
None
}
});
cx.with_baggage(baggage)
Expand Down Expand Up @@ -172,7 +188,7 @@ mod tests {
vec![
(Key::new("key1"), (Value::from("value1"), BaggageMetadata::from("property1;property2"))),
(Key::new("key2"), (Value::from("value2"), BaggageMetadata::default())),
(Key::new("key3"), (Value::from("value3"), BaggageMetadata::from("propertyKey=propertyValue")))
(Key::new("key3"), (Value::from("value3"), BaggageMetadata::from("propertyKey=propertyValue"))),
].into_iter().collect()),
]
}
Expand Down Expand Up @@ -220,12 +236,12 @@ mod tests {
vec![
KeyValueMetadata::new("key1", "val1", "prop1"),
KeyValue::new("key2", "val2").into(),
KeyValueMetadata::new("key3", "val3", "anykey=anyvalue")
KeyValueMetadata::new("key3", "val3", "anykey=anyvalue"),
],
vec![
"key1=val1;prop1",
"key2=val2",
"key3=val3;anykey=anyvalue"
"key3=val3;anykey=anyvalue",
],
)
]
Expand Down
1 change: 1 addition & 0 deletions opentelemetry/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Added

- [#1623](https://github.com/open-telemetry/opentelemetry-rust/pull/1623) Add global::meter_provider_shutdown
- [#1640](https://github.com/open-telemetry/opentelemetry-rust/pull/1640) Add `PropagationError`

### Removed

Expand Down
8 changes: 8 additions & 0 deletions opentelemetry/src/global/error_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::sync::RwLock;
use crate::logs::LogError;
#[cfg(feature = "metrics")]
use crate::metrics::MetricsError;
use crate::propagation::PropagationError;
#[cfg(feature = "trace")]
use crate::trace::TraceError;
use once_cell::sync::Lazy;
Expand Down Expand Up @@ -32,6 +33,10 @@ pub enum Error {
/// Failed to export logs.
Log(#[from] LogError),

#[error(transparent)]
/// Error happens when injecting and extracting information using propagators.
Propagation(#[from] PropagationError),

#[error("{0}")]
/// Other types of failures not covered by the variants above.
Other(String),
Expand Down Expand Up @@ -61,6 +66,9 @@ pub fn handle_error<T: Into<Error>>(err: T) {
#[cfg(feature = "logs")]
#[cfg_attr(docsrs, doc(cfg(feature = "logs")))]
Error::Log(err) => eprintln!("OpenTelemetry log error occurred. {}", err),
Error::Propagation(err) => {
eprintln!("OpenTelemetry propagation error occurred. {}", err)
}
Error::Other(err_msg) => eprintln!("OpenTelemetry error occurred. {}", err_msg),
},
}
Expand Down
32 changes: 32 additions & 0 deletions opentelemetry/src/propagation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
//! [`Context`]: crate::Context

use std::collections::HashMap;
use thiserror::Error;

pub mod composite;
pub mod text_map_propagator;
Expand Down Expand Up @@ -61,6 +62,37 @@ impl<S: std::hash::BuildHasher> Extractor for HashMap<String, String, S> {
}
}

/// Error when extracting or injecting context data(i.e propagating) across application boundaries.
#[derive(Error, Debug)]
#[error("Cannot {} from {}, {}", ops, message, propagator_name)]
pub struct PropagationError {
message: &'static str,
// which propagator does this error comes from
propagator_name: &'static str,
// are we extracting or injecting information across application boundaries
ops: &'static str,
}

impl PropagationError {
/// Error happens when extracting information
pub fn extract(message: &'static str, propagator_name: &'static str) -> Self {
PropagationError {
message,
propagator_name,
ops: "extract",
}
}

/// Error happens when extracting information
pub fn inject(message: &'static str, propagator_name: &'static str) -> Self {
PropagationError {
message,
propagator_name,
ops: "inject",
}
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit 25b0857

Please sign in to comment.