Skip to content

Commit

Permalink
Enable doc generation for testing module for InMemory*Exporters. (#1503)
Browse files Browse the repository at this point in the history
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
  • Loading branch information
lalitb and cijothomas committed Feb 1, 2024
1 parent 989fa3b commit 57c3aa3
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 175 deletions.
1 change: 1 addition & 0 deletions opentelemetry-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- [#1410](https://github.com/open-telemetry/opentelemetry-rust/pull/1410) Add experimental synchronous gauge
- [#1471](https://github.com/open-telemetry/opentelemetry-rust/pull/1471) Configure batch log record processor via [`OTEL_BLRP_*`](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/configuration/sdk-environment-variables.md#batch-logrecord-processor) environment variables and via `OtlpLogPipeline::with_batch_config`
- [#1503](https://github.com/open-telemetry/opentelemetry-rust/pull/1503) Make the documentation for In-Memory exporters visible.

### Changed

Expand Down
2 changes: 1 addition & 1 deletion opentelemetry-sdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ pub mod propagation;
pub mod resource;
pub mod runtime;
#[cfg(any(feature = "testing", test))]
#[doc(hidden)]
#[cfg_attr(docsrs, doc(cfg(any(feature = "testing", test))))]
pub mod testing;
#[cfg(feature = "trace")]
#[cfg_attr(docsrs, doc(cfg(feature = "trace")))]
Expand Down
7 changes: 5 additions & 2 deletions opentelemetry-sdk/src/testing/logs/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
pub use in_memory_exporter::{InMemoryLogsExporter, InMemoryLogsExporterBuilder};
//! In-Memory log exporter for testing purpose.

mod in_memory_exporter;
/// The `in_memory_exporter` module provides in-memory log exporter.
/// For detailed usage and examples, see `in_memory_exporter`.
pub mod in_memory_exporter;
pub use in_memory_exporter::{InMemoryLogsExporter, InMemoryLogsExporterBuilder};
9 changes: 7 additions & 2 deletions opentelemetry-sdk/src/testing/metrics/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
pub use in_memory_exporter::{InMemoryMetricsExporter, InMemoryMetricsExporterBuilder};
pub use metric_reader::TestMetricReader;
//! In-Memory metrics exporter for testing purpose.

/// The `in_memory_exporter` module provides in-memory metrics exporter.
/// For detailed usage and examples, see `in_memory_exporter`.
pub mod in_memory_exporter;
pub use in_memory_exporter::{InMemoryMetricsExporter, InMemoryMetricsExporterBuilder};

#[doc(hidden)]
pub mod metric_reader;
pub use metric_reader::TestMetricReader;
2 changes: 2 additions & 0 deletions opentelemetry-sdk/src/testing/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! In-Memory exporters for testing purpose.

#[cfg(all(feature = "testing", feature = "trace"))]
pub mod trace;

Expand Down
178 changes: 8 additions & 170 deletions opentelemetry-sdk/src/testing/trace/mod.rs
Original file line number Diff line number Diff line change
@@ -1,172 +1,10 @@
pub use in_memory_exporter::{InMemorySpanExporter, InMemorySpanExporterBuilder};

mod in_memory_exporter;

use crate::{
export::{
trace::{ExportResult, SpanData, SpanExporter},
ExportError,
},
trace::{Config, SpanEvents, SpanLinks},
InstrumentationLibrary,
};
use async_trait::async_trait;
use crossbeam_channel::{unbounded, Receiver, SendError, Sender};
use futures_util::future::BoxFuture;
pub use opentelemetry::testing::trace::TestSpan;
use opentelemetry::trace::{
SpanContext, SpanId, SpanKind, Status, TraceFlags, TraceId, TraceState,
};
use std::fmt::{Display, Formatter};

pub fn new_test_export_span_data() -> SpanData {
let config = Config::default();
SpanData {
span_context: SpanContext::new(
TraceId::from_u128(1),
SpanId::from_u64(1),
TraceFlags::SAMPLED,
false,
TraceState::default(),
),
parent_span_id: SpanId::INVALID,
span_kind: SpanKind::Internal,
name: "opentelemetry".into(),
start_time: opentelemetry::time::now(),
end_time: opentelemetry::time::now(),
attributes: Vec::new(),
dropped_attributes_count: 0,
events: SpanEvents::default(),
links: SpanLinks::default(),
status: Status::Unset,
resource: config.resource,
instrumentation_lib: InstrumentationLibrary::default(),
}
}

#[derive(Debug)]
pub struct TestSpanExporter {
tx_export: Sender<SpanData>,
tx_shutdown: Sender<()>,
}

#[async_trait]
impl SpanExporter for TestSpanExporter {
fn export(&mut self, batch: Vec<SpanData>) -> BoxFuture<'static, ExportResult> {
for span_data in batch {
if let Err(err) = self
.tx_export
.send(span_data)
.map_err::<TestExportError, _>(Into::into)
{
return Box::pin(std::future::ready(Err(Into::into(err))));
}
}
Box::pin(std::future::ready(Ok(())))
}

fn shutdown(&mut self) {
let _ = self.tx_shutdown.send(()); // ignore error
}
}

pub fn new_test_exporter() -> (TestSpanExporter, Receiver<SpanData>, Receiver<()>) {
let (tx_export, rx_export) = unbounded();
let (tx_shutdown, rx_shutdown) = unbounded();
let exporter = TestSpanExporter {
tx_export,
tx_shutdown,
};
(exporter, rx_export, rx_shutdown)
}

#[derive(Debug)]
pub struct TokioSpanExporter {
tx_export: tokio::sync::mpsc::UnboundedSender<SpanData>,
tx_shutdown: tokio::sync::mpsc::UnboundedSender<()>,
}

impl SpanExporter for TokioSpanExporter {
fn export(&mut self, batch: Vec<SpanData>) -> BoxFuture<'static, ExportResult> {
for span_data in batch {
if let Err(err) = self
.tx_export
.send(span_data)
.map_err::<TestExportError, _>(Into::into)
{
return Box::pin(std::future::ready(Err(Into::into(err))));
}
}
Box::pin(std::future::ready(Ok(())))
}
//! In-Memory trace exporter for testing purpose.

fn shutdown(&mut self) {
self.tx_shutdown.send(()).unwrap();
}
}

pub fn new_tokio_test_exporter() -> (
TokioSpanExporter,
tokio::sync::mpsc::UnboundedReceiver<SpanData>,
tokio::sync::mpsc::UnboundedReceiver<()>,
) {
let (tx_export, rx_export) = tokio::sync::mpsc::unbounded_channel();
let (tx_shutdown, rx_shutdown) = tokio::sync::mpsc::unbounded_channel();
let exporter = TokioSpanExporter {
tx_export,
tx_shutdown,
};
(exporter, rx_export, rx_shutdown)
}

#[derive(Debug)]
pub struct TestExportError(String);

impl std::error::Error for TestExportError {}

impl ExportError for TestExportError {
fn exporter_name(&self) -> &'static str {
"test"
}
}

impl Display for TestExportError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}

#[cfg(any(feature = "rt-tokio", feature = "rt-tokio-current-thread"))]
impl<T> From<tokio::sync::mpsc::error::SendError<T>> for TestExportError {
fn from(err: tokio::sync::mpsc::error::SendError<T>) -> Self {
TestExportError(err.to_string())
}
}

impl<T> From<crossbeam_channel::SendError<T>> for TestExportError {
fn from(err: SendError<T>) -> Self {
TestExportError(err.to_string())
}
}

/// A no-op instance of an [`SpanExporter`].
///
/// [`SpanExporter`]: crate::export::trace::SpanExporter
#[derive(Debug, Default)]
pub struct NoopSpanExporter {
_private: (),
}

impl NoopSpanExporter {
/// Create a new noop span exporter
pub fn new() -> Self {
NoopSpanExporter { _private: () }
}
}
/// The `in_memory_exporter` module provides in-memory trace exporter.
/// For detailed usage and examples, see `in_memory_exporter`.
pub mod in_memory_exporter;
pub use in_memory_exporter::{InMemorySpanExporter, InMemorySpanExporterBuilder};

#[async_trait::async_trait]
impl SpanExporter for NoopSpanExporter {
fn export(&mut self, _: Vec<SpanData>) -> BoxFuture<'static, ExportResult> {
Box::pin(std::future::ready(Ok(())))
}
}
#[doc(hidden)]
mod span_exporters;
pub use span_exporters::*;
168 changes: 168 additions & 0 deletions opentelemetry-sdk/src/testing/trace/span_exporters.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
use crate::{
export::{
trace::{ExportResult, SpanData, SpanExporter},
ExportError,
},
trace::{Config, SpanEvents, SpanLinks},
InstrumentationLibrary,
};
use async_trait::async_trait;
use crossbeam_channel::{unbounded, Receiver, SendError, Sender};
use futures_util::future::BoxFuture;
pub use opentelemetry::testing::trace::TestSpan;
use opentelemetry::trace::{
SpanContext, SpanId, SpanKind, Status, TraceFlags, TraceId, TraceState,
};
use std::fmt::{Display, Formatter};

pub fn new_test_export_span_data() -> SpanData {
let config = Config::default();
SpanData {
span_context: SpanContext::new(
TraceId::from_u128(1),
SpanId::from_u64(1),
TraceFlags::SAMPLED,
false,
TraceState::default(),
),
parent_span_id: SpanId::INVALID,
span_kind: SpanKind::Internal,
name: "opentelemetry".into(),
start_time: opentelemetry::time::now(),
end_time: opentelemetry::time::now(),
attributes: Vec::new(),
dropped_attributes_count: 0,
events: SpanEvents::default(),
links: SpanLinks::default(),
status: Status::Unset,
resource: config.resource,
instrumentation_lib: InstrumentationLibrary::default(),
}
}

#[derive(Debug)]
pub struct TestSpanExporter {
tx_export: Sender<SpanData>,
tx_shutdown: Sender<()>,
}

#[async_trait]
impl SpanExporter for TestSpanExporter {
fn export(&mut self, batch: Vec<SpanData>) -> BoxFuture<'static, ExportResult> {
for span_data in batch {
if let Err(err) = self
.tx_export
.send(span_data)
.map_err::<TestExportError, _>(Into::into)
{
return Box::pin(std::future::ready(Err(Into::into(err))));
}
}
Box::pin(std::future::ready(Ok(())))
}

fn shutdown(&mut self) {
let _ = self.tx_shutdown.send(()); // ignore error
}
}

pub fn new_test_exporter() -> (TestSpanExporter, Receiver<SpanData>, Receiver<()>) {
let (tx_export, rx_export) = unbounded();
let (tx_shutdown, rx_shutdown) = unbounded();
let exporter = TestSpanExporter {
tx_export,
tx_shutdown,
};
(exporter, rx_export, rx_shutdown)
}

#[derive(Debug)]
pub struct TokioSpanExporter {
tx_export: tokio::sync::mpsc::UnboundedSender<SpanData>,
tx_shutdown: tokio::sync::mpsc::UnboundedSender<()>,
}

impl SpanExporter for TokioSpanExporter {
fn export(&mut self, batch: Vec<SpanData>) -> BoxFuture<'static, ExportResult> {
for span_data in batch {
if let Err(err) = self
.tx_export
.send(span_data)
.map_err::<TestExportError, _>(Into::into)
{
return Box::pin(std::future::ready(Err(Into::into(err))));
}
}
Box::pin(std::future::ready(Ok(())))
}

fn shutdown(&mut self) {
self.tx_shutdown.send(()).unwrap();
}
}

pub fn new_tokio_test_exporter() -> (
TokioSpanExporter,
tokio::sync::mpsc::UnboundedReceiver<SpanData>,
tokio::sync::mpsc::UnboundedReceiver<()>,
) {
let (tx_export, rx_export) = tokio::sync::mpsc::unbounded_channel();
let (tx_shutdown, rx_shutdown) = tokio::sync::mpsc::unbounded_channel();
let exporter = TokioSpanExporter {
tx_export,
tx_shutdown,
};
(exporter, rx_export, rx_shutdown)
}

#[derive(Debug)]
pub struct TestExportError(String);

impl std::error::Error for TestExportError {}

impl ExportError for TestExportError {
fn exporter_name(&self) -> &'static str {
"test"
}
}

impl Display for TestExportError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}

#[cfg(any(feature = "rt-tokio", feature = "rt-tokio-current-thread"))]
impl<T> From<tokio::sync::mpsc::error::SendError<T>> for TestExportError {
fn from(err: tokio::sync::mpsc::error::SendError<T>) -> Self {
TestExportError(err.to_string())
}
}

impl<T> From<crossbeam_channel::SendError<T>> for TestExportError {
fn from(err: SendError<T>) -> Self {
TestExportError(err.to_string())
}
}

/// A no-op instance of an [`SpanExporter`].
///
/// [`SpanExporter`]: crate::export::trace::SpanExporter
#[derive(Debug, Default)]
pub struct NoopSpanExporter {
_private: (),
}

impl NoopSpanExporter {
/// Create a new noop span exporter
pub fn new() -> Self {
NoopSpanExporter { _private: () }
}
}

#[async_trait::async_trait]
impl SpanExporter for NoopSpanExporter {
fn export(&mut self, _: Vec<SpanData>) -> BoxFuture<'static, ExportResult> {
Box::pin(std::future::ready(Ok(())))
}
}

0 comments on commit 57c3aa3

Please sign in to comment.