From 84bc16156234a7f9980b6f50e17e00ee9df4a653 Mon Sep 17 00:00:00 2001 From: Lalit Date: Sun, 9 Jun 2024 22:57:23 -0700 Subject: [PATCH 01/16] initial commit --- opentelemetry-proto/src/transform/common.rs | 17 +++++++++ opentelemetry-proto/src/transform/logs.rs | 40 ++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/opentelemetry-proto/src/transform/common.rs b/opentelemetry-proto/src/transform/common.rs index 8197d90574..14b271cea1 100644 --- a/opentelemetry-proto/src/transform/common.rs +++ b/opentelemetry-proto/src/transform/common.rs @@ -138,4 +138,21 @@ pub mod tonic { .collect::>() .into() } + + #[derive(Hash, Eq, PartialEq)] + pub(crate) struct InstrumentationScopeKey<'a> { + name: &'a str, + version: Option<&'a str>, + schema_url: Option<&'a str>, + } + + impl<'a> From<&'a opentelemetry_sdk::InstrumentationLibrary> for InstrumentationScopeKey<'a> { + fn from(library: &'a opentelemetry_sdk::InstrumentationLibrary) -> Self { + InstrumentationScopeKey { + name: library.name.as_ref(), + version: library.version.as_deref(), + schema_url: library.schema_url.as_deref(), + } + } + } } diff --git a/opentelemetry-proto/src/transform/logs.rs b/opentelemetry-proto/src/transform/logs.rs index dbe3fa91e6..6215fc8855 100644 --- a/opentelemetry-proto/src/transform/logs.rs +++ b/opentelemetry-proto/src/transform/logs.rs @@ -2,7 +2,7 @@ pub mod tonic { use crate::{ tonic::{ - common::v1::{any_value::Value, AnyValue, ArrayValue, KeyValue, KeyValueList}, + common::v1::{any_value::Value, AnyValue, ArrayValue, KeyValue, KeyValueList, InstrumentationScope}, logs::v1::{LogRecord, ResourceLogs, ScopeLogs, SeverityNumber}, resource::v1::Resource, Attributes, @@ -10,6 +10,7 @@ pub mod tonic { transform::common::{to_nanos, tonic::ResourceAttributesWithSchema}, }; use opentelemetry::logs::{AnyValue as LogsAnyValue, Severity}; + use std::collections::HashMap; impl From for AnyValue { fn from(value: LogsAnyValue) -> Self { @@ -143,4 +144,41 @@ pub mod tonic { } } } + + pub fn group_logs_by_resource_and_scope<'a>(logs: Vec, resource: &ResourceAttributesWithSchema) -> Vec { + // no need of explicit grouping by resource, as all the logs belong to single resource. + let scope_map = logs.iter().fold( + HashMap::new(), + |mut scope_map: HashMap)>, log| { + let instrumentation = &log.instrumentation; + let scope_key = InstrumentationScopeKey::from(instrumentation); + let entry = scope_map.entry(scope_key).or_insert_with(|| (instrumentation.attributes.as_slice(), Vec::new())); + entry.1.push(log); + scope_map + }, + ); + + let scope_logs = scope_map.into_iter().map(|(scope_key, (attributes, log_records))| { + ScopeLogs { + scope: Some(InstrumentationScope { + name: scope_key.name.to_string(), + version: scope_key.version.unwrap_or_default().to_string(), + schema_url: scope_key.schema_url.unwrap_or_default().to_string(), + attributes: attributes.to_vec(), + dropped_attributes_count: 0, // Assuming no dropped attributes + }), + log_records: log_records.into_iter().map(|log| log.clone().into()).collect(), + ..Default::default() + } + }).collect(); + + ResourceLogs { + resource: Some(opentelemetry_proto::tonic::resource::v1::Resource { + attributes: resource.attributes.0.clone(), + dropped_attributes_count: 0, + }), + scope_logs, + schema_url: resource.schema_url.clone().unwrap_or_default(), + } + } } From a08cdad10a357db34f1a3210ba29bcd897aadbf6 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Mon, 10 Jun 2024 09:46:55 -0700 Subject: [PATCH 02/16] more changes --- opentelemetry-otlp/src/exporter/http/logs.rs | 2 +- opentelemetry-otlp/src/exporter/http/mod.rs | 9 ++-- opentelemetry-proto/Cargo.toml | 2 +- opentelemetry-proto/src/transform/common.rs | 17 ------- opentelemetry-proto/src/transform/logs.rs | 50 +++++++++++--------- 5 files changed, 32 insertions(+), 48 deletions(-) diff --git a/opentelemetry-otlp/src/exporter/http/logs.rs b/opentelemetry-otlp/src/exporter/http/logs.rs index 3e59ffdd8e..396dec680d 100644 --- a/opentelemetry-otlp/src/exporter/http/logs.rs +++ b/opentelemetry-otlp/src/exporter/http/logs.rs @@ -25,7 +25,7 @@ impl LogExporter for OtlpHttpClient { .map(|cow_log_data| cow_log_data.into_owned()) // Converts Cow to owned LogData .collect::>(); - let (body, content_type) = { self.build_logs_export_body(owned_batch, &self.resource)? }; + let (body, content_type) = { self.build_logs_export_body(owned_batch)? }; let mut request = http::Request::builder() .method(Method::POST) .uri(&self.collector_endpoint) diff --git a/opentelemetry-otlp/src/exporter/http/mod.rs b/opentelemetry-otlp/src/exporter/http/mod.rs index 4a45379121..340939e0fa 100644 --- a/opentelemetry-otlp/src/exporter/http/mod.rs +++ b/opentelemetry-otlp/src/exporter/http/mod.rs @@ -9,7 +9,8 @@ use crate::{ use http::{HeaderName, HeaderValue, Uri}; use opentelemetry_http::HttpClient; use opentelemetry_proto::transform::common::tonic::ResourceAttributesWithSchema; - +#[cfg(feature = "logs")] +use opentelemetry_proto::transform::logs::tonic::group_logs_by_resource_and_scope; #[cfg(feature = "logs")] use opentelemetry_sdk::export::logs::LogData; #[cfg(feature = "trace")] @@ -333,13 +334,9 @@ impl OtlpHttpClient { fn build_logs_export_body( &self, logs: Vec, - resource: &opentelemetry_proto::transform::common::tonic::ResourceAttributesWithSchema, ) -> opentelemetry::logs::LogResult<(Vec, &'static str)> { use opentelemetry_proto::tonic::collector::logs::v1::ExportLogsServiceRequest; - let resource_logs = logs - .into_iter() - .map(|log_event| (log_event, resource).into()) - .collect::>(); + let resource_logs = group_logs_by_resource_and_scope(logs, &self.resource); let req = ExportLogsServiceRequest { resource_logs }; match self.protocol { diff --git a/opentelemetry-proto/Cargo.toml b/opentelemetry-proto/Cargo.toml index 65836b58e7..6a5a3b8063 100644 --- a/opentelemetry-proto/Cargo.toml +++ b/opentelemetry-proto/Cargo.toml @@ -29,7 +29,7 @@ path = "tests/json_deserialize.rs" [features] -default = [] +default = ["full"] full = ["gen-tonic", "trace", "logs", "metrics", "zpages", "with-serde"] diff --git a/opentelemetry-proto/src/transform/common.rs b/opentelemetry-proto/src/transform/common.rs index 14b271cea1..8197d90574 100644 --- a/opentelemetry-proto/src/transform/common.rs +++ b/opentelemetry-proto/src/transform/common.rs @@ -138,21 +138,4 @@ pub mod tonic { .collect::>() .into() } - - #[derive(Hash, Eq, PartialEq)] - pub(crate) struct InstrumentationScopeKey<'a> { - name: &'a str, - version: Option<&'a str>, - schema_url: Option<&'a str>, - } - - impl<'a> From<&'a opentelemetry_sdk::InstrumentationLibrary> for InstrumentationScopeKey<'a> { - fn from(library: &'a opentelemetry_sdk::InstrumentationLibrary) -> Self { - InstrumentationScopeKey { - name: library.name.as_ref(), - version: library.version.as_deref(), - schema_url: library.schema_url.as_deref(), - } - } - } } diff --git a/opentelemetry-proto/src/transform/logs.rs b/opentelemetry-proto/src/transform/logs.rs index 6215fc8855..6bb1a4d233 100644 --- a/opentelemetry-proto/src/transform/logs.rs +++ b/opentelemetry-proto/src/transform/logs.rs @@ -2,7 +2,7 @@ pub mod tonic { use crate::{ tonic::{ - common::v1::{any_value::Value, AnyValue, ArrayValue, KeyValue, KeyValueList, InstrumentationScope}, + common::v1::{any_value::Value, AnyValue, ArrayValue, KeyValue, KeyValueList}, logs::v1::{LogRecord, ResourceLogs, ScopeLogs, SeverityNumber}, resource::v1::Resource, Attributes, @@ -145,40 +145,44 @@ pub mod tonic { } } - pub fn group_logs_by_resource_and_scope<'a>(logs: Vec, resource: &ResourceAttributesWithSchema) -> Vec { + pub fn group_logs_by_resource_and_scope( + logs: Vec, + resource: &ResourceAttributesWithSchema, + ) -> Vec { // no need of explicit grouping by resource, as all the logs belong to single resource. let scope_map = logs.iter().fold( HashMap::new(), - |mut scope_map: HashMap)>, log| { + |mut scope_map: HashMap< + &opentelemetry_sdk::InstrumentationLibrary, + Vec<&opentelemetry_sdk::export::logs::LogData>, + >, + log| { let instrumentation = &log.instrumentation; - let scope_key = InstrumentationScopeKey::from(instrumentation); - let entry = scope_map.entry(scope_key).or_insert_with(|| (instrumentation.attributes.as_slice(), Vec::new())); - entry.1.push(log); + scope_map.entry(instrumentation).or_default().push(log); scope_map }, ); - - let scope_logs = scope_map.into_iter().map(|(scope_key, (attributes, log_records))| { - ScopeLogs { - scope: Some(InstrumentationScope { - name: scope_key.name.to_string(), - version: scope_key.version.unwrap_or_default().to_string(), - schema_url: scope_key.schema_url.unwrap_or_default().to_string(), - attributes: attributes.to_vec(), - dropped_attributes_count: 0, // Assuming no dropped attributes - }), - log_records: log_records.into_iter().map(|log| log.clone().into()).collect(), + + let scope_logs = scope_map + .into_iter() + .map(|(instrumentation, log_records)| ScopeLogs { + scope: Some(instrumentation.into()), + schema_url: resource.schema_url.clone().unwrap_or_default(), + log_records: log_records + .into_iter() + .map(|log_data| log_data.record.clone().into()) + .collect(), ..Default::default() - } - }).collect(); - - ResourceLogs { - resource: Some(opentelemetry_proto::tonic::resource::v1::Resource { + }) + .collect(); + + vec![ResourceLogs { + resource: Some(Resource { attributes: resource.attributes.0.clone(), dropped_attributes_count: 0, }), scope_logs, schema_url: resource.schema_url.clone().unwrap_or_default(), - } + }] } } From f00eb96037fb3bbfb826272bf50a7a66f1a75005 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Mon, 10 Jun 2024 20:46:01 +0000 Subject: [PATCH 03/16] add example --- opentelemetry-proto/Cargo.toml | 2 +- opentelemetry-proto/src/transform/logs.rs | 73 ++++++++++++++++++++++- 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/opentelemetry-proto/Cargo.toml b/opentelemetry-proto/Cargo.toml index 6a5a3b8063..65836b58e7 100644 --- a/opentelemetry-proto/Cargo.toml +++ b/opentelemetry-proto/Cargo.toml @@ -29,7 +29,7 @@ path = "tests/json_deserialize.rs" [features] -default = ["full"] +default = [] full = ["gen-tonic", "trace", "logs", "metrics", "zpages", "with-serde"] diff --git a/opentelemetry-proto/src/transform/logs.rs b/opentelemetry-proto/src/transform/logs.rs index 6bb1a4d233..1f7424b937 100644 --- a/opentelemetry-proto/src/transform/logs.rs +++ b/opentelemetry-proto/src/transform/logs.rs @@ -172,7 +172,6 @@ pub mod tonic { .into_iter() .map(|log_data| log_data.record.clone().into()) .collect(), - ..Default::default() }) .collect(); @@ -186,3 +185,75 @@ pub mod tonic { }] } } + +#[cfg(test)] +mod tests { + use crate::transform::common::tonic::ResourceAttributesWithSchema; + use opentelemetry::logs::LogRecord as _; + use opentelemetry_sdk::export::logs::LogData; + use opentelemetry_sdk::{logs::LogRecord, Resource}; + use std::time::SystemTime; + + fn create_test_log_data(instrumentation_name: &str, _message: &str) -> LogData { + let mut logrecord = LogRecord::default(); + logrecord.set_timestamp(SystemTime::now()); + logrecord.set_observed_timestamp(SystemTime::now()); + LogData { + instrumentation: opentelemetry_sdk::InstrumentationLibrary::builder( + instrumentation_name.to_string(), + ) + .build(), + record: logrecord, + } + } + + #[test] + fn test_group_logs_by_resource_and_scope_single_scope() { + let resource = Resource::default(); + let log1 = create_test_log_data("test-lib", "Log 1"); + let log2 = create_test_log_data("test-lib", "Log 2"); + + let logs = vec![log1, log2]; + let resource: ResourceAttributesWithSchema = (&resource).into(); // Convert Resource to ResourceAttributesWithSchema + + let grouped_logs = + crate::transform::logs::tonic::group_logs_by_resource_and_scope(logs, &resource); + + assert_eq!(grouped_logs.len(), 1); + let resource_logs = &grouped_logs[0]; + assert_eq!(resource_logs.scope_logs.len(), 1); + + let scope_logs = &resource_logs.scope_logs[0]; + assert_eq!(scope_logs.log_records.len(), 2); + } + + #[test] + fn test_group_logs_by_resource_and_scope_multiple_scopes() { + let resource = Resource::default(); + let log1 = create_test_log_data("lib1", "Log 1"); + let log2 = create_test_log_data("lib2", "Log 2"); + + let logs = vec![log1, log2]; + let resource: ResourceAttributesWithSchema = (&resource).into(); // Convert Resource to ResourceAttributesWithSchema + let grouped_logs = + crate::transform::logs::tonic::group_logs_by_resource_and_scope(logs, &resource); + + assert_eq!(grouped_logs.len(), 1); + let resource_logs = &grouped_logs[0]; + assert_eq!(resource_logs.scope_logs.len(), 2); + + let scope_logs_1 = &resource_logs + .scope_logs + .iter() + .find(|scope| scope.scope.as_ref().unwrap().name == "lib1") + .unwrap(); + let scope_logs_2 = &resource_logs + .scope_logs + .iter() + .find(|scope| scope.scope.as_ref().unwrap().name == "lib2") + .unwrap(); + + assert_eq!(scope_logs_1.log_records.len(), 1); + assert_eq!(scope_logs_2.log_records.len(), 1); + } +} From 90f7da51e91342ae42ac7f1023b7cc28381ad8e3 Mon Sep 17 00:00:00 2001 From: Lalit Date: Mon, 10 Jun 2024 23:23:12 -0700 Subject: [PATCH 04/16] add for spans --- opentelemetry-proto/Cargo.toml | 5 +- opentelemetry-proto/src/transform/trace.rs | 181 +++++++++++++++++++++ 2 files changed, 185 insertions(+), 1 deletion(-) diff --git a/opentelemetry-proto/Cargo.toml b/opentelemetry-proto/Cargo.toml index 65836b58e7..ecbbbb304a 100644 --- a/opentelemetry-proto/Cargo.toml +++ b/opentelemetry-proto/Cargo.toml @@ -29,7 +29,7 @@ path = "tests/json_deserialize.rs" [features] -default = [] +default = ["full"] full = ["gen-tonic", "trace", "logs", "metrics", "zpages", "with-serde"] @@ -42,6 +42,7 @@ trace = ["opentelemetry/trace", "opentelemetry_sdk/trace"] metrics = ["opentelemetry/metrics", "opentelemetry_sdk/metrics"] logs = ["opentelemetry/logs", "opentelemetry_sdk/logs"] zpages = ["trace"] +testing = ["opentelemetry/testing"] # add ons with-schemars = ["schemars"] @@ -57,7 +58,9 @@ serde = { workspace = true, optional = true, features = ["serde_derive"] } hex = { version = "0.4.3", optional = true } [dev-dependencies] +opentelemetry = { version = "0.23", features = ["testing"], path = "../opentelemetry" } tonic-build = { workspace = true } prost-build = { workspace = true } tempfile = "3.3.0" serde_json = "1.0" + diff --git a/opentelemetry-proto/src/transform/trace.rs b/opentelemetry-proto/src/transform/trace.rs index 3f0003d44e..32440c609d 100644 --- a/opentelemetry-proto/src/transform/trace.rs +++ b/opentelemetry-proto/src/transform/trace.rs @@ -9,6 +9,7 @@ pub mod tonic { use opentelemetry::trace; use opentelemetry::trace::{Link, SpanId, SpanKind}; use opentelemetry_sdk::export::trace::SpanData; + use std::collections::HashMap; impl From for span::SpanKind { fn from(span_kind: SpanKind) -> Self { @@ -44,6 +45,50 @@ pub mod tonic { } } } + impl From for Span { + fn from(source_span: opentelemetry_sdk::export::trace::SpanData) -> Self { + let span_kind: span::SpanKind = source_span.span_kind.into(); + Span { + trace_id: source_span.span_context.trace_id().to_bytes().to_vec(), + span_id: source_span.span_context.span_id().to_bytes().to_vec(), + trace_state: source_span.span_context.trace_state().header(), + parent_span_id: { + if source_span.parent_span_id != SpanId::INVALID { + source_span.parent_span_id.to_bytes().to_vec() + } else { + vec![] + } + }, + flags: source_span.span_context.trace_flags().to_u8() as u32, + name: source_span.name.into_owned(), + kind: span_kind as i32, + start_time_unix_nano: to_nanos(source_span.start_time), + end_time_unix_nano: to_nanos(source_span.end_time), + dropped_attributes_count: source_span.dropped_attributes_count, + attributes: Attributes::from(source_span.attributes).0, + dropped_events_count: source_span.events.dropped_count, + events: source_span + .events + .into_iter() + .map(|event| span::Event { + time_unix_nano: to_nanos(event.timestamp), + name: event.name.into(), + attributes: Attributes::from(event.attributes).0, + dropped_attributes_count: event.dropped_attributes_count, + }) + .collect(), + dropped_links_count: source_span.links.dropped_count, + links: source_span.links.into_iter().map(Into::into).collect(), + status: Some(Status { + code: status::StatusCode::from(&source_span.status).into(), + message: match source_span.status { + trace::Status::Error { description } => description.to_string(), + _ => Default::default(), + }, + }), + } + } + } impl ResourceSpans { pub fn new(source_span: SpanData, resource: &ResourceAttributesWithSchema) -> Self { @@ -105,4 +150,140 @@ pub mod tonic { } } } + + pub fn group_spans_by_resource_and_scope( + spans: Vec, + resource: &ResourceAttributesWithSchema, + ) -> Vec { + // Group spans by their instrumentation library + let scope_map = spans.iter().fold( + HashMap::new(), + |mut scope_map: HashMap<&opentelemetry_sdk::InstrumentationLibrary, Vec<&SpanData>>, + span| { + let instrumentation = &span.instrumentation_lib; + scope_map.entry(instrumentation).or_default().push(span); + scope_map + }, + ); + + // Convert the grouped spans into ScopeSpans + let scope_spans = scope_map + .into_iter() + .map(|(instrumentation, span_records)| ScopeSpans { + scope: Some(instrumentation.into()), + schema_url: resource.schema_url.clone().unwrap_or_default(), + spans: span_records + .into_iter() + .map(|span_data| span_data.clone().into()) + .collect(), + }) + .collect(); + + // Wrap ScopeSpans into a single ResourceSpans + vec![ResourceSpans { + resource: Some(Resource { + attributes: resource.attributes.0.clone(), + dropped_attributes_count: 0, + }), + scope_spans, + schema_url: resource.schema_url.clone().unwrap_or_default(), + }] + } +} + +#[cfg(test)] +mod tests { + use crate::tonic::common::v1::any_value::Value; + use crate::transform::common::tonic::ResourceAttributesWithSchema; + use opentelemetry::trace::{ + SpanContext, SpanId, SpanKind, Status, TraceFlags, TraceId, TraceState, + }; + use opentelemetry::KeyValue; + use opentelemetry_sdk::export::trace::SpanData; + use opentelemetry_sdk::resource::Resource; + use opentelemetry_sdk::trace::{SpanEvents, SpanLinks}; + use opentelemetry_sdk::InstrumentationLibrary; + use std::borrow::Cow; + use std::time::{Duration, SystemTime}; + + fn create_test_span_data(instrumentation_name: &'static str) -> SpanData { + let span_context = SpanContext::new( + TraceId::from_u128(123), + SpanId::from_u64(456), + TraceFlags::default(), + false, + TraceState::default(), + ); + + SpanData { + span_context, + parent_span_id: SpanId::from_u64(0), + span_kind: SpanKind::Internal, + name: Cow::Borrowed("test_span"), + start_time: SystemTime::now(), + end_time: SystemTime::now() + Duration::from_secs(1), + attributes: vec![KeyValue::new("key", "value")], + dropped_attributes_count: 0, + events: SpanEvents::default(), + links: SpanLinks::default(), + status: Status::Unset, + instrumentation_lib: InstrumentationLibrary::builder(instrumentation_name).build(), + } + } + + #[test] + fn test_group_spans_by_resource_and_scope() { + let resource = Resource::new(vec![KeyValue::new("resource_key", "resource_value")]); + let span_data1 = create_test_span_data("lib1"); + let span_data2 = create_test_span_data("lib1"); + let span_data3 = create_test_span_data("lib2"); + + let spans = vec![span_data1.clone(), span_data2.clone(), span_data3.clone()]; + let resource: ResourceAttributesWithSchema = (&resource).into(); // Convert Resource to ResourceAttributesWithSchema + + let grouped_spans = + crate::transform::trace::tonic::group_spans_by_resource_and_scope(spans, &resource); + + assert_eq!(grouped_spans.len(), 1); + + let resource_spans = &grouped_spans[0]; + assert_eq!( + resource_spans.resource.as_ref().unwrap().attributes.len(), + 1 + ); + assert_eq!( + resource_spans.resource.as_ref().unwrap().attributes[0].key, + "resource_key" + ); + assert_eq!( + resource_spans.resource.as_ref().unwrap().attributes[0] + .value + .clone() + .unwrap() + .value + .unwrap(), + Value::StringValue("resource_value".to_string()) + ); + + let scope_spans = &resource_spans.scope_spans; + assert_eq!(scope_spans.len(), 2); + + let scope_span1 = &scope_spans[0]; + let scope_span2 = &scope_spans[1]; + + assert_eq!(scope_span1.scope.as_ref().unwrap().name, "lib1"); + assert_eq!(scope_span2.scope.as_ref().unwrap().name, "lib2"); + + assert_eq!(scope_span1.spans.len(), 2); + assert_eq!(scope_span2.spans.len(), 1); + + assert_eq!( + scope_span1.spans[0].trace_id, + span_data1.span_context.trace_id().to_bytes().to_vec() + ); + assert_eq!( + scope_span2.spans[0].trace_id, + span_data3.span_context.trace_id().to_bytes().to_vec() + ); + } } From 58501f60984b6e585691b2aa16363943c9a98c30 Mon Sep 17 00:00:00 2001 From: Lalit Date: Mon, 10 Jun 2024 23:32:40 -0700 Subject: [PATCH 05/16] invoke group method from otel-otlp --- opentelemetry-otlp/src/exporter/http/mod.rs | 13 ++++--------- opentelemetry-otlp/src/exporter/http/trace.rs | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/opentelemetry-otlp/src/exporter/http/mod.rs b/opentelemetry-otlp/src/exporter/http/mod.rs index 340939e0fa..2fa3ff851b 100644 --- a/opentelemetry-otlp/src/exporter/http/mod.rs +++ b/opentelemetry-otlp/src/exporter/http/mod.rs @@ -11,6 +11,8 @@ use opentelemetry_http::HttpClient; use opentelemetry_proto::transform::common::tonic::ResourceAttributesWithSchema; #[cfg(feature = "logs")] use opentelemetry_proto::transform::logs::tonic::group_logs_by_resource_and_scope; +#[cfg(feature = "trace")] +use opentelemetry_proto::transform::trace::tonic::group_spans_by_resource_and_scope; #[cfg(feature = "logs")] use opentelemetry_sdk::export::logs::LogData; #[cfg(feature = "trace")] @@ -308,16 +310,9 @@ impl OtlpHttpClient { fn build_trace_export_body( &self, spans: Vec, - resource: &opentelemetry_proto::transform::common::tonic::ResourceAttributesWithSchema, ) -> opentelemetry::trace::TraceResult<(Vec, &'static str)> { - use opentelemetry_proto::tonic::{ - collector::trace::v1::ExportTraceServiceRequest, trace::v1::ResourceSpans, - }; - - let resource_spans = spans - .into_iter() - .map(|span| ResourceSpans::new(span, resource)) - .collect::>(); + use opentelemetry_proto::tonic::collector::trace::v1::ExportTraceServiceRequest; + let resource_spans = group_spans_by_resource_and_scope(spans, &self.resource); let req = ExportTraceServiceRequest { resource_spans }; match self.protocol { diff --git a/opentelemetry-otlp/src/exporter/http/trace.rs b/opentelemetry-otlp/src/exporter/http/trace.rs index 8d6c3116cd..cc7894c266 100644 --- a/opentelemetry-otlp/src/exporter/http/trace.rs +++ b/opentelemetry-otlp/src/exporter/http/trace.rs @@ -21,7 +21,7 @@ impl SpanExporter for OtlpHttpClient { Err(err) => return Box::pin(std::future::ready(Err(err))), }; - let (body, content_type) = match self.build_trace_export_body(batch, &self.resource) { + let (body, content_type) = match self.build_trace_export_body(batch) { Ok(body) => body, Err(e) => return Box::pin(std::future::ready(Err(e))), }; From dc81bcce8afed085daf6f85e0249990a39e476c1 Mon Sep 17 00:00:00 2001 From: Lalit Date: Mon, 10 Jun 2024 23:42:13 -0700 Subject: [PATCH 06/16] add grouping for otlp-grpc --- opentelemetry-otlp/src/exporter/tonic/logs.rs | 18 +++++++++--------- opentelemetry-otlp/src/exporter/tonic/trace.rs | 11 +++-------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/opentelemetry-otlp/src/exporter/tonic/logs.rs b/opentelemetry-otlp/src/exporter/tonic/logs.rs index 6cefd611ff..b529eda511 100644 --- a/opentelemetry-otlp/src/exporter/tonic/logs.rs +++ b/opentelemetry-otlp/src/exporter/tonic/logs.rs @@ -7,6 +7,8 @@ use opentelemetry_proto::tonic::collector::logs::v1::{ use opentelemetry_sdk::export::logs::{LogData, LogExporter}; use tonic::{codegen::CompressionEncoding, service::Interceptor, transport::Channel, Request}; +use opentelemetry_proto::transform::logs::tonic::group_logs_by_resource_and_scope; + use super::BoxInterceptor; pub(crate) struct TonicLogsClient { @@ -65,15 +67,13 @@ impl LogExporter for TonicLogsClient { None => return Err(LogError::Other("exporter is already shut down".into())), }; - // TODO: Avoid cloning here. - let resource_logs = { - batch - .into_iter() - .map(|log_data_cow| (log_data_cow.into_owned())) - .map(|log_data| (log_data, &self.resource)) - .map(Into::into) - .collect() - }; + //TODO: avoid cloning here. + let owned_batch = batch + .into_iter() + .map(|cow_log_data| cow_log_data.into_owned()) // Converts Cow to owned LogData + .collect::>(); + + let resource_logs = group_logs_by_resource_and_scope(owned_batch, &self.resource); client .export(Request::from_parts( diff --git a/opentelemetry-otlp/src/exporter/tonic/trace.rs b/opentelemetry-otlp/src/exporter/tonic/trace.rs index a0dbe0e76b..a4d12ebde7 100644 --- a/opentelemetry-otlp/src/exporter/tonic/trace.rs +++ b/opentelemetry-otlp/src/exporter/tonic/trace.rs @@ -5,10 +5,11 @@ use opentelemetry::trace::TraceError; use opentelemetry_proto::tonic::collector::trace::v1::{ trace_service_client::TraceServiceClient, ExportTraceServiceRequest, }; -use opentelemetry_proto::tonic::trace::v1::ResourceSpans; use opentelemetry_sdk::export::trace::{ExportResult, SpanData, SpanExporter}; use tonic::{codegen::CompressionEncoding, service::Interceptor, transport::Channel, Request}; +use opentelemetry_proto::transform::trace::tonic::group_spans_by_resource_and_scope; + use super::BoxInterceptor; pub(crate) struct TonicTracesClient { @@ -71,13 +72,7 @@ impl SpanExporter for TonicTracesClient { } }; - // TODO: Avoid cloning here. - let resource_spans = { - batch - .into_iter() - .map(|log_data| ResourceSpans::new(log_data, &self.resource)) - .collect() - }; + let resource_spans = group_spans_by_resource_and_scope(batch, &self.resource); Box::pin(async move { client From 63cda4ca66003e414c897c74a001cdfb35ccf530 Mon Sep 17 00:00:00 2001 From: Lalit Date: Tue, 11 Jun 2024 17:21:03 -0700 Subject: [PATCH 07/16] add more tests --- opentelemetry-proto/src/transform/trace.rs | 79 +++++++++++++++++++--- 1 file changed, 70 insertions(+), 9 deletions(-) diff --git a/opentelemetry-proto/src/transform/trace.rs b/opentelemetry-proto/src/transform/trace.rs index 32440c609d..b5f7f50b27 100644 --- a/opentelemetry-proto/src/transform/trace.rs +++ b/opentelemetry-proto/src/transform/trace.rs @@ -232,7 +232,52 @@ mod tests { } #[test] - fn test_group_spans_by_resource_and_scope() { + fn test_group_spans_by_resource_and_scope_single_span() { + let resource = Resource::new(vec![KeyValue::new("resource_key", "resource_value")]); + let span_data = create_test_span_data("lib1"); + + let spans = vec![span_data.clone()]; + let resource: ResourceAttributesWithSchema = (&resource).into(); // Convert Resource to ResourceAttributesWithSchema + + let grouped_spans = + crate::transform::trace::tonic::group_spans_by_resource_and_scope(spans, &resource); + + assert_eq!(grouped_spans.len(), 1); + + let resource_spans = &grouped_spans[0]; + assert_eq!( + resource_spans.resource.as_ref().unwrap().attributes.len(), + 1 + ); + assert_eq!( + resource_spans.resource.as_ref().unwrap().attributes[0].key, + "resource_key" + ); + assert_eq!( + resource_spans.resource.as_ref().unwrap().attributes[0] + .value + .clone() + .unwrap() + .value + .unwrap(), + Value::StringValue("resource_value".to_string()) + ); + + let scope_spans = &resource_spans.scope_spans; + assert_eq!(scope_spans.len(), 1); + + let scope_span = &scope_spans[0]; + assert_eq!(scope_span.scope.as_ref().unwrap().name, "lib1"); + assert_eq!(scope_span.spans.len(), 1); + + assert_eq!( + scope_span.spans[0].trace_id, + span_data.span_context.trace_id().to_bytes().to_vec() + ); + } + + #[test] + fn test_group_spans_by_resource_and_scope_multiple_span() { let resource = Resource::new(vec![KeyValue::new("resource_key", "resource_value")]); let span_data1 = create_test_span_data("lib1"); let span_data2 = create_test_span_data("lib1"); @@ -268,21 +313,37 @@ mod tests { let scope_spans = &resource_spans.scope_spans; assert_eq!(scope_spans.len(), 2); - let scope_span1 = &scope_spans[0]; - let scope_span2 = &scope_spans[1]; + // Check the scope spans for both lib1 and lib2 + let mut lib1_scope_span = None; + let mut lib2_scope_span = None; + + for scope_span in scope_spans { + match scope_span.scope.as_ref().unwrap().name.as_str() { + "lib1" => lib1_scope_span = Some(scope_span), + "lib2" => lib2_scope_span = Some(scope_span), + _ => {} + } + } + + let lib1_scope_span = lib1_scope_span.expect("lib1 scope span not found"); + let lib2_scope_span = lib2_scope_span.expect("lib2 scope span not found"); - assert_eq!(scope_span1.scope.as_ref().unwrap().name, "lib1"); - assert_eq!(scope_span2.scope.as_ref().unwrap().name, "lib2"); + assert_eq!(lib1_scope_span.scope.as_ref().unwrap().name, "lib1"); + assert_eq!(lib2_scope_span.scope.as_ref().unwrap().name, "lib2"); - assert_eq!(scope_span1.spans.len(), 2); - assert_eq!(scope_span2.spans.len(), 1); + assert_eq!(lib1_scope_span.spans.len(), 2); + assert_eq!(lib2_scope_span.spans.len(), 1); assert_eq!( - scope_span1.spans[0].trace_id, + lib1_scope_span.spans[0].trace_id, span_data1.span_context.trace_id().to_bytes().to_vec() ); assert_eq!( - scope_span2.spans[0].trace_id, + lib1_scope_span.spans[1].trace_id, + span_data2.span_context.trace_id().to_bytes().to_vec() + ); + assert_eq!( + lib2_scope_span.spans[0].trace_id, span_data3.span_context.trace_id().to_bytes().to_vec() ); } From 185f6c7b77011c48b9db104c900bf4ac5e22b778 Mon Sep 17 00:00:00 2001 From: Lalit Date: Tue, 11 Jun 2024 17:25:46 -0700 Subject: [PATCH 08/16] tests.. --- opentelemetry-proto/src/transform/trace.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/opentelemetry-proto/src/transform/trace.rs b/opentelemetry-proto/src/transform/trace.rs index b5f7f50b27..218191b7dd 100644 --- a/opentelemetry-proto/src/transform/trace.rs +++ b/opentelemetry-proto/src/transform/trace.rs @@ -232,7 +232,7 @@ mod tests { } #[test] - fn test_group_spans_by_resource_and_scope_single_span() { + fn test_group_spans_by_resource_and_scope_single_scope() { let resource = Resource::new(vec![KeyValue::new("resource_key", "resource_value")]); let span_data = create_test_span_data("lib1"); @@ -277,7 +277,7 @@ mod tests { } #[test] - fn test_group_spans_by_resource_and_scope_multiple_span() { + fn test_group_spans_by_resource_and_scope_multiple_scopes() { let resource = Resource::new(vec![KeyValue::new("resource_key", "resource_value")]); let span_data1 = create_test_span_data("lib1"); let span_data2 = create_test_span_data("lib1"); From 764422098d24f8ab88ceed235d44e44e7fbf4457 Mon Sep 17 00:00:00 2001 From: Lalit Date: Tue, 11 Jun 2024 17:41:06 -0700 Subject: [PATCH 09/16] changelogs --- opentelemetry-otlp/CHANGELOG.md | 3 +++ opentelemetry-proto/CHANGELOG.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/opentelemetry-otlp/CHANGELOG.md b/opentelemetry-otlp/CHANGELOG.md index 5ec7699d2a..ce4cff0b84 100644 --- a/opentelemetry-otlp/CHANGELOG.md +++ b/opentelemetry-otlp/CHANGELOG.md @@ -16,6 +16,9 @@ now use `.with_resource(RESOURCE::default())` to configure Resource when using These methods would also no longer set the global tracer provider. It would now be the responsibility of users to set it by calling `global::set_tracer_provider(tracer_provider.clone());`. Refer to the [basic-otlp](https://github.com/open-telemetry/opentelemetry-rust/blob/main/opentelemetry-otlp/examples/basic-otlp/src/main.rs) and [basic-otlp-http](https://github.com/open-telemetry/opentelemetry-rust/blob/main/opentelemetry-otlp/examples/basic-otlp-http/src/main.rs) examples on how to initialize OTLP Trace Exporter. - **Breaking** Correct the misspelling of "webkpi" to "webpki" in features [#1842](https://github.com/open-telemetry/opentelemetry-rust/pull/1842) - Bump MSRV to 1.70 [#1840](https://github.com/open-telemetry/opentelemetry-rust/pull/1840) +- Group log and Span batch by their resource and instrumentation scope before exporting [#1873](https://github.com/open-telemetry/opentelemetry-rust/pull/1873). + - This optimization reduces redundancy and improves the efficiency of log export. + - The OTLP compliant Collector or Agents would be able to succesfuuly parse these events. ## v0.16.0 diff --git a/opentelemetry-proto/CHANGELOG.md b/opentelemetry-proto/CHANGELOG.md index afcccc6ea4..3abcc693d0 100644 --- a/opentelemetry-proto/CHANGELOG.md +++ b/opentelemetry-proto/CHANGELOG.md @@ -3,6 +3,9 @@ ## vNext - Bump MSRV to 1.70 [1864](https://github.com/open-telemetry/opentelemetry-rust/pull/1874) +- **BREAKING** Group log and Span batch by their resource and instrumentation scope before exporting [#1873](https://github.com/open-telemetry/opentelemetry-rust/pull/1873). + - Introduced `group_logs_by_resource_and_scope()` and `group_spans_by_resource_and_scope()` methods to group logs and spans by the resource and scope respectively. + - his is a breaking change for exporters consuming the OTLP format. Refer to the OTLP Log and Span exporter in the opentelemetry-otlp crate for the required changes. ## v0.6.0 From 17fd32e6587a1b4e8c53424691a5c10877bb58b1 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Wed, 12 Jun 2024 08:57:50 -0700 Subject: [PATCH 10/16] Update CHANGELOG.md --- opentelemetry-proto/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-proto/CHANGELOG.md b/opentelemetry-proto/CHANGELOG.md index 3abcc693d0..37e4d649a1 100644 --- a/opentelemetry-proto/CHANGELOG.md +++ b/opentelemetry-proto/CHANGELOG.md @@ -5,7 +5,7 @@ - Bump MSRV to 1.70 [1864](https://github.com/open-telemetry/opentelemetry-rust/pull/1874) - **BREAKING** Group log and Span batch by their resource and instrumentation scope before exporting [#1873](https://github.com/open-telemetry/opentelemetry-rust/pull/1873). - Introduced `group_logs_by_resource_and_scope()` and `group_spans_by_resource_and_scope()` methods to group logs and spans by the resource and scope respectively. - - his is a breaking change for exporters consuming the OTLP format. Refer to the OTLP Log and Span exporter in the opentelemetry-otlp crate for the required changes. + - This is a breaking change for exporters consuming the OTLP format. Refer to the OTLP Log and Span exporter in the opentelemetry-otlp crate for the required changes. ## v0.6.0 From 2c1fae6c9f1822fe3d8d89f20ee45a54c0c40eba Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Wed, 19 Jun 2024 11:51:30 -0700 Subject: [PATCH 11/16] Update opentelemetry-otlp/CHANGELOG.md Co-authored-by: Cijo Thomas --- opentelemetry-otlp/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-otlp/CHANGELOG.md b/opentelemetry-otlp/CHANGELOG.md index ce4cff0b84..9633d7e7cb 100644 --- a/opentelemetry-otlp/CHANGELOG.md +++ b/opentelemetry-otlp/CHANGELOG.md @@ -16,7 +16,7 @@ now use `.with_resource(RESOURCE::default())` to configure Resource when using These methods would also no longer set the global tracer provider. It would now be the responsibility of users to set it by calling `global::set_tracer_provider(tracer_provider.clone());`. Refer to the [basic-otlp](https://github.com/open-telemetry/opentelemetry-rust/blob/main/opentelemetry-otlp/examples/basic-otlp/src/main.rs) and [basic-otlp-http](https://github.com/open-telemetry/opentelemetry-rust/blob/main/opentelemetry-otlp/examples/basic-otlp-http/src/main.rs) examples on how to initialize OTLP Trace Exporter. - **Breaking** Correct the misspelling of "webkpi" to "webpki" in features [#1842](https://github.com/open-telemetry/opentelemetry-rust/pull/1842) - Bump MSRV to 1.70 [#1840](https://github.com/open-telemetry/opentelemetry-rust/pull/1840) -- Group log and Span batch by their resource and instrumentation scope before exporting [#1873](https://github.com/open-telemetry/opentelemetry-rust/pull/1873). +- Group batch of `LogRecord` and `Span` by their resource and instrumentation scope before exporting, for better efficiency [#1873](https://github.com/open-telemetry/opentelemetry-rust/pull/1873). - This optimization reduces redundancy and improves the efficiency of log export. - The OTLP compliant Collector or Agents would be able to succesfuuly parse these events. From dfac2e62f20d6e078dfda3c8755980b50e1959d7 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Wed, 19 Jun 2024 11:51:36 -0700 Subject: [PATCH 12/16] Update opentelemetry-otlp/CHANGELOG.md Co-authored-by: Cijo Thomas --- opentelemetry-otlp/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-otlp/CHANGELOG.md b/opentelemetry-otlp/CHANGELOG.md index 9633d7e7cb..a42ffb697f 100644 --- a/opentelemetry-otlp/CHANGELOG.md +++ b/opentelemetry-otlp/CHANGELOG.md @@ -18,7 +18,7 @@ now use `.with_resource(RESOURCE::default())` to configure Resource when using - Bump MSRV to 1.70 [#1840](https://github.com/open-telemetry/opentelemetry-rust/pull/1840) - Group batch of `LogRecord` and `Span` by their resource and instrumentation scope before exporting, for better efficiency [#1873](https://github.com/open-telemetry/opentelemetry-rust/pull/1873). - This optimization reduces redundancy and improves the efficiency of log export. - - The OTLP compliant Collector or Agents would be able to succesfuuly parse these events. + - The OTLP compliant Collector or Agents would be able to successfully parse these events. ## v0.16.0 From 38c1979b4da8ae6f6b814f7827ce9a7b346a2b0b Mon Sep 17 00:00:00 2001 From: Lalit Date: Fri, 21 Jun 2024 13:10:33 -0700 Subject: [PATCH 13/16] merge conflict --- opentelemetry-proto/CHANGELOG.md | 2 +- opentelemetry-proto/src/transform/logs.rs | 27 +++++++++++++++------- opentelemetry-proto/src/transform/trace.rs | 2 +- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/opentelemetry-proto/CHANGELOG.md b/opentelemetry-proto/CHANGELOG.md index 37e4d649a1..5c34cc882a 100644 --- a/opentelemetry-proto/CHANGELOG.md +++ b/opentelemetry-proto/CHANGELOG.md @@ -4,7 +4,7 @@ - Bump MSRV to 1.70 [1864](https://github.com/open-telemetry/opentelemetry-rust/pull/1874) - **BREAKING** Group log and Span batch by their resource and instrumentation scope before exporting [#1873](https://github.com/open-telemetry/opentelemetry-rust/pull/1873). - - Introduced `group_logs_by_resource_and_scope()` and `group_spans_by_resource_and_scope()` methods to group logs and spans by the resource and scope respectively. + - **BREAKING** Introduced `group_logs_by_resource_and_scope()` and `group_spans_by_resource_and_scope()` methods to group logs and spans by the resource and scope respectively. - This is a breaking change for exporters consuming the OTLP format. Refer to the OTLP Log and Span exporter in the opentelemetry-otlp crate for the required changes. ## v0.6.0 diff --git a/opentelemetry-proto/src/transform/logs.rs b/opentelemetry-proto/src/transform/logs.rs index 5e9281bd0c..0a672d3d51 100644 --- a/opentelemetry-proto/src/transform/logs.rs +++ b/opentelemetry-proto/src/transform/logs.rs @@ -2,7 +2,10 @@ pub mod tonic { use crate::{ tonic::{ - common::v1::{any_value::Value, AnyValue, ArrayValue, KeyValue, KeyValueList}, + common::v1::{ + any_value::Value, AnyValue, ArrayValue, InstrumentationScope, KeyValue, + KeyValueList, + }, logs::v1::{LogRecord, ResourceLogs, ScopeLogs, SeverityNumber}, resource::v1::Resource, Attributes, @@ -10,6 +13,7 @@ pub mod tonic { transform::common::{to_nanos, tonic::ResourceAttributesWithSchema}, }; use opentelemetry::logs::{AnyValue as LogsAnyValue, Severity}; + use std::borrow::Cow; use std::collections::HashMap; impl From for AnyValue { @@ -149,26 +153,33 @@ pub mod tonic { logs: Vec, resource: &ResourceAttributesWithSchema, ) -> Vec { - // no need of explicit grouping by resource, as all the logs belong to single resource. + // Group logs by target or instrumentation name let scope_map = logs.iter().fold( HashMap::new(), |mut scope_map: HashMap< - &opentelemetry_sdk::InstrumentationLibrary, + Cow<'static, str>, Vec<&opentelemetry_sdk::export::logs::LogData>, >, log| { - let instrumentation = &log.instrumentation; - scope_map.entry(instrumentation).or_default().push(log); + let key = log + .record + .target + .clone() + .unwrap_or_else(|| log.instrumentation.name.clone()); + scope_map.entry(key).or_default().push(log); scope_map }, ); let scope_logs = scope_map .into_iter() - .map(|(instrumentation, log_records)| ScopeLogs { - scope: Some(instrumentation.into()), + .map(|(key, log_data)| ScopeLogs { + scope: Some(InstrumentationScope::from(( + &log_data.first().unwrap().instrumentation, + Some(key), + ))), schema_url: resource.schema_url.clone().unwrap_or_default(), - log_records: log_records + log_records: log_data .into_iter() .map(|log_data| log_data.record.clone().into()) .collect(), diff --git a/opentelemetry-proto/src/transform/trace.rs b/opentelemetry-proto/src/transform/trace.rs index c00ade1796..12871b33aa 100644 --- a/opentelemetry-proto/src/transform/trace.rs +++ b/opentelemetry-proto/src/transform/trace.rs @@ -170,7 +170,7 @@ pub mod tonic { let scope_spans = scope_map .into_iter() .map(|(instrumentation, span_records)| ScopeSpans { - scope: Some(instrumentation.into()), + scope: Some((instrumentation, None).into()), schema_url: resource.schema_url.clone().unwrap_or_default(), spans: span_records .into_iter() From 7f3198a6d69cee1c1d182e32959a454a78552e96 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Fri, 21 Jun 2024 13:12:57 -0700 Subject: [PATCH 14/16] Update opentelemetry-otlp/CHANGELOG.md Co-authored-by: Cijo Thomas --- opentelemetry-otlp/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-otlp/CHANGELOG.md b/opentelemetry-otlp/CHANGELOG.md index 86886da32b..77d203c83c 100644 --- a/opentelemetry-otlp/CHANGELOG.md +++ b/opentelemetry-otlp/CHANGELOG.md @@ -19,7 +19,7 @@ now use `.with_resource(RESOURCE::default())` to configure Resource when using - Fixing the OTLP HTTP/JSON exporter. [#1882](https://github.com/open-telemetry/opentelemetry-rust/pull/1882) - The exporter was broken in the previous release. - **Breaking** [1869](https://github.com/open-telemetry/opentelemetry-rust/pull/1869) The OTLP logs exporter now overrides the [InstrumentationScope::name](https://github.com/open-telemetry/opentelemetry-proto/blob/b3060d2104df364136d75a35779e6bd48bac449a/opentelemetry/proto/common/v1/common.proto#L73) field with the `target` from `LogRecord`, if target is populated. -- Group batch of `LogRecord` and `Span` by their resource and instrumentation scope before exporting, for better efficiency [#1873](https://github.com/open-telemetry/opentelemetry-rust/pull/1873). +- Groups batch of `LogRecord` and `Span` by their resource and instrumentation scope before exporting, for better efficiency [#1873](https://github.com/open-telemetry/opentelemetry-rust/pull/1873). - This optimization reduces redundancy and improves the efficiency of log export. - The OTLP compliant Collector or Agents would be able to successfully parse these events. From 3fb36600ffaba06dd6fff9e741c7cefaedc64a7b Mon Sep 17 00:00:00 2001 From: Lalit Date: Fri, 21 Jun 2024 13:13:38 -0700 Subject: [PATCH 15/16] fix --- opentelemetry-otlp/CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/opentelemetry-otlp/CHANGELOG.md b/opentelemetry-otlp/CHANGELOG.md index 77d203c83c..5295ae9ee0 100644 --- a/opentelemetry-otlp/CHANGELOG.md +++ b/opentelemetry-otlp/CHANGELOG.md @@ -20,8 +20,7 @@ now use `.with_resource(RESOURCE::default())` to configure Resource when using previous release. - **Breaking** [1869](https://github.com/open-telemetry/opentelemetry-rust/pull/1869) The OTLP logs exporter now overrides the [InstrumentationScope::name](https://github.com/open-telemetry/opentelemetry-proto/blob/b3060d2104df364136d75a35779e6bd48bac449a/opentelemetry/proto/common/v1/common.proto#L73) field with the `target` from `LogRecord`, if target is populated. - Groups batch of `LogRecord` and `Span` by their resource and instrumentation scope before exporting, for better efficiency [#1873](https://github.com/open-telemetry/opentelemetry-rust/pull/1873). - - This optimization reduces redundancy and improves the efficiency of log export. - - The OTLP compliant Collector or Agents would be able to successfully parse these events. + ## v0.16.0 From 242d8ffb3b4d5196de8a162d3c920384383ce79e Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Wed, 26 Jun 2024 10:44:41 -0700 Subject: [PATCH 16/16] Update CHANGELOG.md --- opentelemetry-proto/CHANGELOG.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/opentelemetry-proto/CHANGELOG.md b/opentelemetry-proto/CHANGELOG.md index 5c34cc882a..666dd30571 100644 --- a/opentelemetry-proto/CHANGELOG.md +++ b/opentelemetry-proto/CHANGELOG.md @@ -3,9 +3,8 @@ ## vNext - Bump MSRV to 1.70 [1864](https://github.com/open-telemetry/opentelemetry-rust/pull/1874) -- **BREAKING** Group log and Span batch by their resource and instrumentation scope before exporting [#1873](https://github.com/open-telemetry/opentelemetry-rust/pull/1873). - - **BREAKING** Introduced `group_logs_by_resource_and_scope()` and `group_spans_by_resource_and_scope()` methods to group logs and spans by the resource and scope respectively. - - This is a breaking change for exporters consuming the OTLP format. Refer to the OTLP Log and Span exporter in the opentelemetry-otlp crate for the required changes. +- Group log and Span batch by their resource and instrumentation scope before exporting [#1873](https://github.com/open-telemetry/opentelemetry-rust/pull/1873). + - Introduced `group_logs_by_resource_and_scope()` and `group_spans_by_resource_and_scope()` methods to group logs and spans by the resource and scope respectively. ## v0.6.0