opentelemetry_spanprocessor_any/sdk/export/trace/
stdout.rs1use crate::{
31 global, sdk,
32 sdk::export::{
33 trace::{ExportResult, SpanData, SpanExporter},
34 ExportError,
35 },
36 trace::TracerProvider,
37};
38use async_trait::async_trait;
39use std::fmt::Debug;
40use std::io::{stdout, Stdout, Write};
41
42#[derive(Debug)]
44pub struct PipelineBuilder<W: Write> {
45 pretty_print: bool,
46 trace_config: Option<sdk::trace::Config>,
47 writer: W,
48}
49
50pub fn new_pipeline() -> PipelineBuilder<Stdout> {
52 PipelineBuilder::default()
53}
54
55impl Default for PipelineBuilder<Stdout> {
56 fn default() -> Self {
58 Self {
59 pretty_print: false,
60 trace_config: None,
61 writer: stdout(),
62 }
63 }
64}
65
66impl<W: Write> PipelineBuilder<W> {
67 pub fn with_pretty_print(mut self, pretty_print: bool) -> Self {
69 self.pretty_print = pretty_print;
70 self
71 }
72
73 pub fn with_trace_config(mut self, config: sdk::trace::Config) -> Self {
75 self.trace_config = Some(config);
76 self
77 }
78
79 pub fn with_writer<T: Write>(self, writer: T) -> PipelineBuilder<T> {
81 PipelineBuilder {
82 pretty_print: self.pretty_print,
83 trace_config: self.trace_config,
84 writer,
85 }
86 }
87}
88
89impl<W> PipelineBuilder<W>
90where
91 W: Write + Debug + Send + 'static,
92{
93 pub fn install_simple(mut self) -> sdk::trace::Tracer {
95 let exporter = Exporter::new(self.writer, self.pretty_print);
96
97 let mut provider_builder =
98 sdk::trace::TracerProvider::builder().with_simple_exporter(exporter);
99 if let Some(config) = self.trace_config.take() {
100 provider_builder = provider_builder.with_config(config);
101 }
102 let provider = provider_builder.build();
103
104 let tracer =
105 provider.versioned_tracer("opentelemetry", Some(env!("CARGO_PKG_VERSION")), None);
106 let _ = global::set_tracer_provider(provider);
107
108 tracer
109 }
110}
111
112#[derive(Debug)]
118pub struct Exporter<W: Write> {
119 writer: W,
120 pretty_print: bool,
121}
122
123impl<W: Write> Exporter<W> {
124 pub fn new(writer: W, pretty_print: bool) -> Self {
126 Self {
127 writer,
128 pretty_print,
129 }
130 }
131}
132
133#[async_trait]
134impl<W> SpanExporter for Exporter<W>
135where
136 W: Write + Debug + Send + 'static,
137{
138 async fn export(&mut self, batch: Vec<SpanData>) -> ExportResult {
140 for span in batch {
141 if self.pretty_print {
142 self.writer
143 .write_all(format!("{:#?}\n", span).as_bytes())
144 .map_err::<Error, _>(Into::into)?;
145 } else {
146 self.writer
147 .write_all(format!("{:?}\n", span).as_bytes())
148 .map_err::<Error, _>(Into::into)?;
149 }
150 }
151
152 Ok(())
153 }
154}
155
156#[derive(thiserror::Error, Debug)]
158#[error(transparent)]
159struct Error(#[from] std::io::Error);
160
161impl ExportError for Error {
162 fn exporter_name(&self) -> &'static str {
163 "stdout"
164 }
165}